summaryrefslogtreecommitdiff
path: root/attic/muse2-oom/muse2/muse/instruments
diff options
context:
space:
mode:
Diffstat (limited to 'attic/muse2-oom/muse2/muse/instruments')
-rw-r--r--attic/muse2-oom/muse2/muse/instruments/CMakeLists.txt89
-rw-r--r--attic/muse2-oom/muse2/muse/instruments/ccontrolbase.ui525
-rw-r--r--attic/muse2-oom/muse2/muse/instruments/editinstrument.cpp3588
-rw-r--r--attic/muse2-oom/muse2/muse/instruments/editinstrument.h91
-rw-r--r--attic/muse2-oom/muse2/muse/instruments/editinstrumentbase.ui1649
-rw-r--r--attic/muse2-oom/muse2/muse/instruments/midictrledit.cpp725
-rw-r--r--attic/muse2-oom/muse2/muse/instruments/midictrledit.h56
-rw-r--r--attic/muse2-oom/muse2/muse/instruments/minstrument.cpp927
-rw-r--r--attic/muse2-oom/muse2/muse/instruments/minstrument.h145
9 files changed, 7795 insertions, 0 deletions
diff --git a/attic/muse2-oom/muse2/muse/instruments/CMakeLists.txt b/attic/muse2-oom/muse2/muse/instruments/CMakeLists.txt
new file mode 100644
index 00000000..b068798a
--- /dev/null
+++ b/attic/muse2-oom/muse2/muse/instruments/CMakeLists.txt
@@ -0,0 +1,89 @@
+#=============================================================================
+# MusE
+# Linux Music Editor
+# $Id:$
+#
+# Copyright (C) 2002-2006 by Werner Schweer and others
+#
+# 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.
+#=============================================================================
+
+##
+## Expand Qt macros in source files
+##
+QT4_WRAP_CPP ( instruments_mocs
+ editinstrument.h
+ # minstrument.h
+ )
+
+##
+## UI files
+##
+file (GLOB instruments_ui_files
+ # ccontrollerbase.ui # not built. It needs to be converted to Qt4 for revival.
+ editinstrumentbase.ui
+ )
+QT4_WRAP_UI ( instruments_uis ${instruments_ui_files} )
+
+##
+## List of source files to compile
+##
+file (GLOB instruments_source_files
+ editinstrument.cpp
+ editinstrument.h
+ minstrument.cpp
+ minstrument.h
+ )
+
+##
+## Define target
+##
+add_library ( instruments SHARED
+ ${instruments_source_files}
+ ${instruments_mocs}
+ ${instruments_uis}
+ )
+
+##
+## Append to the list of translations
+##
+set (FILES_TO_TRANSLATE
+ ${FILES_TO_TRANSLATE}
+ ${instruments_source_files}
+ ${instruments_ui_files}
+ CACHE INTERNAL ""
+ )
+
+##
+## Compilation flags and target name
+##
+set_target_properties( instruments
+ PROPERTIES COMPILE_FLAGS "-include ${PROJECT_BINARY_DIR}/all.h -fPIC"
+ OUTPUT_NAME muse_instruments
+ )
+
+##
+## Linkage
+##
+target_link_libraries ( instruments
+ ${QT_LIBRARIES}
+ icons
+ )
+
+##
+## Install location
+##
+install(TARGETS instruments
+ DESTINATION ${MusE_MODULES_DIR}
+ )
+
diff --git a/attic/muse2-oom/muse2/muse/instruments/ccontrolbase.ui b/attic/muse2-oom/muse2/muse/instruments/ccontrolbase.ui
new file mode 100644
index 00000000..3094776f
--- /dev/null
+++ b/attic/muse2-oom/muse2/muse/instruments/ccontrolbase.ui
@@ -0,0 +1,525 @@
+<!DOCTYPE UI><UI version="3.1" stdsetdef="1">
+<class>MidiControllerEditDialogBase</class>
+<widget class="QDialog">
+ <property name="name">
+ <cstring>MidiControllerEditDialogBase</cstring>
+ </property>
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>698</width>
+ <height>457</height>
+ </rect>
+ </property>
+ <property name="caption">
+ <string>MusE: Define Midi Controller</string>
+ </property>
+ <property name="sizeGripEnabled">
+ <bool>true</bool>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLayoutWidget" row="3" column="0" rowspan="1" colspan="2">
+ <property name="name">
+ <cstring>Layout2</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>buttonNew</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Add</string>
+ </property>
+ <property name="accel">
+ <string>Alt+A</string>
+ </property>
+ <property name="autoDefault">
+ <bool>false</bool>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>create new entry</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>pressing the New button you create a new entry
+in the MusE list of defined controllers</string>
+ </property>
+ </widget>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>buttonDelete</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Delete</string>
+ </property>
+ <property name="autoDefault">
+ <bool>false</bool>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>delete selected entry</string>
+ </property>
+ </widget>
+ <spacer>
+ <property name="name">
+ <cstring>Spacer1</cstring>
+ </property>
+ <property name="orientation">
+ <enum>Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>Expanding</enum>
+ </property>
+ <property name="sizeHint">
+ <size>
+ <width>20</width>
+ <height>0</height>
+ </size>
+ </property>
+ </spacer>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>buttonOk</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;OK</string>
+ </property>
+ <property name="autoDefault">
+ <bool>false</bool>
+ </property>
+ </widget>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>buttonApply</cstring>
+ </property>
+ <property name="text">
+ <string>A&amp;pply</string>
+ </property>
+ <property name="autoDefault">
+ <bool>false</bool>
+ </property>
+ </widget>
+ <widget class="QPushButton">
+ <property name="name">
+ <cstring>buttonCancel</cstring>
+ </property>
+ <property name="text">
+ <string>&amp;Cancel</string>
+ </property>
+ <property name="autoDefault">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>textLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>Predefined Controller:</string>
+ </property>
+ </widget>
+ <widget class="QListView" row="1" column="1">
+ <column>
+ <property name="text">
+ <string>Name </string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Type </string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>true</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>H-Ctrl</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>false</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>L-Ctrl</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>false</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Min Val</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>false</bool>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Max Val</string>
+ </property>
+ <property name="clickable">
+ <bool>true</bool>
+ </property>
+ <property name="resizable">
+ <bool>false</bool>
+ </property>
+ </column>
+ <property name="name">
+ <cstring>viewController</cstring>
+ </property>
+ <property name="frameShape">
+ <enum>StyledPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>Sunken</enum>
+ </property>
+ <property name="allColumnsShowFocus">
+ <bool>true</bool>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>list of defined controllers</string>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>This is the MusE list of defined controllers.</string>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget" row="0" column="1">
+ <property name="name">
+ <cstring>layout2</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel2</cstring>
+ </property>
+ <property name="text">
+ <string>Managed Controller for Port</string>
+ </property>
+ </widget>
+ <widget class="QComboBox">
+ <property name="name">
+ <cstring>midiPortsList</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>textLabel3</cstring>
+ </property>
+ <property name="text">
+ <string>Channel</string>
+ </property>
+ </widget>
+ <widget class="QSpinBox">
+ <property name="name">
+ <cstring>midiChannel</cstring>
+ </property>
+ <property name="maxValue">
+ <number>16</number>
+ </property>
+ <property name="minValue">
+ <number>1</number>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QListBox" row="1" column="0" rowspan="2" colspan="1">
+ <property name="name">
+ <cstring>listController</cstring>
+ </property>
+ <property name="whatsThis" stdset="0">
+ <string>This is a list of commonly used midi controllers.
+Note that in MusE pitch and program changes are
+handled like normal controllers.</string>
+ </property>
+ </widget>
+ <widget class="QGroupBox" row="2" column="1">
+ <property name="name">
+ <cstring>GroupBox1</cstring>
+ </property>
+ <property name="title">
+ <string>Properties</string>
+ </property>
+ <grid>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <property name="margin">
+ <number>11</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <widget class="QLabel" row="0" column="0">
+ <property name="name">
+ <cstring>TextLabel1</cstring>
+ </property>
+ <property name="text">
+ <string>Name</string>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget" row="2" column="1">
+ <property name="name">
+ <cstring>layout3</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>TextLabel1_2</cstring>
+ </property>
+ <property name="text">
+ <string>Min Value</string>
+ </property>
+ <property name="indent">
+ <number>10</number>
+ </property>
+ </widget>
+ <widget class="QSpinBox">
+ <property name="name">
+ <cstring>spinboxMin</cstring>
+ </property>
+ <property name="maxValue">
+ <number>16384</number>
+ </property>
+ <property name="minValue">
+ <number>-16385</number>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>TextLabel2_2</cstring>
+ </property>
+ <property name="text">
+ <string>Max Value</string>
+ </property>
+ <property name="indent">
+ <number>10</number>
+ </property>
+ </widget>
+ <widget class="QSpinBox">
+ <property name="name">
+ <cstring>spinboxMax</cstring>
+ </property>
+ <property name="maxValue">
+ <number>16384</number>
+ </property>
+ <property name="minValue">
+ <number>-16385</number>
+ </property>
+ <property name="value">
+ <number>127</number>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QLabel" row="1" column="0">
+ <property name="name">
+ <cstring>TextLabel2</cstring>
+ </property>
+ <property name="text">
+ <string>Type</string>
+ </property>
+ </widget>
+ <widget class="QLineEdit" row="0" column="1">
+ <property name="name">
+ <cstring>entryName</cstring>
+ </property>
+ </widget>
+ <widget class="QLayoutWidget" row="1" column="1">
+ <property name="name">
+ <cstring>layout5</cstring>
+ </property>
+ <hbox>
+ <property name="name">
+ <cstring>unnamed</cstring>
+ </property>
+ <widget class="QComboBox">
+ <item>
+ <property name="text">
+ <string>Control7</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Control14</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>RPN</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>NRPN</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>RPN14</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>NRPN14</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Pitch</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Program</string>
+ </property>
+ </item>
+ <property name="name">
+ <cstring>comboType</cstring>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>TextLabel3</cstring>
+ </property>
+ <property name="text">
+ <string>H-Ctrl</string>
+ </property>
+ <property name="indent">
+ <number>10</number>
+ </property>
+ </widget>
+ <widget class="QSpinBox">
+ <property name="name">
+ <cstring>spinboxHCtrlNo</cstring>
+ </property>
+ <property name="maxValue">
+ <number>127</number>
+ </property>
+ <property name="minValue">
+ <number>0</number>
+ </property>
+ <property name="value">
+ <number>1</number>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Midi Controller Number High Byte</string>
+ </property>
+ </widget>
+ <widget class="QLabel">
+ <property name="name">
+ <cstring>TextLabel2_3</cstring>
+ </property>
+ <property name="text">
+ <string>L-Ctrl</string>
+ </property>
+ <property name="indent">
+ <number>10</number>
+ </property>
+ </widget>
+ <widget class="QSpinBox">
+ <property name="name">
+ <cstring>spinboxLCtrlNo</cstring>
+ </property>
+ <property name="maxValue">
+ <number>127</number>
+ </property>
+ <property name="minValue">
+ <number>0</number>
+ </property>
+ <property name="value">
+ <number>1</number>
+ </property>
+ <property name="toolTip" stdset="0">
+ <string>Midi Controller Number Low Byte</string>
+ </property>
+ </widget>
+ </hbox>
+ </widget>
+ <widget class="QLabel" row="2" column="0">
+ <property name="name">
+ <cstring>textLabel4</cstring>
+ </property>
+ <property name="text">
+ <string>Range</string>
+ </property>
+ </widget>
+ </grid>
+ </widget>
+ </grid>
+</widget>
+<connections>
+ <connection>
+ <sender>buttonCancel</sender>
+ <signal>clicked()</signal>
+ <receiver>MidiControllerEditDialogBase</receiver>
+ <slot>reject()</slot>
+ </connection>
+ <connection>
+ <sender>buttonOk</sender>
+ <signal>clicked()</signal>
+ <receiver>MidiControllerEditDialogBase</receiver>
+ <slot>accept()</slot>
+ </connection>
+</connections>
+<tabstops>
+ <tabstop>viewController</tabstop>
+ <tabstop>entryName</tabstop>
+ <tabstop>comboType</tabstop>
+ <tabstop>spinboxHCtrlNo</tabstop>
+ <tabstop>spinboxLCtrlNo</tabstop>
+ <tabstop>spinboxMin</tabstop>
+ <tabstop>spinboxMax</tabstop>
+ <tabstop>buttonNew</tabstop>
+ <tabstop>buttonDelete</tabstop>
+ <tabstop>buttonOk</tabstop>
+ <tabstop>buttonApply</tabstop>
+ <tabstop>buttonCancel</tabstop>
+</tabstops>
+<layoutdefaults spacing="6" margin="11"/>
+</UI>
diff --git a/attic/muse2-oom/muse2/muse/instruments/editinstrument.cpp b/attic/muse2-oom/muse2/muse/instruments/editinstrument.cpp
new file mode 100644
index 00000000..c45ac97a
--- /dev/null
+++ b/attic/muse2-oom/muse2/muse/instruments/editinstrument.cpp
@@ -0,0 +1,3588 @@
+//=========================================================
+// MusE
+// Linux Music Editor
+// $Id: editinstrument.cpp,v 1.2.2.6 2009/05/31 05:12:12 terminator356 Exp $
+//
+// (C) Copyright 2003 Werner Schweer (ws@seh.de)
+//=========================================================
+
+#include <stdio.h>
+#include <errno.h>
+
+#include <QCloseEvent>
+#include <QDir>
+#include <QFileDialog>
+#include <QFileInfo>
+#include <QInputDialog>
+#include <QMessageBox>
+#include <QLineEdit>
+#include <QWhatsThis>
+
+#include "editinstrument.h"
+#include "minstrument.h"
+#include "globals.h"
+#include "song.h"
+#include "xml.h"
+#include "midictrl.h"
+#include "gconfig.h"
+#include "icons.h"
+
+
+enum {
+ COL_NAME = 0, COL_TYPE,
+ COL_HNUM, COL_LNUM, COL_MIN, COL_MAX, COL_DEF
+ };
+
+//---------------------------------------------------------
+// EditInstrument
+//---------------------------------------------------------
+
+EditInstrument::EditInstrument(QWidget* parent, Qt::WFlags fl)
+ : QMainWindow(parent, fl)
+ {
+ setupUi(this);
+ fileNewAction->setIcon(QIcon(*filenewIcon));
+ fileOpenAction->setIcon(QIcon(*openIcon));
+ fileSaveAction->setIcon(QIcon(*saveIcon));
+ fileSaveAsAction->setIcon(QIcon(*saveasIcon));
+ fileExitAction->setIcon(QIcon(*exitIcon));
+ viewController->setSelectionMode(QAbstractItemView::SingleSelection);
+ toolBar->addAction(QWhatsThis::createAction(this));
+ Help->addAction(QWhatsThis::createAction(this));
+
+ ///patchpopup = new QMenu(patchButton);
+ //patchpopup->setCheckable(false);// Qt4 doc says this is unnecessary.
+
+ // populate instrument list
+ // Populate common controller list.
+ for(int i = 0; i < 128; ++i)
+ {
+ QListWidgetItem *lci = new QListWidgetItem(midiCtrlName(i));
+ listController->addItem(lci);
+ }
+ oldMidiInstrument = 0;
+ oldPatchItem = 0;
+ for (iMidiInstrument i = midiInstruments.begin(); i != midiInstruments.end(); ++i) {
+ // Imperfect, crude way of ignoring internal instruments, soft synths etc. If it has a gui,
+ // it must be an internal instrument. But this will still allow some vst instruments (without a gui)
+ // to show up in the list.
+ // Hmm, try file path instead...
+ //if((*i)->hasGui())
+ if((*i)->filePath().isEmpty())
+ continue;
+
+ QListWidgetItem* item = new QListWidgetItem((*i)->iname());
+ QVariant v = qVariantFromValue((void*)(*i));
+ item->setData(Qt::UserRole, v);
+ instrumentList->addItem(item);
+ }
+ instrumentList->setSelectionMode(QAbstractItemView::SingleSelection);
+ if(instrumentList->item(0))
+ instrumentList->setCurrentItem(instrumentList->item(0));
+ //oldMidiInstrument = (MidiInstrument*)((ListBoxData*)instrumentList->item(0))->data();
+ //oldMidiInstrument = (ListBoxData*)instrumentList->item(0);
+ //oldMidiInstrument = (ListBoxData*)instrumentList->selectedItem();
+
+// MidiInstrument* wip = (MidiInstrument*)((ListBoxData*)instrumentList->item(0))->data();
+// if(wip)
+ // Assignment
+// workingInstrument.assign( *wip );
+
+
+ connect(instrumentList, SIGNAL(itemSelectionChanged()), SLOT(instrumentChanged()));
+ connect(patchView, SIGNAL(itemSelectionChanged()), SLOT(patchChanged()));
+
+ //instrumentChanged();
+ changeInstrument();
+
+ //connect(listController, SIGNAL(selectionChanged()), SLOT(controllerChanged()));
+ connect(viewController, SIGNAL(itemSelectionChanged()), SLOT(controllerChanged()));
+
+ //connect(instrumentName, SIGNAL(textChanged(const QString&)), SLOT(instrumentNameChanged(const QString&)));
+ connect(instrumentName, SIGNAL(returnPressed()), SLOT(instrumentNameReturn()));
+ connect(instrumentName, SIGNAL(lostFocus()), SLOT(instrumentNameReturn()));
+
+ connect(patchNameEdit, SIGNAL(returnPressed()), SLOT(patchNameReturn()));
+ connect(patchNameEdit, SIGNAL(lostFocus()), SLOT(patchNameReturn()));
+ connect(patchDelete, SIGNAL(clicked()), SLOT(deletePatchClicked()));
+ connect(patchNew, SIGNAL(clicked()), SLOT(newPatchClicked()));
+ connect(patchNewGroup, SIGNAL(clicked()), SLOT(newGroupClicked()));
+ //connect(newCategory, SIGNAL(clicked()), SLOT(newCategoryClicked()));
+
+ connect(patchButton, SIGNAL(clicked()), SLOT(patchButtonClicked()));
+ connect(defPatchH, SIGNAL(valueChanged(int)), SLOT(defPatchChanged(int)));
+ connect(defPatchL, SIGNAL(valueChanged(int)), SLOT(defPatchChanged(int)));
+ connect(defPatchProg, SIGNAL(valueChanged(int)), SLOT(defPatchChanged(int)));
+ connect(deleteController, SIGNAL(clicked()), SLOT(deleteControllerClicked()));
+ connect(newController, SIGNAL(clicked()), SLOT(newControllerClicked()));
+ connect(addController, SIGNAL(clicked()), SLOT(addControllerClicked()));
+ connect(listController, SIGNAL(itemDoubleClicked(QListWidgetItem*)), SLOT(addControllerClicked()));
+ connect(ctrlType,SIGNAL(activated(int)), SLOT(ctrlTypeChanged(int)));
+ connect(ctrlName, SIGNAL(returnPressed()), SLOT(ctrlNameReturn()));
+ connect(ctrlName, SIGNAL(lostFocus()), SLOT(ctrlNameReturn()));
+ //connect(ctrlName, SIGNAL(textChanged(const QString&)), SLOT(ctrlNameChanged(const QString&)));
+ connect(spinBoxHCtrlNo, SIGNAL(valueChanged(int)), SLOT(ctrlHNumChanged(int)));
+ connect(spinBoxLCtrlNo, SIGNAL(valueChanged(int)), SLOT(ctrlLNumChanged(int)));
+ connect(spinBoxMin, SIGNAL(valueChanged(int)), SLOT(ctrlMinChanged(int)));
+ connect(spinBoxMax, SIGNAL(valueChanged(int)), SLOT(ctrlMaxChanged(int)));
+ connect(spinBoxDefault, SIGNAL(valueChanged(int)), SLOT(ctrlDefaultChanged(int)));
+ connect(nullParamSpinBoxH, SIGNAL(valueChanged(int)), SLOT(ctrlNullParamHChanged(int)));
+ connect(nullParamSpinBoxL, SIGNAL(valueChanged(int)), SLOT(ctrlNullParamLChanged(int)));
+
+ connect(tabWidget3, SIGNAL(currentChanged(QWidget*)), SLOT(tabChanged(QWidget*)));
+ //connect(sysexList, SIGNAL(selectionChanged()), SLOT(sysexChanged()));
+ //connect(deleteSysex, SIGNAL(clicked()), SLOT(deleteSysexClicked()));
+ //connect(newSysex, SIGNAL(clicked()), SLOT(newSysexClicked()));
+ }
+
+//---------------------------------------------------------
+// helpWhatsThis
+//---------------------------------------------------------
+
+void EditInstrument::helpWhatsThis()
+{
+ whatsThis();
+}
+
+//---------------------------------------------------------
+// fileNew
+//---------------------------------------------------------
+
+void EditInstrument::fileNew()
+ {
+ // Allow these to update...
+ instrumentNameReturn();
+ patchNameReturn();
+ ctrlNameReturn();
+
+ for (int i = 1;; ++i) {
+ QString s = QString("Instrument-%1").arg(i);
+ bool found = false;
+ for (iMidiInstrument i = midiInstruments.begin(); i != midiInstruments.end(); ++i) {
+ if (s == (*i)->iname()) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ //if(oldMidiInstrument)
+ //{
+ MidiInstrument* oi = 0;
+ if(oldMidiInstrument)
+ oi = (MidiInstrument*)oldMidiInstrument->data(Qt::UserRole).value<void*>();
+ MidiInstrument* wip = &workingInstrument;
+ //checkDirty(oi);
+ //if(checkDirty(oi))
+ if(checkDirty(wip))
+ // No save was chosen. Restore the actual instrument name.
+ {
+ if(oi)
+ {
+ oldMidiInstrument->setText(oi->iname());
+ //workingInstrument.setIName(oi->iname());
+
+ // No file path? Only a new unsaved instrument can do that. So delete it.
+ if(oi->filePath().isEmpty())
+ // Delete the list item and the instrument.
+ deleteInstrument(oldMidiInstrument);
+
+ }
+ }
+ //else
+ //{
+ // if(oi)
+ // Save was chosen. Assign the working instrument to the actual instrument.
+ // oi->assign(workingInstrument);
+ //}
+
+ //oi->setDirty(false);
+ workingInstrument.setDirty(false);
+ //}
+
+ MidiInstrument* ni = new MidiInstrument(s);
+ //midiInstruments.append(ni);
+ midiInstruments.push_back(ni);
+ //QListWidgetItem* item = new QListWidgetItem(ni->iname());
+ //InstrumentListItem* item = new InstrumentListItem(ni->iname());
+ QListWidgetItem* item = new QListWidgetItem(ni->iname());
+
+ //oldMidiInstrument = item;
+ workingInstrument.assign( *ni );
+ //workingInstrument.setDirty(false);
+
+ //item->setText(ni->iname());
+ QVariant v = qVariantFromValue((void*)(ni));
+ item->setData(Qt::UserRole, v);
+ instrumentList->addItem(item);
+
+ oldMidiInstrument = 0;
+
+ instrumentList->blockSignals(true);
+ instrumentList->setCurrentItem(item);
+ instrumentList->blockSignals(false);
+
+ changeInstrument();
+
+ // We have our new instrument! So set dirty to true.
+ workingInstrument.setDirty(true);
+
+ break;
+ }
+ }
+
+ }
+
+//---------------------------------------------------------
+// fileOpen
+//---------------------------------------------------------
+
+void EditInstrument::fileOpen()
+ {
+ // Allow these to update...
+ //instrumentNameReturn();
+ //patchNameReturn();
+ //ctrlNameReturn();
+
+
+ }
+
+//---------------------------------------------------------
+// fileSave
+//---------------------------------------------------------
+
+void EditInstrument::fileSave()
+{
+ //if (instrument->filePath().isEmpty())
+ if (workingInstrument.filePath().isEmpty())
+ {
+ //fileSaveAs();
+ saveAs();
+ return;
+ }
+
+ // Do not allow a direct overwrite of a 'built-in' muse instrument.
+ QFileInfo qfi(workingInstrument.filePath());
+ if(qfi.absolutePath() == museInstruments)
+ {
+ //fileSaveAs();
+ saveAs();
+ return;
+ }
+
+ //QFile f(instrument->filePath());
+ //if (!f.open(QIODevice::WriteOnly)) {
+ //FILE* f = fopen(instrument->filePath().toLatin1().constData(), "w");
+ FILE* f = fopen(workingInstrument.filePath().toLatin1().constData(), "w");
+ if(f == 0)
+ {
+ //fileSaveAs();
+ saveAs();
+ return;
+ }
+
+ // Allow these to update...
+ instrumentNameReturn();
+ patchNameReturn();
+ ctrlNameReturn();
+
+ //f.close();
+ if(fclose(f) != 0)
+ {
+ //QString s = QString("Creating file:\n") + instrument->filePath() + QString("\nfailed: ")
+ QString s = QString("Creating file:\n") + workingInstrument.filePath() + QString("\nfailed: ")
+ //+ f.errorString();
+ + QString(strerror(errno) );
+ //fprintf(stderr, "poll failed: %s\n", strerror(errno));
+ QMessageBox::critical(this, tr("MusE: Create file failed"), s);
+ return;
+ }
+
+ //if(fileSave(instrument, instrument->filePath()))
+ // instrument->setDirty(false);
+ if(fileSave(&workingInstrument, workingInstrument.filePath()))
+ workingInstrument.setDirty(false);
+}
+
+//---------------------------------------------------------
+// fileSave
+//---------------------------------------------------------
+
+bool EditInstrument::fileSave(MidiInstrument* instrument, const QString& name)
+ {
+ //QFile f(name);
+ //if (!f.open(QIODevice::WriteOnly)) {
+ // QString s("Creating file failed: ");
+ // s += strerror(errno);
+ // QMessageBox::critical(this,
+ // tr("MusE: Create file failed"), s);
+ // return false;
+ // }
+ //Xml xml(&f);
+
+ FILE* f = fopen(name.toAscii().constData(), "w");
+ if(f == 0)
+ {
+ //if(debugMsg)
+ // printf("READ IDF %s\n", fi->filePath().toLatin1().constData());
+ QString s("Creating file failed: ");
+ s += QString(strerror(errno));
+ QMessageBox::critical(this,
+ tr("MusE: Create file failed"), s);
+ return false;
+ }
+
+ Xml xml(f);
+
+ updateInstrument(instrument);
+
+ //instrument->write(xml);
+ instrument->write(0, xml);
+
+ // Assign the working instrument values to the actual current selected instrument...
+ if(oldMidiInstrument)
+ {
+ MidiInstrument* oi = (MidiInstrument*)oldMidiInstrument->data(Qt::UserRole).value<void*>();
+ if(oi)
+ {
+ oi->assign(workingInstrument);
+
+ // Now signal the rest of the app so stuff can change...
+ song->update(SC_CONFIG | SC_MIDI_CONTROLLER);
+ //song->update(SC_CONFIG | SC_MIDI_CONTROLLER | SC_MIDI_CONTROLLER_ADD);
+ }
+ }
+
+ //f.close();
+ //if (f.error()) {
+ if(fclose(f) != 0)
+ {
+ QString s = QString("Write File\n") + name + QString("\nfailed: ")
+ //+ f.errorString();
+ + QString(strerror(errno));
+ //fprintf(stderr, "poll failed: %s\n", strerror(errno));
+ QMessageBox::critical(this, tr("MusE: Write File failed"), s);
+ return false;
+ }
+ return true;
+ }
+
+//---------------------------------------------------------
+// saveAs
+//---------------------------------------------------------
+
+void EditInstrument::saveAs()
+ {
+ // Allow these to update...
+ instrumentNameReturn();
+ patchNameReturn();
+ ctrlNameReturn();
+
+ //QListWidgetItem* item = instrumentList->currentItem();
+// ListBoxData* item = (ListBoxData*)instrumentList->selectedItem();
+// if (item == 0)
+// return;
+ //MidiInstrument* instrument = (MidiInstrument*)item->data(Qt::UserRole).value<void*>();
+// MidiInstrument* instrument = (MidiInstrument*)item->data();
+
+ //QString path = QDir::homePath() + "/" + config.instrumentPath;
+ //QString path = QDir::homeDirPath() + "/" + museGlobalShare;
+ //QString path = museInstruments;
+ QString path = museUserInstruments;
+
+ if(!QDir(museUserInstruments).exists())
+ {
+ if(QMessageBox::question(this,
+ tr("MusE:"),
+ tr("The user instrument directory\n") + museUserInstruments + tr("\ndoes not exist yet. Create it now?\n") +
+ tr("(You can change the user instruments directory at Settings->Global Settings->Midi)"),
+ QMessageBox::Ok | QMessageBox::Default,
+ QMessageBox::Cancel | QMessageBox::Escape,
+ Qt::NoButton) == QMessageBox::Ok)
+ {
+ if(QDir().mkdir(museUserInstruments))
+ printf("Created user instrument directory: %s\n", museUserInstruments.toLatin1().constData());
+ else
+ {
+ printf("Unable to create user instrument directory: %s\n", museUserInstruments.toLatin1().constData());
+ QMessageBox::critical(this, tr("MusE:"), tr("Unable to create user instrument directory\n") + museUserInstruments);
+ //return;
+ path = museUser;
+ }
+ }
+ else
+ // return;
+ path = museUser;
+ }
+
+ //if (instrument->filePath().isEmpty())
+ if (workingInstrument.filePath().isEmpty())
+ path += QString("/%1.idf").arg(workingInstrument.iname());
+ else {
+ //QFileInfo fi(instrument->filePath());
+ QFileInfo fi(workingInstrument.filePath());
+
+ // Prompt for a new instrument name if the name has not been changed, to avoid duplicates.
+ if(oldMidiInstrument)
+ {
+ MidiInstrument* oi = (MidiInstrument*)oldMidiInstrument->data(Qt::UserRole).value<void*>();
+ if(oi)
+ {
+ if(oi->iname() == workingInstrument.iname())
+ {
+ // Prompt only if it's a user instrument, to avoid duplicates in the user instrument dir.
+ // This will still allow a user instrument to override a built-in instrument with the same name.
+ if(fi.absolutePath() != museInstruments)
+ {
+ //QMessageBox::critical(this,
+ // tr("MusE: Bad instrument name"),
+ // tr("Please change the instrument name to a new unique name before saving, to avoid duplicates"),
+ // QMessageBox::Ok,
+ // QMessageBox::NoButton,
+ // QMessageBox::NoButton);
+ printf("EditInstrument::saveAs Error: Instrument name %s already used!\n", workingInstrument.iname().toLatin1().constData());
+ return;
+ }
+ }
+ }
+ }
+ path += QString("/%1.idf").arg(fi.baseName());
+ }
+ //QString s = QFileDialog::getSaveFileName(this,
+ // tr("MusE: Save Instrument Definition"),
+ // path,
+ // tr("Instrument Definition (*.idf)"));
+
+ QString s = QFileDialog::getSaveFileName(this, tr("MusE: Save Instrument Definition").toLatin1().constData(),
+ path, tr("Instrument Definition (*.idf)"));
+ if (s.isEmpty())
+ return;
+ //instrument->setFilePath(s);
+ workingInstrument.setFilePath(s);
+
+ //if (fileSave(instrument, s))
+ // instrument->setDirty(false);
+ if(fileSave(&workingInstrument, s))
+ workingInstrument.setDirty(false);
+ }
+
+//---------------------------------------------------------
+// fileSaveAs
+//---------------------------------------------------------
+
+void EditInstrument::fileSaveAs()
+ {
+ // Is this a new unsaved instrument? Just do a normal save.
+ if(workingInstrument.filePath().isEmpty())
+ {
+ saveAs();
+ return;
+ }
+
+ // Allow these to update...
+ instrumentNameReturn();
+ patchNameReturn();
+ ctrlNameReturn();
+
+ MidiInstrument* oi = 0;
+ if(oldMidiInstrument)
+ oi = (MidiInstrument*)oldMidiInstrument->data(Qt::UserRole).value<void*>();
+
+ int res = checkDirty(&workingInstrument, true);
+ switch(res)
+ {
+ // No save:
+ case 1:
+ //item->setText(instrument->iname());
+ //instrumentList->triggerUpdate(true);
+ //instrument->setDirty(false);
+ workingInstrument.setDirty(false);
+ if(oi)
+ {
+ oldMidiInstrument->setText(oi->iname());
+ //workingInstrument.setIName(oi->iname());
+
+ //workingInstrument.assign(*oi);
+
+ // No file path? Only a new unsaved instrument can do that. So delete it.
+ if(oi->filePath().isEmpty())
+ {
+ // Delete the list item and the instrument.
+ deleteInstrument(oldMidiInstrument);
+ oldMidiInstrument = 0;
+ }
+
+ changeInstrument();
+
+ }
+ return;
+ break;
+
+ // Abort:
+ case 2:
+ return;
+ break;
+
+ // Save:
+ case 0:
+ //if(oi)
+ // oi->assign(workingInstrument);
+ workingInstrument.setDirty(false);
+ break;
+ }
+
+ //QListWidgetItem* item = instrumentList->currentItem();
+// ListBoxData* item = (ListBoxData*)instrumentList->selectedItem();
+// if (item == 0)
+// return;
+ //MidiInstrument* instrument = (MidiInstrument*)item->data(Qt::UserRole).value<void*>();
+// MidiInstrument* instrument = (MidiInstrument*)item->data();
+
+ bool isuser = false;
+ QString so;
+ if(workingInstrument.iname().isEmpty())
+ so = QString("Instrument");
+ else
+ so = workingInstrument.iname();
+
+ for(int i = 1;; ++i)
+ {
+ QString s = so + QString("-%1").arg(i);
+
+ bool found = false;
+ for(iMidiInstrument imi = midiInstruments.begin(); imi != midiInstruments.end(); ++imi)
+ {
+ if(s == (*imi)->iname())
+ {
+ // Allow override of built-in instrument names.
+ QFileInfo fi((*imi)->filePath());
+ if(fi.absolutePath() == museInstruments)
+ break;
+ found = true;
+ break;
+ }
+ }
+ if(found)
+ continue;
+
+ bool ok;
+ s = QInputDialog::getText(this, tr("MusE: Save instrument as"), tr("Enter a new unique instrument name:"),
+ QLineEdit::Normal, s, &ok);
+ if(!ok)
+ return;
+ if(s.isEmpty())
+ {
+ --i;
+ continue;
+ }
+
+ isuser = false;
+ bool builtin = false;
+ found = false;
+ for(iMidiInstrument imi = midiInstruments.begin(); imi != midiInstruments.end(); ++imi)
+ {
+ // If an instrument with the same name is found...
+ if((*imi)->iname() == s)
+ {
+ // If it's not the same name as the working instrument, and it's not an internal instrument (soft synth etc.)...
+ if(s != workingInstrument.iname() && !(*imi)->filePath().isEmpty())
+ {
+ QFileInfo fi((*imi)->filePath());
+ // Allow override of built-in and user instruments:
+ // If it's a user instrument, not a built-in instrument...
+ if(fi.absolutePath() == museUserInstruments)
+ {
+ // No choice really but to overwrite the destination instrument file!
+ // Can not have two user files containing the same instrument name.
+ if(QMessageBox::question(this,
+ tr("MusE: Save instrument as"),
+ tr("The user instrument:\n") + s + tr("\nalready exists. This will overwrite its .idf instrument file.\nAre you sure?"),
+ QMessageBox::Ok | QMessageBox::Default,
+ QMessageBox::Cancel | QMessageBox::Escape,
+ Qt::NoButton) == QMessageBox::Ok)
+ {
+ // Set the working instrument's file path to the found instrument's path.
+ workingInstrument.setFilePath((*imi)->filePath());
+ // Mark as overwriting a user instrument.
+ isuser = true;
+ }
+ else
+ {
+ found = true;
+ break;
+ }
+ }
+ // Assign the found instrument to the working instrument.
+ //workingInstrument.assign(*(*imi));
+ // Assign the found instrument name to the working instrument name.
+ workingInstrument.setIName(s);
+
+ // Find the instrument in the list and set the old instrument to the item.
+ oldMidiInstrument = instrumentList->findItems(s, Qt::MatchExactly)[0];
+
+ // Mark as a built-in instrument.
+ builtin = true;
+ break;
+ }
+ found = true;
+ break;
+ }
+ }
+ if(found)
+ {
+ so = s;
+ i = 0;
+ continue;
+ }
+
+ so = s;
+
+ // If the name does not belong to a built-in instrument...
+ if(!builtin)
+ {
+ MidiInstrument* ni = new MidiInstrument();
+ ni->assign(workingInstrument);
+ ni->setIName(so);
+ ni->setFilePath(QString());
+ //midiInstruments.append(ni);
+ midiInstruments.push_back(ni);
+ //QListWidgetItem* item = new QListWidgetItem(ni->iname());
+ //InstrumentListItem* item = new InstrumentListItem(ni->iname());
+ //ListBoxData* item = new ListBoxData(ni->iname());
+ QListWidgetItem* item = new QListWidgetItem(so);
+
+ //oldMidiInstrument = item;
+ workingInstrument.assign( *ni );
+ //workingInstrument.setDirty(false);
+
+ //item->setText(ni->iname());
+ //item->setData((void*)ni);
+ QVariant v = qVariantFromValue((void*)(ni));
+ item->setData(Qt::UserRole, v);
+ //instrumentList->addItem(item);
+ instrumentList->addItem(item);
+
+ oldMidiInstrument = 0;
+
+ instrumentList->blockSignals(true);
+ instrumentList->setCurrentItem(item);
+ instrumentList->blockSignals(false);
+
+ changeInstrument();
+
+ // We have our new instrument! So set dirty to true.
+ workingInstrument.setDirty(true);
+ }
+
+ break;
+ }
+
+ //QString path = QDir::homePath() + "/" + config.instrumentPath;
+ //QString path = QDir::homeDirPath() + "/" + museGlobalShare;
+ //QString path = museInstruments;
+ QString path = museUserInstruments;
+
+ if(!QDir(museUserInstruments).exists())
+ {
+ if(QMessageBox::question(this,
+ tr("MusE:"),
+ tr("The user instrument directory\n") + museUserInstruments + tr("\ndoes not exist yet. Create it now?\n") +
+ tr("(You can change the user instruments directory at Settings->Global Settings->Midi)"),
+ QMessageBox::Ok | QMessageBox::Default,
+ QMessageBox::Cancel | QMessageBox::Escape,
+ Qt::NoButton) == QMessageBox::Ok)
+ {
+ if(QDir().mkdir(museUserInstruments))
+ printf("Created user instrument directory: %s\n", museUserInstruments.toLatin1().constData());
+ else
+ {
+ printf("Unable to create user instrument directory: %s\n", museUserInstruments.toLatin1().constData());
+ QMessageBox::critical(this, tr("MusE:"), tr("Unable to create user instrument directory\n") + museUserInstruments);
+ //return;
+ path = museUser;
+ }
+ }
+ else
+ // return;
+ path = museUser;
+ }
+ path += QString("/%1.idf").arg(so);
+
+ //QString s = QFileDialog::getSaveFileName(this,
+ // tr("MusE: Save Instrument Definition"),
+ // path,
+ // tr("Instrument Definition (*.idf)"));
+
+ QString sfn;
+ // If we are overwriting a user instrument just force the path.
+ if(isuser)
+ sfn = path;
+ else
+ {
+ sfn = QFileDialog::getSaveFileName(this, tr("MusE: Save Instrument Definition").toLatin1().constData(),
+ path, tr("Instrument Definition (*.idf)"));
+ if (sfn.isEmpty())
+ return;
+ //instrument->setFilePath(s);
+ workingInstrument.setFilePath(sfn);
+ }
+
+ //if (fileSave(instrument, s))
+ // instrument->setDirty(false);
+ if(fileSave(&workingInstrument, sfn))
+ workingInstrument.setDirty(false);
+ }
+
+//---------------------------------------------------------
+// fileExit
+//---------------------------------------------------------
+
+void EditInstrument::fileExit()
+ {
+
+ }
+
+//---------------------------------------------------------
+// closeEvent
+//---------------------------------------------------------
+
+void EditInstrument::closeEvent(QCloseEvent* ev)
+ {
+ // Allow these to update...
+ instrumentNameReturn();
+ patchNameReturn();
+ ctrlNameReturn();
+
+ //QListWidgetItem* item = instrumentList->currentItem();
+
+// ListBoxData* item = (ListBoxData*)instrumentList->selectedItem();
+
+// if(item)
+// {
+ //MidiInstrument* instrument = (MidiInstrument*)item->data(Qt::UserRole).value<void*>();
+// MidiInstrument* instrument = (MidiInstrument*)item->data();
+// int res = checkDirty(instrument, true);
+ MidiInstrument* oi = 0;
+ if(oldMidiInstrument)
+ oi = (MidiInstrument*)oldMidiInstrument->data(Qt::UserRole).value<void*>();
+
+ int res = checkDirty(&workingInstrument, true);
+ switch(res)
+ {
+ // No save:
+ case 1:
+ //item->setText(instrument->iname());
+ //instrumentList->triggerUpdate(true);
+ //instrument->setDirty(false);
+ workingInstrument.setDirty(false);
+ if(oi)
+ {
+ oldMidiInstrument->setText(oi->iname());
+ //workingInstrument.setIName(oi->iname());
+
+ //workingInstrument.assign(*oi);
+
+ // No file path? Only a new unsaved instrument can do that. So delete it.
+ if(oi->filePath().isEmpty())
+ {
+ // Delete the list item and the instrument.
+ deleteInstrument(oldMidiInstrument);
+ oldMidiInstrument = 0;
+ }
+
+ changeInstrument();
+
+ }
+ break;
+
+ // Abort:
+ case 2:
+ ev->ignore();
+ return;
+ break;
+
+ // Save:
+ case 0:
+ //if(oi)
+ // oi->assign(workingInstrument);
+ workingInstrument.setDirty(false);
+ break;
+
+ }
+
+// }
+
+ QMainWindow::closeEvent(ev);
+ }
+
+//---------------------------------------------------------
+// changeInstrument
+//---------------------------------------------------------
+
+void EditInstrument::changeInstrument()
+{
+ QListWidgetItem* sel = instrumentList->currentItem();
+
+ if(!sel)
+ return;
+
+ //oldMidiInstrument = (MidiInstrument*)sel->data();
+ oldMidiInstrument = sel;
+ // Assignment
+ //workingInstrument = *((MidiInstrument*)sel->data());
+
+ // Assign will 'delete' any existing patches, groups, or controllers.
+ workingInstrument.assign( *((MidiInstrument*)sel->data(Qt::UserRole).value<void*>()) );
+
+ workingInstrument.setDirty(false);
+
+ // populate patch list
+ patchView->blockSignals(true);
+ for (int i = 0; i < patchView->topLevelItemCount(); ++i)
+ qDeleteAll(patchView->topLevelItem(i)->takeChildren());
+ patchView->clear();
+ patchView->blockSignals(false);
+
+ //viewController->blockSignals(true);
+ for (int i = 0; i < viewController->topLevelItemCount(); ++i)
+ qDeleteAll(viewController->topLevelItem(i)->takeChildren());
+ viewController->clear();
+ //viewController->blockSignals(false);
+
+ //listController->clear();
+ //category->clear();
+ //sysexList->clear();
+
+
+ //MidiInstrument* instrument = (MidiInstrument*)sel->data(Qt::UserRole).value<void*>();
+ //MidiInstrument* instrument = (MidiInstrument*)sel->data();
+ //instrument->setDirty(false);
+
+ instrumentName->blockSignals(true);
+ //instrumentName->setText(instrument->iname());
+ instrumentName->setText(workingInstrument.iname());
+ instrumentName->blockSignals(false);
+
+ nullParamSpinBoxH->blockSignals(true);
+ nullParamSpinBoxL->blockSignals(true);
+ int nv = workingInstrument.nullSendValue();
+ if(nv == -1)
+ {
+ nullParamSpinBoxH->setValue(-1);
+ nullParamSpinBoxL->setValue(-1);
+ }
+ else
+ {
+ int nvh = (nv >> 8) & 0xff;
+ int nvl = nv & 0xff;
+ if(nvh == 0xff)
+ nullParamSpinBoxH->setValue(-1);
+ else
+ nullParamSpinBoxH->setValue(nvh & 0x7f);
+ if(nvl == 0xff)
+ nullParamSpinBoxL->setValue(-1);
+ else
+ nullParamSpinBoxL->setValue(nvl & 0x7f);
+ }
+ nullParamSpinBoxH->blockSignals(false);
+ nullParamSpinBoxL->blockSignals(false);
+
+ //std::vector<PatchGroup>* pg = instrument->groups();
+ //PatchGroupList* pg = instrument->groups();
+ PatchGroupList* pg = workingInstrument.groups();
+ //for (std::vector<PatchGroup>::iterator g = pg->begin(); g != pg->end(); ++g) {
+ for (ciPatchGroup g = pg->begin(); g != pg->end(); ++g) {
+ PatchGroup* pgp = *g;
+ if(pgp)
+ {
+ //QTreeWidgetItem* item = new QTreeWidgetItem;
+ QTreeWidgetItem* item = new QTreeWidgetItem(patchView);
+
+ //item->setText(0, g->name);
+ item->setText(0, pgp->name);
+ //QVariant v = QVariant::fromValue((void*)0);
+ //item->setData(0, Qt::UserRole, v);
+ //item->setData((void*)*g);
+ //item->setData((void*)0);
+ //item->setData((void*)&*g);
+ //item->setData((void*)pgp);
+ QVariant v = qVariantFromValue((void*)(pgp));
+ item->setData(0, Qt::UserRole, v);
+ //patchView->addTopLevelItem(item);
+
+ //for (ciPatch p = g->patches.begin(); p != g->patches.end(); ++p)
+ for (ciPatch p = pgp->patches.begin(); p != pgp->patches.end(); ++p)
+ {
+ //const Patch& patch = *p;
+ Patch* patch = *p;
+ if(patch)
+ {
+ //QTreeWidgetItem* sitem = new QTreeWidgetItem;
+ QTreeWidgetItem* sitem = new QTreeWidgetItem(item);
+ //printf("%s \n", qPrintable(patch->name));
+
+ //sitem->setText(0, patch.name);
+ //sitem->setText(0, p->name);
+ sitem->setText(0, patch->name);
+ //QVariant v = QVariant::fromValue((void*)patch);
+ //sitem->setData(0, Qt::UserRole, v);
+ //sitem->setData((void*)&*p);
+ //sitem->setData((void*)patch);
+ QVariant v = QVariant::fromValue((void*)patch);
+ sitem->setData(0, Qt::UserRole, v);
+ //item->addChild(sitem);
+ }
+ }
+ }
+ }
+ //patchView->setSelected(patchView->item(0), true);
+
+ oldPatchItem = 0;
+
+ QTreeWidgetItem* fc = patchView->topLevelItem(0);
+ if(fc)
+ {
+ // This may cause a patchChanged call.
+ //if(patchView->selectedItem() != fc)
+ patchView->blockSignals(true);
+ fc->setSelected(true);
+ patchView->blockSignals(false);
+ //else
+ // patchChanged();
+
+ //patchView->firstChild()->setSelected(true);
+ //patchView->triggerUpdate(true);
+ }
+
+ patchChanged();
+
+// oldPatchItem = (ListViewData*)patchView->selectedItem();
+ //patchChanged();
+// if(oldPatchItem)
+// {
+// if(oldPatchItem->parent())
+// patchNameEdit->setText( ((Patch*)oldPatchItem->data())->name );
+// else
+// patchNameEdit->setText( ((PatchGroup*)oldPatchItem->data())->name );
+// }
+
+ //MidiControllerList* cl = instrument->controller();
+ MidiControllerList* cl = workingInstrument.controller();
+ for (ciMidiController ic = cl->begin(); ic != cl->end(); ++ic) {
+ MidiController* c = ic->second;
+ //QListWidgetItem* item = new QListWidgetItem(c->name());
+ // ListBoxData* item = new ListBoxData(c->name());
+ //QVariant v = QVariant::fromValue((void*)c);
+ //item->setData(Qt::UserRole, v);
+ // item->setData((void*)c);
+ // listController->insertItem(item);
+
+ addControllerToView(c);
+ }
+
+
+ //listController->setItemSelected(listController->item(0), true);
+
+// oldController = 0;
+
+ //ListBoxData* ci = (ListBoxData*)listController->item(0);
+
+ QTreeWidgetItem *ci = viewController->topLevelItem(0);
+
+ if(ci)
+ {
+ // This may cause a controllerChanged call.
+ //if(listController->selectedItem != ci)
+ // listController->blockSignals(true);
+ // listController->setSelected(ci, true);
+ // listController->blockSignals(false);
+ //else
+ // controllerChanged();
+
+ viewController->blockSignals(true);
+ ci->setSelected(true);
+ viewController->blockSignals(false);
+ }
+
+ controllerChanged();
+
+ //oldController = (ListBoxData*)listController->selectedItem();
+
+
+ //controllerChanged(listController->item(0), 0);
+ //controllerChanged();
+
+/*
+ category->addItems(instrument->categories());
+
+ foreach(const SysEx* s, instrument->sysex()) {
+ QListWidgetItem* item = new QListWidgetItem(s->name);
+ QVariant v = QVariant::fromValue((void*)s);
+ item->setData(Qt::UserRole, v);
+ sysexList->addItem(item);
+ }
+
+ sysexList->setItemSelected(sysexList->item(0), true);
+ sysexChanged(sysexList->item(0), 0);
+
+ if (!cl->empty()) {
+ listController->setItemSelected(listController->item(0), true);
+ controllerChanged(listController->item(0), 0);
+ }
+*/
+
+
+}
+
+//---------------------------------------------------------
+// instrumentChanged
+//---------------------------------------------------------
+
+void EditInstrument::instrumentChanged()
+ {
+ QListWidgetItem* sel = instrumentList->currentItem();
+
+ if(!sel)
+ return;
+
+ //printf("instrument changed: %s\n", sel->text().toLatin1().constData());
+
+ //if (old) {
+ //if(oldMidiInstrument)
+ //{
+ MidiInstrument* oi = 0;
+ if(oldMidiInstrument)
+ oi = (MidiInstrument*)oldMidiInstrument->data(Qt::UserRole).value<void*>();
+ MidiInstrument* wip = &workingInstrument;
+ // Returns true if aborted.
+ //checkDirty(oi);
+ //if(checkDirty(oi))
+ if(checkDirty(wip))
+ {
+ // No save was chosen. Abandon changes, or delete if it is new...
+ if(oi)
+ {
+ oldMidiInstrument->setText(oi->iname());
+ //wip->setText(oi->iname());
+
+ // No file path? Only a new unsaved instrument can do that. So delete it.
+ if(oi->filePath().isEmpty())
+ {
+ // Delete the list item and the instrument.
+ deleteInstrument(oldMidiInstrument);
+ oldMidiInstrument = 0;
+ }
+
+ }
+ }
+ //else
+ //{
+ // Save was chosen.
+ // if(oi)
+ // oi->assign(workingInstrument);
+ //}
+
+ //oi->setDirty(false);
+ //wip->setDirty(false);
+ workingInstrument.setDirty(false);
+ //}
+
+ changeInstrument();
+
+ }
+
+//---------------------------------------------------------
+// instrumentNameReturn
+//---------------------------------------------------------
+
+void EditInstrument::instrumentNameReturn()
+//void EditInstrument::instrumentNameChanged(const QString& s)
+{
+ //instrumentNameChanged(instrumentName->text());
+ QListWidgetItem* item = instrumentList->currentItem();
+
+ if (item == 0)
+ return;
+ QString s = instrumentName->text();
+
+ if(s == item->text())
+ return;
+
+ MidiInstrument* curins = (MidiInstrument*)item->data(Qt::UserRole).value<void*>();
+
+ for(iMidiInstrument i = midiInstruments.begin(); i != midiInstruments.end(); ++i)
+ {
+ if((*i) != curins && s == (*i)->iname())
+ {
+ instrumentName->blockSignals(true);
+ // Grab the last valid name from the item text, since the instrument has not been updated yet.
+ //instrumentName->setText(curins->iname());
+ instrumentName->setText(item->text());
+ instrumentName->blockSignals(false);
+
+ QMessageBox::critical(this,
+ tr("MusE: Bad instrument name"),
+ tr("Please choose a unique instrument name.\n(The name might be used by a hidden instrument.)"),
+ QMessageBox::Ok,
+ Qt::NoButton,
+ Qt::NoButton);
+
+ return;
+ }
+ }
+
+ //if (s != workingInstrument.iname()) {
+ item->setText(s);
+ //MidiInstrument* instrument = (MidiInstrument*)item->data(Qt::UserRole).value<void*>();
+ //MidiInstrument* instrument = (MidiInstrument*)item->data();
+ //instrument->setDirty(true);
+ workingInstrument.setIName(s);
+ workingInstrument.setDirty(true);
+ //instrumentList->updateItem(item);
+ //instrumentList->update();
+ // }
+}
+
+//---------------------------------------------------------
+// deleteInstrument
+//---------------------------------------------------------
+
+void EditInstrument::deleteInstrument(QListWidgetItem* item)
+{
+ if(!item)
+ return;
+
+ //ListBoxData* curritem = (ListBoxData*)instrumentList->selectedItem();
+
+ MidiInstrument* ins = (MidiInstrument*)item->data(Qt::UserRole).value<void*>();
+
+ // Be kind to the list item, just in case we install a delete handler or something.
+ //item->setData(0);
+
+ // Delete the list item.
+ // Test this: Is this going to change the current selection?
+ instrumentList->blockSignals(true);
+ delete item;
+ instrumentList->blockSignals(false);
+
+ // Test this: Neccessary?
+ // if(curritem)
+ // instrumentList->setCurrentItem(curritem);
+
+ if(!ins)
+ return;
+
+ // Remove the instrument from the list.
+ midiInstruments.remove(ins);
+
+ // Delete the instrument.
+ delete ins;
+}
+
+//---------------------------------------------------------
+// tabChanged
+// Added so that patch list is updated when switching tabs,
+// so that 'Program' default values and text are current in controller tab.
+//---------------------------------------------------------
+
+void EditInstrument::tabChanged(QWidget* w)
+{
+ if(!w)
+ return;
+
+ // If we're switching to the Patches tab, just ignore.
+ if(QString(w->objectName()) == QString("patchesTab"))
+ return;
+
+ if(oldPatchItem)
+ {
+ // Don't bother calling patchChanged, just update the patch or group.
+ if(oldPatchItem->QTreeWidgetItem::parent())
+ updatePatch(&workingInstrument, (Patch*)oldPatchItem->data(0, Qt::UserRole).value<void*>());
+ else
+ updatePatchGroup(&workingInstrument, (PatchGroup*)oldPatchItem->data(0, Qt::UserRole).value<void*>());
+ }
+
+ // We're still on the same item. No need to set oldPatchItem as in patchChanged...
+
+ // If we're switching to the Controller tab, update the default patch button text in case a patch changed...
+ if(QString(w->objectName()) == QString("controllerTab"))
+ {
+ QTreeWidgetItem* sel = viewController->currentItem();
+
+ if(!sel || !sel->data(0, Qt::UserRole).value<void*>())
+ return;
+
+ MidiController* c = (MidiController*)sel->data(0, Qt::UserRole).value<void*>();
+ MidiController::ControllerType type = midiControllerType(c->num());
+
+ // Grab the controller number from the actual values showing
+ // and set the patch button text.
+ if(type == MidiController::Program)
+ setDefaultPatchName(getDefaultPatchNumber());
+ }
+}
+
+//---------------------------------------------------------
+// patchNameReturn
+//---------------------------------------------------------
+
+void EditInstrument::patchNameReturn()
+{
+ QTreeWidgetItem* item = patchView->currentItem();
+
+ if (item == 0)
+ return;
+
+ QString s = patchNameEdit->text();
+
+ if(item->text(0) == s)
+ return;
+
+ PatchGroupList* pg = workingInstrument.groups();
+ for(iPatchGroup g = pg->begin(); g != pg->end(); ++g)
+ {
+ PatchGroup* pgp = *g;
+ // If the item has a parent, it's a patch item.
+ if(item->QTreeWidgetItem::parent())
+ {
+ Patch* curp = (Patch*)item->data(0, Qt::UserRole).value<void*>();
+ for(iPatch p = pgp->patches.begin(); p != pgp->patches.end(); ++p)
+ {
+ if((*p) != curp && (*p)->name == s)
+ {
+ patchNameEdit->blockSignals(true);
+ // Grab the last valid name from the item text, since the patch has not been updated yet.
+ //patchNameEdit->setText(curp->name);
+ patchNameEdit->setText(item->text(0));
+ patchNameEdit->blockSignals(false);
+
+ QMessageBox::critical(this,
+ tr("MusE: Bad patch name"),
+ tr("Please choose a unique patch name"),
+ QMessageBox::Ok,
+ Qt::NoButton,
+ Qt::NoButton);
+
+ return;
+ }
+ }
+ }
+ else
+ // The item has no parent. It's a patch group item.
+ {
+ PatchGroup* curpg = (PatchGroup*)item->data(0, Qt::UserRole).value<void*>();
+ if(pgp != curpg && pgp->name == s)
+ {
+ patchNameEdit->blockSignals(true);
+ // Grab the last valid name from the item text, since the patch group has not been updated yet.
+ //patchNameEdit->setText(curpg->name);
+ patchNameEdit->setText(item->text(0));
+ patchNameEdit->blockSignals(false);
+
+ QMessageBox::critical(this,
+ tr("MusE: Bad patchgroup name"),
+ tr("Please choose a unique patchgroup name"),
+ QMessageBox::Ok,
+ Qt::NoButton,
+ Qt::NoButton);
+
+ return;
+ }
+ }
+ }
+
+ item->setText(0, s);
+ workingInstrument.setDirty(true);
+
+ // Since the name of the patch/group in the working instrument will be updated later,
+ // there's no need to do manually set the name here now.
+ /*
+ // If the item has a parent, it's a patch item.
+ if(item->parent())
+ {
+ Patch* p = item->data();
+ if(s != p->name)
+ {
+ item->setText(s);
+ p->name = s;
+ workingInstrument.setDirty(true);
+ //patchView->triggerUpdate(true);
+ }
+ }
+ else
+ // The item has no parent. It's a patch group item.
+ {
+ PatchGroup* pg = (PatchGroup*)item->data();
+ if(s != pg->name)
+ {
+ item->setText(s);
+ pg->name = s;
+ workingInstrument.setDirty(true);
+ //patchView->triggerUpdate(true);
+ }
+ }
+ */
+}
+
+//---------------------------------------------------------
+// patchChanged
+//---------------------------------------------------------
+void EditInstrument::patchChanged()
+ {
+ //if (old && old->data(0, Qt::UserRole).value<void*>()) {
+ if(oldPatchItem)
+ {
+ //QListWidgetItem* item = instrumentList->currentItem();
+ //if (item == 0)
+ // return;
+ //MidiInstrument* instrument = (MidiInstrument*)item->data(Qt::UserRole).value<void*>();
+ //Patch* p = (Patch*)old->data(0, Qt::UserRole).value<void*>();
+ //updatePatch(instrument, p);
+ if(oldPatchItem->parent())
+ updatePatch(&workingInstrument, (Patch*)oldPatchItem->data(0, Qt::UserRole).value<void*>());
+ else
+ updatePatchGroup(&workingInstrument, (PatchGroup*)oldPatchItem->data(0, Qt::UserRole).value<void*>());
+ }
+
+ QTreeWidgetItem* sel = patchView->selectedItems().size() ? patchView->selectedItems()[0] : 0;
+ oldPatchItem = sel;
+
+ if(!sel || !sel->data(0, Qt::UserRole).value<void*>())
+ {
+ patchNameEdit->setText("");
+ spinBoxHBank->setEnabled(false);
+ spinBoxLBank->setEnabled(false);
+ spinBoxProgram->setEnabled(false);
+ checkBoxDrum->setEnabled(false);
+ checkBoxGM->setEnabled(false);
+ checkBoxGS->setEnabled(false);
+ checkBoxXG->setEnabled(false);
+ return;
+ }
+
+ // If the item has a parent, it's a patch item.
+ if(sel->parent())
+ {
+ Patch* p = (Patch*)sel->data(0, Qt::UserRole).value<void*>();
+ patchNameEdit->setText(p->name);
+ spinBoxHBank->setEnabled(true);
+ spinBoxLBank->setEnabled(true);
+ spinBoxProgram->setEnabled(true);
+ checkBoxDrum->setEnabled(true);
+ checkBoxGM->setEnabled(true);
+ checkBoxGS->setEnabled(true);
+ checkBoxXG->setEnabled(true);
+
+ int hb = ((p->hbank + 1) & 0xff);
+ int lb = ((p->lbank + 1) & 0xff);
+ int pr = ((p->prog + 1) & 0xff);
+ spinBoxHBank->setValue(hb);
+ spinBoxLBank->setValue(lb);
+ spinBoxProgram->setValue(pr);
+ //checkBoxDrum->setChecked(p->drumMap);
+ checkBoxDrum->setChecked(p->drum);
+ checkBoxGM->setChecked(p->typ & 1);
+ checkBoxGS->setChecked(p->typ & 2);
+ checkBoxXG->setChecked(p->typ & 4);
+ //category->setCurrentIndex(p->categorie);
+ }
+ else
+ // The item is a patch group item.
+ {
+ patchNameEdit->setText( ((PatchGroup*)sel->data(0, Qt::UserRole).value<void*>())->name );
+ spinBoxHBank->setEnabled(false);
+ spinBoxLBank->setEnabled(false);
+ spinBoxProgram->setEnabled(false);
+ checkBoxDrum->setEnabled(false);
+ checkBoxGM->setEnabled(false);
+ checkBoxGS->setEnabled(false);
+ checkBoxXG->setEnabled(false);
+ }
+ }
+
+//---------------------------------------------------------
+// defPatchChanged
+//---------------------------------------------------------
+
+void EditInstrument::defPatchChanged(int)
+{
+ QTreeWidgetItem* item = viewController->currentItem();
+
+ if (!item)
+ return;
+
+ MidiController* c = (MidiController*)item->data(0, Qt::UserRole).value<void*>();
+
+ int val = getDefaultPatchNumber();
+
+ //if(val == c->minVal() - 1)
+ // c->setInitVal(CTRL_VAL_UNKNOWN);
+ //else
+ c->setInitVal(val);
+
+ setDefaultPatchName(val);
+
+ item->setText(COL_DEF, getPatchItemText(val));
+ workingInstrument.setDirty(true);
+}
+
+//---------------------------------------------------------
+// patchButtonClicked
+//---------------------------------------------------------
+
+void EditInstrument::patchButtonClicked()
+{
+ //MidiTrack* track = (MidiTrack*)selected;
+ //int channel = track->outChannel();
+ //int port = track->outPort();
+ //MidiInstrument* instr = midiPorts[port].instrument();
+
+ //patchpopup->clear();
+
+ QMenu* patchpopup = new QMenu;
+
+ PatchGroupList* pg = workingInstrument.groups();
+
+ if (pg->size() > 1) {
+ for (ciPatchGroup i = pg->begin(); i != pg->end(); ++i) {
+ PatchGroup* pgp = *i;
+ QMenu* pm = patchpopup->addMenu(pgp->name);
+ //pm->setCheckable(false);//Qt4 doc says this is unnecessary
+ pm->setFont(config.fonts[0]);
+ const PatchList& pl = pgp->patches;
+ for (ciPatch ipl = pl.begin(); ipl != pl.end(); ++ipl) {
+ const Patch* mp = *ipl;
+ //if ((mp->typ & mask) &&
+ // ((drum && songType != MT_GM) ||
+ // (mp->drum == drumchan)) )
+
+ // {
+ int id = ((mp->hbank & 0xff) << 16)
+ + ((mp->lbank & 0xff) << 8) + (mp->prog & 0xff);
+ QAction *ac1 = pm->addAction(mp->name);
+ ac1->setData(id);
+ // }
+
+ }
+ }
+ }
+ else if (pg->size() == 1 ){
+ // no groups
+ const PatchList& pl = pg->front()->patches;
+ for (ciPatch ipl = pl.begin(); ipl != pl.end(); ++ipl) {
+ const Patch* mp = *ipl;
+ //if (mp->typ & mask) {
+ int id = ((mp->hbank & 0xff) << 16)
+ + ((mp->lbank & 0xff) << 8) + (mp->prog & 0xff);
+ QAction *ac2 = patchpopup->addAction(mp->name);
+ ac2->setData(id);
+ // }
+ }
+ }
+
+ if(patchpopup->actions().count() == 0)
+ {
+ delete patchpopup;
+ return;
+ }
+
+ QAction* act = patchpopup->exec(patchButton->mapToGlobal(QPoint(10,5)));
+ if(!act)
+ {
+ delete patchpopup;
+ return;
+ }
+
+ int rv = act->data().toInt();
+ delete patchpopup;
+
+ if (rv != -1)
+ {
+ //if(rv != workingInstrument.
+
+ setDefaultPatchControls(rv);
+
+ QTreeWidgetItem* item = viewController->currentItem();
+
+ if(item)
+ {
+ MidiController* c = (MidiController*)item->data(0, Qt::UserRole).value<void*>();
+ c->setInitVal(rv);
+
+ item->setText(COL_DEF, getPatchItemText(rv));
+ }
+ workingInstrument.setDirty(true);
+ }
+
+}
+
+//---------------------------------------------------------
+// addControllerToView
+//---------------------------------------------------------
+
+QTreeWidgetItem* EditInstrument::addControllerToView(MidiController* mctrl)
+{
+ QString hnum;
+ QString lnum;
+ QString min;
+ QString max;
+ QString def;
+ int defval = mctrl->initVal();
+ int n = mctrl->num();
+ //int h = (n >> 7) & 0x7f;
+ int h = (n >> 8) & 0x7f;
+ int l = n & 0x7f;
+ if((n & 0xff) == 0xff)
+ l = -1;
+
+ MidiController::ControllerType t = midiControllerType(n);
+ switch(t)
+ {
+ case MidiController::Controller7:
+ //case MidiController::RPN:
+ //case MidiController::NRPN:
+ hnum = "---";
+ if(l == -1)
+ lnum = "*";
+ else
+ lnum.setNum(l);
+ min.setNum(mctrl->minVal());
+ max.setNum(mctrl->maxVal());
+ if(defval == CTRL_VAL_UNKNOWN)
+ def = "---";
+ else
+ def.setNum(defval);
+ break;
+ case MidiController::RPN:
+ case MidiController::NRPN:
+ case MidiController::RPN14:
+ case MidiController::NRPN14:
+ case MidiController::Controller14:
+ hnum.setNum(h);
+ if(l == -1)
+ lnum = "*";
+ else
+ lnum.setNum(l);
+ min.setNum(mctrl->minVal());
+ max.setNum(mctrl->maxVal());
+ if(defval == CTRL_VAL_UNKNOWN)
+ def = "---";
+ else
+ def.setNum(defval);
+ break;
+ case MidiController::Pitch:
+ hnum = "---";
+ lnum = "---";
+ min.setNum(mctrl->minVal());
+ max.setNum(mctrl->maxVal());
+ if(defval == CTRL_VAL_UNKNOWN)
+ def = "---";
+ else
+ def.setNum(defval);
+ break;
+ case MidiController::Program:
+ hnum = "---";
+ lnum = "---";
+ min = "---";
+ max = "---";
+ def = getPatchItemText(defval);
+ break;
+
+ default:
+ hnum = "---";
+ lnum = "---";
+ //min.setNum(0);
+ //max.setNum(0);
+ min = "---";
+ max = "---";
+ def = "---";
+ break;
+ }
+
+ QTreeWidgetItem* ci = new QTreeWidgetItem(viewController, QStringList() << mctrl->name() << int2ctrlType(t) << hnum << lnum << min << max << def);
+ //ListViewData* ci = new ListViewData(viewController, mctrl->name(), int2ctrlType(t),
+ // hnum, lnum, min, max, def);
+ //ci->setData((void*)mctrl);
+ QVariant v = qVariantFromValue((void*)(mctrl));
+ ci->setData(0, Qt::UserRole, v);
+ //setModified(true);
+
+ return ci;
+}
+
+//---------------------------------------------------------
+// controllerChanged
+//---------------------------------------------------------
+
+void EditInstrument::controllerChanged()
+ {
+ //if (old) {
+// if(oldController)
+// {
+ //QListWidgetItem* item = instrumentList->currentItem();
+ //if (item == 0)
+ // return;
+ //MidiInstrument* instrument = (MidiInstrument*)item->data(Qt::UserRole).value<void*>();
+ //MidiController* oc = (MidiController*)old->data(Qt::UserRole).value<void*>();
+ //updateController(instrument, oc);
+// updateController(&workingInstrument, (MidiController*)oldController->data());
+// }
+
+ // ListBoxData* sel = (ListBoxData*)listController->selectedItem();
+
+ QTreeWidgetItem* sel = viewController->selectedItems().size() ? viewController->selectedItems()[0] : 0;
+// oldController = sel;
+
+ if(!sel || !sel->data(0, Qt::UserRole).value<void*>())
+ {
+ ctrlName->blockSignals(true);
+ ctrlName->setText("");
+ ctrlName->blockSignals(false);
+ //ctrlComment->setText("");
+ return;
+ }
+
+ MidiController* c = (MidiController*)sel->data(0, Qt::UserRole).value<void*>();
+
+ ctrlName->blockSignals(true);
+ ctrlName->setText(c->name());
+ ctrlName->blockSignals(false);
+
+ //ctrlComment->setText(c->comment());
+ int ctrlH = (c->num() >> 8) & 0x7f;
+ int ctrlL = c->num() & 0x7f;
+ if((c->num() & 0xff) == 0xff)
+ ctrlL = -1;
+
+ //int type = int(c->type());
+ MidiController::ControllerType type = midiControllerType(c->num());
+
+ //ctrlType->setCurrentIndex(type);
+ ctrlType->blockSignals(true);
+ ctrlType->setCurrentIndex(type);
+ ctrlType->blockSignals(false);
+
+ //ctrlTypeChanged(type);
+
+ spinBoxHCtrlNo->blockSignals(true);
+ spinBoxLCtrlNo->blockSignals(true);
+ spinBoxMin->blockSignals(true);
+ spinBoxMax->blockSignals(true);
+ spinBoxDefault->blockSignals(true);
+
+ //ctrlTypeChanged(type);
+
+ switch (type) {
+ //case MidiController::RPN:
+ //case MidiController::NRPN:
+ case MidiController::Controller7:
+ spinBoxHCtrlNo->setEnabled(false);
+ spinBoxLCtrlNo->setEnabled(true);
+ spinBoxHCtrlNo->setValue(0);
+ spinBoxLCtrlNo->setValue(ctrlL);
+ spinBoxMin->setEnabled(true);
+ spinBoxMax->setEnabled(true);
+ spinBoxMin->setRange(-128, 127);
+ spinBoxMax->setRange(-128, 127);
+ spinBoxMin->setValue(c->minVal());
+ spinBoxMax->setValue(c->maxVal());
+ enableDefaultControls(true, false);
+ break;
+ case MidiController::RPN:
+ case MidiController::NRPN:
+ spinBoxHCtrlNo->setEnabled(true);
+ spinBoxLCtrlNo->setEnabled(true);
+ spinBoxHCtrlNo->setValue(ctrlH);
+ spinBoxLCtrlNo->setValue(ctrlL);
+ spinBoxMin->setEnabled(true);
+ spinBoxMax->setEnabled(true);
+ spinBoxMin->setRange(-128, 127);
+ spinBoxMax->setRange(-128, 127);
+ spinBoxMin->setValue(c->minVal());
+ spinBoxMax->setValue(c->maxVal());
+ enableDefaultControls(true, false);
+ break;
+ case MidiController::Controller14:
+ case MidiController::RPN14:
+ case MidiController::NRPN14:
+ spinBoxHCtrlNo->setEnabled(true);
+ spinBoxLCtrlNo->setEnabled(true);
+ spinBoxHCtrlNo->setValue(ctrlH);
+ spinBoxLCtrlNo->setValue(ctrlL);
+ spinBoxMin->setEnabled(true);
+ spinBoxMax->setEnabled(true);
+ spinBoxMin->setRange(-16384, 16383);
+ spinBoxMax->setRange(-16384, 16383);
+ spinBoxMin->setValue(c->minVal());
+ spinBoxMax->setValue(c->maxVal());
+ enableDefaultControls(true, false);
+ break;
+ case MidiController::Pitch:
+ spinBoxHCtrlNo->setEnabled(false);
+ spinBoxLCtrlNo->setEnabled(false);
+ spinBoxHCtrlNo->setValue(0);
+ spinBoxLCtrlNo->setValue(0);
+ spinBoxMin->setEnabled(true);
+ spinBoxMax->setEnabled(true);
+ spinBoxMin->setRange(-8192, 8191);
+ spinBoxMax->setRange(-8192, 8191);
+ spinBoxMin->setValue(c->minVal());
+ spinBoxMax->setValue(c->maxVal());
+ enableDefaultControls(true, false);
+ break;
+ case MidiController::Program:
+ spinBoxHCtrlNo->setEnabled(false);
+ spinBoxLCtrlNo->setEnabled(false);
+ spinBoxHCtrlNo->setValue(0);
+ spinBoxLCtrlNo->setValue(0);
+ spinBoxMin->setEnabled(false);
+ spinBoxMax->setEnabled(false);
+ spinBoxMin->setRange(0, 0);
+ spinBoxMax->setRange(0, 0);
+ spinBoxMin->setValue(0);
+ spinBoxMax->setValue(0);
+ enableDefaultControls(false, true);
+ break;
+ default:
+ spinBoxHCtrlNo->setEnabled(false);
+ spinBoxLCtrlNo->setEnabled(false);
+ spinBoxMin->setEnabled(false);
+ spinBoxMax->setEnabled(false);
+ enableDefaultControls(false, false);
+ break;
+ }
+
+ if(type == MidiController::Program)
+ {
+ spinBoxDefault->setRange(0, 0);
+ spinBoxDefault->setValue(0);
+ setDefaultPatchControls(c->initVal());
+ }
+ else
+ {
+ spinBoxDefault->setRange(c->minVal() - 1, c->maxVal());
+ if(c->initVal() == CTRL_VAL_UNKNOWN)
+ //spinBoxDefault->setValue(c->minVal() - 1);
+ spinBoxDefault->setValue(spinBoxDefault->minimum());
+ else
+ spinBoxDefault->setValue(c->initVal());
+ }
+
+ //moveWithPart->setChecked(c->moveWithPart());
+
+ spinBoxHCtrlNo->blockSignals(false);
+ spinBoxLCtrlNo->blockSignals(false);
+ spinBoxMin->blockSignals(false);
+ spinBoxMax->blockSignals(false);
+ spinBoxDefault->blockSignals(false);
+ }
+
+//---------------------------------------------------------
+// ctrlNameReturn
+//---------------------------------------------------------
+
+void EditInstrument::ctrlNameReturn()
+//void EditInstrument::ctrlNameChanged(const QString& s)
+{
+ QTreeWidgetItem* item = viewController->currentItem();
+
+ if (item == 0)
+ return;
+ MidiController* c = (MidiController*)item->data(0, Qt::UserRole).value<void*>();
+
+ QString cName = ctrlName->text();
+
+ if(c->name() == cName)
+ return;
+
+ //MidiControllerList* cl = instrument->controller();
+ MidiControllerList* cl = workingInstrument.controller();
+ for(ciMidiController ic = cl->begin(); ic != cl->end(); ++ic)
+ {
+ MidiController* mc = ic->second;
+ if(mc != c && mc->name() == cName)
+ {
+ ctrlName->blockSignals(true);
+ ctrlName->setText(c->name());
+ ctrlName->blockSignals(false);
+
+ QMessageBox::critical(this,
+ tr("MusE: Bad controller name"),
+ tr("Please choose a unique controller name"),
+ QMessageBox::Ok,
+ Qt::NoButton,
+ Qt::NoButton);
+
+ return;
+ }
+ }
+
+ c->setName(ctrlName->text());
+ item->setText(COL_NAME, ctrlName->text());
+ //c->setName(s);
+ //item->setText(COL_NAME, s);
+ workingInstrument.setDirty(true);
+}
+
+//---------------------------------------------------------
+// ctrlTypeChanged
+//---------------------------------------------------------
+
+void EditInstrument::ctrlTypeChanged(int idx)
+ {
+ QTreeWidgetItem* item = viewController->currentItem();
+
+ if (item == 0)
+ return;
+
+ MidiController::ControllerType t = (MidiController::ControllerType)idx;
+ MidiController* c = (MidiController*)item->data(0, Qt::UserRole).value<void*>();
+ if(t == midiControllerType(c->num()))
+ return;
+
+ //if(item)
+ item->setText(COL_TYPE, ctrlType->currentText());
+
+ int hnum = 0, lnum = 0;
+ //int rng = 0;
+ //int min = 0, max = 0;
+
+ spinBoxMin->blockSignals(true);
+ spinBoxMax->blockSignals(true);
+ spinBoxDefault->blockSignals(true);
+
+ switch (t) {
+ //case MidiController::RPN:
+ //case MidiController::NRPN:
+ case MidiController::Controller7:
+ spinBoxHCtrlNo->setEnabled(false);
+ spinBoxLCtrlNo->setEnabled(true);
+ spinBoxMin->setEnabled(true);
+ spinBoxMax->setEnabled(true);
+ enableDefaultControls(true, false);
+ spinBoxMin->setRange(-128, 127);
+ spinBoxMax->setRange(-128, 127);
+
+ spinBoxMin->setValue(0);
+ spinBoxMax->setValue(127);
+ spinBoxDefault->setRange(spinBoxMin->value() - 1, spinBoxMax->value());
+
+ spinBoxDefault->setValue(spinBoxDefault->minimum());
+ lnum = spinBoxLCtrlNo->value();
+ //rng = 127;
+ //min = -128;
+ //max = 127;
+ //if(item)
+ //{
+ //item->setText(COL_LNUM, QString().setNum(spinBoxLCtrlNo->value()));
+ if(lnum == -1)
+ item->setText(COL_LNUM, QString("*"));
+ else
+ item->setText(COL_LNUM, QString().setNum(lnum));
+ item->setText(COL_HNUM, QString("---"));
+ item->setText(COL_MIN, QString().setNum(spinBoxMin->value()));
+ item->setText(COL_MAX, QString().setNum(spinBoxMax->value()));
+ item->setText(COL_DEF, QString("---"));
+ //}
+ break;
+ case MidiController::RPN:
+ case MidiController::NRPN:
+ spinBoxHCtrlNo->setEnabled(true);
+ spinBoxLCtrlNo->setEnabled(true);
+ spinBoxMin->setEnabled(true);
+ spinBoxMax->setEnabled(true);
+ enableDefaultControls(true, false);
+ spinBoxMin->setRange(-128, 127);
+ spinBoxMax->setRange(-128, 127);
+
+ spinBoxMin->setValue(0);
+ spinBoxMax->setValue(127);
+ spinBoxDefault->setRange(spinBoxMin->value() - 1, spinBoxMax->value());
+ spinBoxDefault->setValue(spinBoxDefault->minimum());
+
+ hnum = spinBoxHCtrlNo->value();
+ lnum = spinBoxLCtrlNo->value();
+ //rng = 127;
+ //min = -128;
+ //max = 127;
+ //if(item)
+ //{
+ //item->setText(COL_LNUM, QString().setNum(spinBoxLCtrlNo->value()));
+ //item->setText(COL_HNUM, QString().setNum(spinBoxHCtrlNo->value()));
+ if(lnum == -1)
+ item->setText(COL_LNUM, QString("*"));
+ else
+ item->setText(COL_LNUM, QString().setNum(lnum));
+ item->setText(COL_HNUM, QString().setNum(hnum));
+ item->setText(COL_MIN, QString().setNum(spinBoxMin->value()));
+ item->setText(COL_MAX, QString().setNum(spinBoxMax->value()));
+ item->setText(COL_DEF, QString("---"));
+ //}
+ break;
+ case MidiController::Controller14:
+ case MidiController::RPN14:
+ case MidiController::NRPN14:
+ spinBoxHCtrlNo->setEnabled(true);
+ spinBoxLCtrlNo->setEnabled(true);
+ spinBoxMin->setEnabled(true);
+ spinBoxMax->setEnabled(true);
+ enableDefaultControls(true, false);
+ spinBoxMin->setRange(-16384, 16383);
+ spinBoxMax->setRange(-16384, 16383);
+
+ spinBoxMin->setValue(0);
+ spinBoxMax->setValue(16383);
+ spinBoxDefault->setRange(spinBoxMin->value() - 1, spinBoxMax->value());
+ spinBoxDefault->setValue(spinBoxDefault->minimum());
+
+ hnum = spinBoxHCtrlNo->value();
+ lnum = spinBoxLCtrlNo->value();
+ //rng = 16383;
+ //min = -16384;
+ //max = 16383;
+ //if(item)
+ //{
+ //item->setText(COL_LNUM, QString().setNum(spinBoxLCtrlNo->value()));
+ //item->setText(COL_HNUM, QString().setNum(spinBoxHCtrlNo->value()));
+ if(lnum == -1)
+ item->setText(COL_LNUM, QString("*"));
+ else
+ item->setText(COL_LNUM, QString().setNum(lnum));
+ item->setText(COL_HNUM, QString().setNum(hnum));
+ item->setText(COL_MIN, QString().setNum(spinBoxMin->value()));
+ item->setText(COL_MAX, QString().setNum(spinBoxMax->value()));
+ item->setText(COL_DEF, QString("---"));
+ //}
+ break;
+ case MidiController::Pitch:
+ spinBoxHCtrlNo->setEnabled(false);
+ spinBoxLCtrlNo->setEnabled(false);
+ spinBoxMin->setEnabled(true);
+ spinBoxMax->setEnabled(true);
+ enableDefaultControls(true, false);
+ spinBoxMin->setRange(-8192, 8191);
+ spinBoxMax->setRange(-8192, 8191);
+
+ spinBoxMin->setValue(-8192);
+ spinBoxMax->setValue(8191);
+ spinBoxDefault->setRange(spinBoxMin->value() - 1, spinBoxMax->value());
+ spinBoxDefault->setValue(spinBoxDefault->minimum());
+
+ //rng = 8191;
+ //min = -8192;
+ //max = 8191;
+ //if(item)
+ //{
+ item->setText(COL_LNUM, QString("---"));
+ item->setText(COL_HNUM, QString("---"));
+ item->setText(COL_MIN, QString().setNum(spinBoxMin->value()));
+ item->setText(COL_MAX, QString().setNum(spinBoxMax->value()));
+ item->setText(COL_DEF, QString("---"));
+ //}
+ break;
+ case MidiController::Program:
+ spinBoxHCtrlNo->setEnabled(false);
+ spinBoxLCtrlNo->setEnabled(false);
+ spinBoxMin->setEnabled(false);
+ spinBoxMax->setEnabled(false);
+ enableDefaultControls(false, true);
+ spinBoxMin->setRange(0, 0);
+ spinBoxMax->setRange(0, 0);
+
+ spinBoxMin->setValue(0);
+ spinBoxMax->setValue(0);
+ spinBoxDefault->setRange(0, 0);
+ spinBoxDefault->setValue(0);
+
+ //if(item)
+ //{
+ item->setText(COL_LNUM, QString("---"));
+ item->setText(COL_HNUM, QString("---"));
+ item->setText(COL_MIN, QString("---"));
+ item->setText(COL_MAX, QString("---"));
+
+ //item->setText(COL_DEF, QString("0-0-0"));
+ item->setText(COL_DEF, QString("---"));
+ //}
+ break;
+ // Shouldn't happen...
+ default:
+ spinBoxHCtrlNo->setEnabled(false);
+ spinBoxLCtrlNo->setEnabled(false);
+ spinBoxMin->setEnabled(false);
+ spinBoxMax->setEnabled(false);
+ enableDefaultControls(false, false);
+
+ spinBoxMin->blockSignals(false);
+ spinBoxMax->blockSignals(false);
+ return;
+
+ break;
+ }
+
+ spinBoxMin->blockSignals(false);
+ spinBoxMax->blockSignals(false);
+ spinBoxDefault->blockSignals(false);
+
+ c->setNum(MidiController::genNum(t, hnum, lnum));
+
+ setDefaultPatchControls(0xffffff);
+ if(t == MidiController::Program)
+ {
+ c->setMinVal(0);
+ c->setMaxVal(0xffffff);
+ c->setInitVal(0xffffff);
+ }
+ else
+ {
+ c->setMinVal(spinBoxMin->value());
+ c->setMaxVal(spinBoxMax->value());
+ if(spinBoxDefault->value() == spinBoxDefault->minimum())
+ c->setInitVal(CTRL_VAL_UNKNOWN);
+ else
+ c->setInitVal(spinBoxDefault->value());
+ }
+
+
+ /*
+
+ if(rng != 0)
+ {
+ int mn = c->minVal();
+ int mx = c->maxVal();
+ //if(val > item->text(COL_MAX).toInt())
+ if(mx > max)
+ {
+ c->setMaxVal(max);
+ spinBoxMax->blockSignals(true);
+ spinBoxMax->setValue(max);
+ spinBoxMax->blockSignals(false);
+ if(item)
+ item->setText(COL_MAX, QString().setNum(max));
+ }
+ //else
+ if(mn < min)
+ {
+ c->setMinVal(min);
+ spinBoxMin->blockSignals(true);
+ spinBoxMin->setValue(min);
+ spinBoxMin->blockSignals(false);
+ if(item)
+ item->setText(COL_MIN, QString().setNum(min));
+ }
+ //else
+ if(mx - mn > rng)
+ {
+ //mx = val + rng;
+ c->setMinVal(0);
+ c->setMaxVal(rng);
+ spinBoxMin->blockSignals(true);
+ spinBoxMax->blockSignals(true);
+ spinBoxMin->setValue(0);
+ spinBoxMax->setValue(rng);
+ spinBoxMin->blockSignals(false);
+ spinBoxMax->blockSignals(false);
+ if(item)
+ {
+ item->setText(COL_MIN, QString().setNum(0));
+ item->setText(COL_MAX, QString().setNum(rng));
+ }
+ }
+
+ spinBoxDefault->blockSignals(true);
+
+ spinBoxDefault->setRange(spinBoxMin->value() - 1, spinBoxMax->value());
+ int inval = c->initVal();
+ if(inval == CTRL_VAL_UNKNOWN)
+ spinBoxDefault->setValue(spinBoxDefault->minimum());
+ else
+ {
+ if(inval < c->minVal())
+ {
+ c->setInitVal(c->minVal());
+ spinBoxDefault->setValue(c->minVal());
+ }
+ else
+ if(inval > c->maxVal())
+ {
+ c->setInitVal(c->maxVal());
+ spinBoxDefault->setValue(c->maxVal());
+ }
+ }
+
+ //spinBoxDefault->setRange(c->minVal() - 1, c->maxVal());
+ spinBoxDefault->blockSignals(false);
+
+ }
+
+ */
+
+ workingInstrument.setDirty(true);
+ }
+
+//---------------------------------------------------------
+// ctrlHNumChanged
+//---------------------------------------------------------
+
+void EditInstrument::ctrlHNumChanged(int val)
+ {
+ QTreeWidgetItem* item = viewController->currentItem();
+
+ if (item == 0)
+ return;
+ QString s;
+ s.setNum(val);
+ MidiController* c = (MidiController*)item->data(0, Qt::UserRole).value<void*>();
+ //int n = c->num() & 0xff;
+ int n = c->num() & 0x7fff00ff;
+ c->setNum(n | ((val & 0xff) << 8));
+ item->setText(COL_HNUM, s);
+ workingInstrument.setDirty(true);
+ }
+
+//---------------------------------------------------------
+// ctrlLNumChanged
+//---------------------------------------------------------
+
+void EditInstrument::ctrlLNumChanged(int val)
+ {
+ QTreeWidgetItem* item = viewController->currentItem();
+
+ if (item == 0)
+ return;
+ MidiController* c = (MidiController*)item->data(0, Qt::UserRole).value<void*>();
+ //int n = c->num() & 0xff00;
+ int n = c->num() & ~0xff;
+ c->setNum(n | (val & 0xff));
+ if(val == -1)
+ item->setText(COL_LNUM, QString("*"));
+ else
+ {
+ QString s;
+ s.setNum(val);
+ item->setText(COL_LNUM, s);
+ }
+ workingInstrument.setDirty(true);
+ }
+
+//---------------------------------------------------------
+// ctrlMinChanged
+//---------------------------------------------------------
+
+void EditInstrument::ctrlMinChanged(int val)
+{
+ QTreeWidgetItem* item = viewController->currentItem();
+
+ if (item == 0)
+ return;
+
+ QString s;
+ s.setNum(val);
+ item->setText(COL_MIN, s);
+
+ MidiController* c = (MidiController*)item->data(0, Qt::UserRole).value<void*>();
+ c->setMinVal(val);
+
+ int rng = 0;
+ //switch((MidiController::ControllerType)ctrlType->currentItem())
+ switch(midiControllerType(c->num()))
+ {
+ case MidiController::Controller7:
+ case MidiController::RPN:
+ case MidiController::NRPN:
+ rng = 127;
+ break;
+ case MidiController::Controller14:
+ case MidiController::RPN14:
+ case MidiController::NRPN14:
+ case MidiController::Pitch:
+ rng = 16383;
+ break;
+ default:
+ break;
+ }
+
+ int mx = c->maxVal();
+
+ //if(val > item->text(COL_MAX).toInt())
+ if(val > mx)
+ {
+ c->setMaxVal(val);
+ spinBoxMax->blockSignals(true);
+ spinBoxMax->setValue(val);
+ spinBoxMax->blockSignals(false);
+ item->setText(COL_MAX, s);
+ }
+ else
+ if(mx - val > rng)
+ {
+ mx = val + rng;
+ c->setMaxVal(mx);
+ spinBoxMax->blockSignals(true);
+ spinBoxMax->setValue(mx);
+ spinBoxMax->blockSignals(false);
+ item->setText(COL_MAX, QString().setNum(mx));
+ }
+
+ spinBoxDefault->blockSignals(true);
+
+ spinBoxDefault->setRange(spinBoxMin->value() - 1, spinBoxMax->value());
+
+ int inval = c->initVal();
+ if(inval == CTRL_VAL_UNKNOWN)
+ spinBoxDefault->setValue(spinBoxDefault->minimum());
+ else
+ {
+ if(inval < c->minVal())
+ {
+ c->setInitVal(c->minVal());
+ spinBoxDefault->setValue(c->minVal());
+ }
+ else
+ if(inval > c->maxVal())
+ {
+ c->setInitVal(c->maxVal());
+ spinBoxDefault->setValue(c->maxVal());
+ }
+ }
+
+ spinBoxDefault->blockSignals(false);
+
+ workingInstrument.setDirty(true);
+}
+
+//---------------------------------------------------------
+// ctrlMaxChanged
+//---------------------------------------------------------
+
+void EditInstrument::ctrlMaxChanged(int val)
+{
+ QTreeWidgetItem* item = viewController->currentItem();
+
+ if (item == 0)
+ return;
+
+ QString s;
+ s.setNum(val);
+ item->setText(COL_MAX, s);
+
+ MidiController* c = (MidiController*)item->data(0, Qt::UserRole).value<void*>();
+ c->setMaxVal(val);
+
+ int rng = 0;
+ //switch((MidiController::ControllerType)ctrlType->currentItem())
+ switch(midiControllerType(c->num()))
+ {
+ case MidiController::Controller7:
+ case MidiController::RPN:
+ case MidiController::NRPN:
+ rng = 127;
+ break;
+ case MidiController::Controller14:
+ case MidiController::RPN14:
+ case MidiController::NRPN14:
+ case MidiController::Pitch:
+ rng = 16383;
+ break;
+ default:
+ break;
+ }
+
+ int mn = c->minVal();
+
+ //if(val < item->text(COL_MIN).toInt())
+ if(val < mn)
+ {
+ c->setMinVal(val);
+ spinBoxMin->blockSignals(true);
+ spinBoxMin->setValue(val);
+ spinBoxMin->blockSignals(false);
+ item->setText(COL_MIN, s);
+ }
+ else
+ if(val - mn > rng)
+ {
+ mn = val - rng;
+ c->setMinVal(mn);
+ spinBoxMin->blockSignals(true);
+ spinBoxMin->setValue(mn);
+ spinBoxMin->blockSignals(false);
+ item->setText(COL_MIN, QString().setNum(mn));
+ }
+
+ spinBoxDefault->blockSignals(true);
+
+ spinBoxDefault->setRange(spinBoxMin->value() - 1, spinBoxMax->value());
+
+ int inval = c->initVal();
+ if(inval == CTRL_VAL_UNKNOWN)
+ spinBoxDefault->setValue(spinBoxDefault->minimum());
+ else
+ {
+ if(inval < c->minVal())
+ {
+ c->setInitVal(c->minVal());
+ spinBoxDefault->setValue(c->minVal());
+ }
+ else
+ if(inval > c->maxVal())
+ {
+ c->setInitVal(c->maxVal());
+ spinBoxDefault->setValue(c->maxVal());
+ }
+ }
+
+ spinBoxDefault->blockSignals(false);
+
+ workingInstrument.setDirty(true);
+}
+
+//---------------------------------------------------------
+// ctrlDefaultChanged
+//---------------------------------------------------------
+
+void EditInstrument::ctrlDefaultChanged(int val)
+{
+ QTreeWidgetItem* item = viewController->currentItem();
+
+ if (item == 0)
+ return;
+
+ MidiController* c = (MidiController*)item->data(0, Qt::UserRole).value<void*>();
+
+ if(val == c->minVal() - 1)
+ {
+ c->setInitVal(CTRL_VAL_UNKNOWN);
+ item->setText(COL_DEF, QString("---"));
+ }
+ else
+ {
+ c->setInitVal(val);
+ item->setText(COL_DEF, QString().setNum(val));
+ }
+ workingInstrument.setDirty(true);
+}
+
+//---------------------------------------------------------
+// ctrlNullParamHChanged
+//---------------------------------------------------------
+
+void EditInstrument::ctrlNullParamHChanged(int nvh)
+{
+ int nvl = nullParamSpinBoxL->value();
+ if(nvh == -1)
+ {
+ nullParamSpinBoxL->blockSignals(true);
+ nullParamSpinBoxL->setValue(-1);
+ nullParamSpinBoxL->blockSignals(false);
+ nvl = -1;
+ }
+ else
+ {
+ if(nvl == -1)
+ {
+ nullParamSpinBoxL->blockSignals(true);
+ nullParamSpinBoxL->setValue(0);
+ nullParamSpinBoxL->blockSignals(false);
+ nvl = 0;
+ }
+ }
+ if(nvh == -1 && nvl == -1)
+ workingInstrument.setNullSendValue(-1);
+ else
+ workingInstrument.setNullSendValue((nvh << 8) | nvl);
+ workingInstrument.setDirty(true);
+}
+
+//---------------------------------------------------------
+// ctrlNullParamLChanged
+//---------------------------------------------------------
+
+void EditInstrument::ctrlNullParamLChanged(int nvl)
+{
+ int nvh = nullParamSpinBoxH->value();
+ if(nvl == -1)
+ {
+ nullParamSpinBoxH->blockSignals(true);
+ nullParamSpinBoxH->setValue(-1);
+ nullParamSpinBoxH->blockSignals(false);
+ nvh = -1;
+ }
+ else
+ {
+ if(nvh == -1)
+ {
+ nullParamSpinBoxH->blockSignals(true);
+ nullParamSpinBoxH->setValue(0);
+ nullParamSpinBoxH->blockSignals(false);
+ nvh = 0;
+ }
+ }
+ if(nvh == -1 && nvl == -1)
+ workingInstrument.setNullSendValue(-1);
+ else
+ workingInstrument.setNullSendValue((nvh << 8) | nvl);
+ workingInstrument.setDirty(true);
+}
+
+//---------------------------------------------------------
+// deletePatchClicked
+//---------------------------------------------------------
+
+void EditInstrument::deletePatchClicked()
+ {
+ //QListWidgetItem* item = instrumentList->currentItem();
+// ListBoxData* item = (ListBoxData*)instrumentList->selectedItem();
+// if (item == 0)
+// return;
+ //MidiInstrument* instrument = (MidiInstrument*)item->data(Qt::UserRole).value<void*>();
+// MidiInstrument* instrument = (MidiInstrument*)item->data();
+ //QTreeWidgetItem* pi = patchView->currentItem();
+ QTreeWidgetItem* pi = patchView->currentItem();
+
+ if (pi == 0)
+ return;
+
+ //void* p = pi->data(0, Qt::UserRole).value<void*>();
+// Patch* patch = (Patch*)pi->data();
+ //if (p == 0)
+ // If patch is zero it's a patch group.
+// if(patch == 0)
+
+ // If the item has a parent item, it's a patch item...
+ if(pi->parent())
+ {
+ PatchGroup* group = (PatchGroup*)(pi->parent())->data(0, Qt::UserRole).value<void*>();
+
+ // If there is an allocated patch in the data, delete it.
+ //Patch* patch = (Patch*)pi->auxData();
+ Patch* patch = (Patch*)pi->data(0, Qt::UserRole).value<void*>();
+ if(patch)
+ {
+ if(group)
+ {
+ //for(iPatch ip = group->patches.begin(); ip != group->patches.end(); ++ip)
+ // if(&*ip == patch)
+ // if(*ip == patch)
+ // {
+ //
+ // printf("deletePatchClicked: erasing patch\n");
+ //
+ // group->patches.erase(ip);
+ // break;
+ // }
+ //group->patches.remove( (const Patch&)(*patch) );
+ group->patches.remove(patch);
+ }
+ delete patch;
+ }
+ }
+ else
+ // The item has no parent item, it's a patch group item...
+ {
+ // Is there an allocated patch group in the data?
+ //PatchGroup* group = (PatchGroup*)pi->auxData();
+ PatchGroup* group = (PatchGroup*)pi->data(0, Qt::UserRole).value<void*>();
+ if(group)
+ {
+
+ PatchGroupList* pg = workingInstrument.groups();
+ //for(ciPatchGroup ipg = pg->begin(); ipg != pg->end(); ++ipg)
+ for(iPatchGroup ipg = pg->begin(); ipg != pg->end(); ++ipg)
+ {
+
+ //printf("deletePatchClicked: working patch group name:%s ad:%X group name:%s ad:%X\n", (*ipg)->name.toLatin1().constData(), (unsigned int)(*ipg), group->name.toLatin1().constData(), (unsigned int) group);
+
+ //if(&*ipg == group)
+ if(*ipg == group)
+ {
+ pg->erase(ipg);
+ break;
+ }
+ }
+
+ // Iterate all child list view (patch) items. Find and delete any allocated patches in the items' data.
+// for(ListViewData* i = (ListViewData*)pi->firstChild(); i; i = (ListViewData*)i->nextSibling())
+// {
+ //Patch* patch = (Patch*)i->auxData();
+// Patch* patch = (Patch*)i->data();
+// if(patch)
+// {
+ //delete patch;
+ //group->patches.remove(*patch);
+ const PatchList& pl = group->patches;
+ for(ciPatch ip = pl.begin(); ip != pl.end(); ++ip)
+ {
+// if(&*ip == patch)
+// {
+// group->patches.erase(ip);
+// break;
+// }
+
+ // Delete the patch.
+ if(*ip)
+ delete *ip;
+ }
+
+ //group->patches.clear();
+
+// }
+// }
+
+ // Now delete the group.
+ delete group;
+
+ }
+ }
+
+ //oldPatchItem = (ListViewData*)patchView->selectedItem();
+ //oldPatchItem = 0;
+
+ // Now delete the patch or group item (and any child patch items) from the list view tree.
+ // !!! This will trigger a patchChanged call.
+ patchView->blockSignals(true);
+ delete pi;
+ if(patchView->currentItem())
+ patchView->currentItem()->setSelected(true);
+ patchView->blockSignals(false);
+
+ oldPatchItem = 0;
+ patchChanged();
+
+ //Patch* patch = (Patch*)p;
+
+ //std::vector<PatchGroup>* pg = instrument->groups();
+ //for (std::vector<PatchGroup>::iterator g = pg->begin(); g != pg->end(); ++g) {
+ // for (iPatch p = g->patches.begin(); p != g->patches.end(); ++p) {
+ // if (patch == *p) {
+ // g->patches.erase(p);
+ // delete pi;
+ // instrument->setDirty(true);
+ // return;
+ // }
+ // }
+ // }
+ //printf("fatal: patch not found\n");
+ //delete patch;
+ //delete pi;
+
+
+ workingInstrument.setDirty(true);
+ }
+
+//---------------------------------------------------------
+// newPatchClicked
+//---------------------------------------------------------
+
+void EditInstrument::newPatchClicked()
+ {
+ //QListWidgetItem* item = instrumentList->currentItem();
+// ListBoxData* item = (ListBoxData*)instrumentList->selectedItem();
+// if (item == 0)
+// return;
+
+ if(oldPatchItem)
+ {
+ if(oldPatchItem->parent())
+ updatePatch(&workingInstrument, (Patch*)oldPatchItem->data(0, Qt::UserRole).value<void*>());
+ else
+ updatePatchGroup(&workingInstrument, (PatchGroup*)oldPatchItem->data(0, Qt::UserRole).value<void*>());
+ }
+
+ //MidiInstrument* instrument = (MidiInstrument*)item->data(Qt::UserRole).value<void*>();
+// MidiInstrument* instrument = (MidiInstrument*)item->data();
+ //std::vector<PatchGroup>* pg = instrument->groups();
+// PatchGroupList* pg = instrument->groups();
+ PatchGroupList* pg = workingInstrument.groups();
+ QString patchName;
+ for (int i = 1;; ++i) {
+ patchName = QString("Patch-%1").arg(i);
+ bool found = false;
+
+ //for (std::vector<PatchGroup>::iterator g = pg->begin(); g != pg->end(); ++g) {
+ for (iPatchGroup g = pg->begin(); g != pg->end(); ++g) {
+ PatchGroup* pgp = *g;
+ //for (iPatch p = g->patches.begin(); p != g->patches.end(); ++p) {
+ for (iPatch p = pgp->patches.begin(); p != pgp->patches.end(); ++p) {
+ //if (p->name == patchName) {
+ if ((*p)->name == patchName) {
+ found = true;
+ break;
+ }
+ }
+ if (found)
+ break;
+ }
+ if (!found)
+ break;
+ }
+
+ //
+ // search current patch group
+ //
+ //PatchGroup* pGroup = 0;
+ //QTreeWidgetItem* pi = patchView->currentItem();
+ QTreeWidgetItem* pi = patchView->currentItem();
+
+ if (pi == 0)
+ return;
+
+ // If there is data then pi is a patch item, and there must be a parent patch group item (with null data).
+ //if (pi->data(0, Qt::UserRole).value<void*>())
+ //if (pi->data())
+
+ Patch* selpatch = 0;
+
+ // If there is a parent item then pi is a patch item, and there must be a parent patch group item.
+ if(pi->parent())
+ {
+ // Remember the current selected patch.
+ selpatch = (Patch*)pi->data(0, Qt::UserRole).value<void*>();
+
+ pi = pi->parent();
+ }
+
+ PatchGroup* group = (PatchGroup*)pi->data(0, Qt::UserRole).value<void*>();
+ if(!group)
+ return;
+
+ //for (std::vector<PatchGroup>::iterator g = pg->begin(); g != pg->end(); ++g) {
+// for (ciPatchGroup g = pg->begin(); g != pg->end(); ++g) {
+// if (g->name == pi->text(0)) {
+// pGroup = &*g;
+// break;
+// }
+// }
+// if (pGroup == 0) {
+// printf("group not found\n");
+// return;
+// }
+
+ // Create a new Patch, then store its pointer in a new patch item,
+ // to be added later to the patch group only upon save...
+ //Patch patch;
+ //patch.name = patchName;
+ Patch* patch = new Patch;
+ int hb = -1;
+ int lb = -1;
+ int prg = 0;
+ patch->hbank = hb;
+ patch->lbank = lb;
+ patch->prog = prg;
+ patch->typ = -1;
+ patch->drum = false;
+
+ if(selpatch)
+ {
+ hb = selpatch->hbank;
+ lb = selpatch->lbank;
+ prg = selpatch->prog;
+ patch->typ = selpatch->typ;
+ patch->drum = selpatch->drum;
+ }
+
+ bool found = false;
+
+ // The 129 is to accommodate -1 values. Yes, it may cause one extra redundant loop but hey,
+ // if it hasn't found an available patch number by then, another loop won't matter.
+ for(int k = 0; k < 129; ++k)
+ {
+ for(int j = 0; j < 129; ++j)
+ {
+ for(int i = 0; i < 128; ++i)
+ {
+ found = false;
+
+ for(iPatchGroup g = pg->begin(); g != pg->end(); ++g)
+ {
+ PatchGroup* pgp = *g;
+ for(iPatch ip = pgp->patches.begin(); ip != pgp->patches.end(); ++ip)
+ {
+ Patch* p = *ip;
+ if((p->prog == ((prg + i) & 0x7f)) &&
+ ((p->lbank == -1 && lb == -1) || (p->lbank == ((lb + j) & 0x7f))) &&
+ ((p->hbank == -1 && hb == -1) || (p->hbank == ((hb + k) & 0x7f))))
+ {
+ found = true;
+ break;
+ }
+ }
+ if(found)
+ break;
+ }
+
+ if(!found)
+ {
+ patch->prog = (prg + i) & 0x7f;
+ if(lb == -1)
+ patch->lbank = -1;
+ else
+ patch->lbank = (lb + j) & 0x7f;
+
+ if(hb == -1)
+ patch->hbank = -1;
+ else
+ patch->hbank = (hb + k) & 0x7f;
+
+ //patch->typ = selpatch->typ;
+ //patch->drum = selpatch->drum;
+ break;
+ }
+
+ }
+ if(!found)
+ break;
+ }
+ if(!found)
+ break;
+ }
+
+ patch->name = patchName;
+
+ group->patches.push_back(patch);
+ //Patch* pp = &(group->patches.back());
+
+ //QTreeWidgetItem* sitem = new QTreeWidgetItem;
+ QTreeWidgetItem* sitem = new QTreeWidgetItem(pi);
+ //sitem->setText(0, patch->name);
+ sitem->setText(0, patchName);
+
+ patchNameEdit->setText(patchName);
+
+ //QVariant v = QVariant::fromValue((void*)(patch));
+ //sitem->setData(0, Qt::UserRole, v);
+
+ // Set the list view item's data.
+ //sitem->setData((void*)patch);
+ QVariant v = qVariantFromValue((void*)(patch));
+ sitem->setData(0, Qt::UserRole, v);
+ //sitem->setAuxData((void*)patch);
+ //sitem->setData((void*)pp);
+
+ //pi->addChild(sitem);
+
+ //printf("newPatchClicked: before patchView->setCurrentItem\n");
+
+ //patchView->setCurrentItem(sitem);
+
+ //printf("newPatchClicked: after patchView->setCurrentItem\n");
+
+ //oldPatchItem = 0;
+
+ // May cause patchChanged call.
+ patchView->blockSignals(true);
+ sitem->setSelected(true);
+ patchView->scrollToItem((QTreeWidgetItem*)sitem, QAbstractItemView::EnsureVisible);
+ patchView->blockSignals(false);
+
+ //oldPatchItem = (ListViewData*)patchView->selectedItem();
+ //oldPatchItem = sitem;
+ //oldPatchItem = 0;
+
+ spinBoxHBank->setEnabled(true);
+ spinBoxLBank->setEnabled(true);
+ spinBoxProgram->setEnabled(true);
+ checkBoxDrum->setEnabled(true);
+ checkBoxGM->setEnabled(true);
+ checkBoxGS->setEnabled(true);
+ checkBoxXG->setEnabled(true);
+
+ oldPatchItem = 0;
+ patchChanged();
+
+ //instrument->setDirty(true);
+ workingInstrument.setDirty(true);
+ }
+
+//---------------------------------------------------------
+// newGroupClicked
+//---------------------------------------------------------
+
+void EditInstrument::newGroupClicked()
+ {
+ //QListWidgetItem* item = instrumentList->currentItem();
+// ListBoxData* item = (ListBoxData*)instrumentList->selectedItem();
+// if (item == 0)
+// return;
+
+ if(oldPatchItem)
+ {
+ if(oldPatchItem->parent())
+ updatePatch(&workingInstrument, (Patch*)oldPatchItem->data(0, Qt::UserRole).value<void*>());
+ else
+ updatePatchGroup(&workingInstrument, (PatchGroup*)oldPatchItem->data(0, Qt::UserRole).value<void*>());
+ }
+
+ //MidiInstrument* instrument = (MidiInstrument*)item->data(Qt::UserRole).value<void*>();
+// MidiInstrument* instrument = (MidiInstrument*)item->data();
+ //std::vector<PatchGroup>* pg = instrument->groups();
+// PatchGroupList* pg = instrument->groups();
+ PatchGroupList* pg = workingInstrument.groups();
+ QString groupName;
+ for (int i = 1;; ++i) {
+ groupName = QString("Group-%1").arg(i);
+ bool found = false;
+
+ //for (std::vector<PatchGroup>::iterator g = pg->begin(); g != pg->end(); ++g) {
+ for (ciPatchGroup g = pg->begin(); g != pg->end(); ++g) {
+ //if (g->name == groupName) {
+ if ((*g)->name == groupName) {
+ found = true;
+ break;
+ }
+ }
+ if (!found)
+ break;
+ }
+
+ // Create a new PatchGroup, then store its pointer in a new patch group item,
+ // to be added later to the instrument only upon save...
+ PatchGroup* group = new PatchGroup;
+ group->name = groupName;
+ //PatchGroup group;
+ //group.name = groupName;
+
+ pg->push_back(group);
+ //PatchGroup* pgp = &(pg->back());
+
+ QTreeWidgetItem* sitem = new QTreeWidgetItem(patchView);
+ sitem->setText(0, groupName);
+
+ patchNameEdit->setText(groupName);
+
+ //QVariant v = QVariant::fromValue((void*)0);
+ //sitem->setData(0, Qt::UserRole, v);
+ //sitem->setData((void*)0);
+
+ // Set the list view item's data.
+ QVariant v = qVariantFromValue((void*)(group));
+ sitem->setData(0, Qt::UserRole, v);
+ //sitem->setAuxData((void*)pgp);
+
+ //patchView->addTopLevelItem(sitem);
+ //patchView->setCurrentItem(sitem);
+
+ //oldPatchItem = 0;
+
+ // May cause patchChanged call.
+ patchView->blockSignals(true);
+ sitem->setSelected(true);
+ patchView->blockSignals(false);
+
+ //oldPatchItem = (ListViewData*)patchView->selectedItem();
+ oldPatchItem = sitem;
+ //oldPatchItem = 0;
+ //patchChanged();
+
+ spinBoxHBank->setEnabled(false);
+ spinBoxLBank->setEnabled(false);
+ spinBoxProgram->setEnabled(false);
+ checkBoxDrum->setEnabled(false);
+ checkBoxGM->setEnabled(false);
+ checkBoxGS->setEnabled(false);
+ checkBoxXG->setEnabled(false);
+
+ //instrument->setDirty(true);
+ workingInstrument.setDirty(true);
+ }
+
+//---------------------------------------------------------
+// deleteControllerClicked
+//---------------------------------------------------------
+
+void EditInstrument::deleteControllerClicked()
+ {
+ //QListWidgetItem* item = instrumentList->currentItem();
+ //ListBoxData* item = (ListBoxData*)instrumentList->selectedItem();
+ //QListWidgetItem* item2 = listController->currentItem();
+// ListBoxData* item = (ListBoxData*)listController->selectedItem();
+ QTreeWidgetItem* item = viewController->currentItem();
+
+ //if (item == 0 || item2 == 0)
+ if(!item)
+ return;
+ //MidiInstrument* instrument = (MidiInstrument*)item->data(Qt::UserRole).value<void*>();
+// MidiInstrument* instrument = (MidiInstrument*)item->data();
+ //MidiController* ctrl = (MidiController*)item2->data(Qt::UserRole).value<void*>();
+ //MidiController* ctrl = (MidiController*)item2->data();
+ //MidiControllerList* cl = instrument->controller();
+ //cl->removeAll(ctrl);
+
+ MidiController* ctrl = (MidiController*)item->data(0, Qt::UserRole).value<void*>();
+ if(!ctrl)
+ return;
+
+ workingInstrument.controller()->erase(ctrl->num());
+ // Now delete the controller.
+ delete ctrl;
+
+ // Now remove the controller item from the list.
+ // This may cause a controllerChanged call.
+// listController->blockSignals(true);
+ viewController->blockSignals(true);
+ delete item;
+ if(viewController->currentItem())
+ viewController->currentItem()->setSelected(true);
+// listController->blockSignals(false);
+ viewController->blockSignals(false);
+
+ //oldController = (ListBoxData*)listController->selectedItem();
+// oldController = 0;
+
+ controllerChanged();
+
+ //instrument->setDirty(true);
+ workingInstrument.setDirty(true);
+ }
+
+//---------------------------------------------------------
+// newControllerClicked
+//---------------------------------------------------------
+
+void EditInstrument::newControllerClicked()
+ {
+ //QListWidgetItem* item = instrumentList->currentItem();
+ //if (item == 0)
+ // return;
+ //MidiInstrument* instrument = (MidiInstrument*)item->data(Qt::UserRole).value<void*>();
+
+// if(oldController)
+// updateController(&workingInstrument, (MidiController*)oldController->data());
+
+ QString cName;
+ //MidiControllerList* cl = instrument->controller();
+ MidiControllerList* cl = workingInstrument.controller();
+ for (int i = 1;; ++i) {
+ //ctrlName = QString("Controller-%d").arg(i);
+ cName = QString("Controller-%1").arg(i);
+ bool found = false;
+ for (iMidiController ic = cl->begin(); ic != cl->end(); ++ic) {
+ MidiController* c = ic->second;
+ if (c->name() == cName) {
+ found = true;
+ break;
+ }
+ }
+ if (!found)
+ break;
+ }
+
+ MidiController* ctrl = new MidiController();
+ ctrl->setNum(CTRL_MODULATION);
+ ctrl->setMinVal(0);
+ ctrl->setMaxVal(127);
+ ctrl->setInitVal(CTRL_VAL_UNKNOWN);
+
+ QTreeWidgetItem* ci = viewController->currentItem();
+
+ // To allow for quick multiple successive controller creation.
+ // If there's a current controller item selected, copy initial values from it.
+ bool found = false;
+ if(ci)
+ {
+ MidiController* selctl = (MidiController*)ci->data(0, Qt::UserRole).value<void*>();
+ // Assign.
+ // *ctrl = *selctl;
+
+ // Auto increment controller number.
+ //int l = ctrl->num() & 0x7f;
+ //int h = ctrl->num() & 0xffffff00;
+ int l = selctl->num() & 0x7f;
+ int h = selctl->num() & 0xffffff00;
+
+ // Ignore internal controllers and wild cards.
+ //if(((h & 0xff0000) != 0x40000) && ((ctrl->num() & 0xff) != 0xff))
+ if(((h & 0xff0000) != 0x40000) && ((selctl->num() & 0xff) != 0xff))
+ {
+ // Assign.
+ *ctrl = *selctl;
+
+ for (int i = 1; i < 128; ++i)
+ {
+ //ctrlName = QString("Controller-%d").arg(i);
+ //cName = QString("Controller-%1").arg(i);
+ int j = ((i + l) & 0x7f) | h;
+ found = false;
+ for (iMidiController ic = cl->begin(); ic != cl->end(); ++ic)
+ {
+ MidiController* c = ic->second;
+ if(c->num() == j)
+ {
+ found = true;
+ break;
+ }
+ }
+ if(!found)
+ {
+ ctrl->setNum(j);
+ break;
+ }
+ }
+ }
+ }
+
+ ctrl->setName(cName);
+
+ //item = new QListWidgetItem(ctrlName);
+// ListBoxData* item = new ListBoxData(ctrlName);
+
+ //QVariant v = qVariantFromValue((void*)(ctrl));
+ //item->setData(Qt::UserRole, v);
+// item->setData((void*)ctrl);
+ //listController->addItem(item);
+// listController->insertItem(item);
+ //listController->setCurrentItem(item);
+
+ workingInstrument.controller()->add(ctrl);
+ QTreeWidgetItem* item = addControllerToView(ctrl);
+
+// listController->blockSignals(true);
+// listController->setSelected(item, true);
+// listController->blockSignals(false);
+ viewController->blockSignals(true);
+ item->setSelected(true);
+ viewController->blockSignals(false);
+
+ //oldController = (ListBoxData*)listController->selectedItem();
+// oldController = item;
+ //oldController = 0;
+ // MidiController is a class, with itialized values. We have to call this to show the values.
+ // To make multiple entries easier, don't bother calling this.
+ controllerChanged();
+
+ //instrument->setDirty(true);
+ workingInstrument.setDirty(true);
+ }
+
+//---------------------------------------------------------
+// addControllerClicked
+//---------------------------------------------------------
+
+void EditInstrument::addControllerClicked()
+{
+ //int lnum = listController->currentItem();
+ //if(lnum == -1)
+ // return;
+
+ //QString name = midiCtrlName(lnum);
+
+ QListWidgetItem* idx = listController->currentItem();
+ if(idx == 0)
+ return;
+
+ int lnum = -1;
+ QString name = listController->currentItem()->text();
+ for(int i = 0; i < 128; i++)
+ {
+ if(midiCtrlName(i) == name)
+ {
+ lnum = i;
+ break;
+ }
+ }
+ if(lnum == -1)
+ {
+ printf("Add controller: Controller not found: %s\n", name.toLatin1().constData());
+ return;
+ }
+
+ int num = MidiController::genNum(MidiController::Controller7, 0, lnum);
+
+ MidiControllerList* cl = workingInstrument.controller();
+ for(iMidiController ic = cl->begin(); ic != cl->end(); ++ic)
+ {
+ MidiController* c = ic->second;
+ if(c->name() == name)
+ {
+ QMessageBox::critical(this,
+ tr("MusE: Cannot add common controller"),
+ tr("A controller named ") + name + tr(" already exists."),
+ QMessageBox::Ok,
+ Qt::NoButton,
+ Qt::NoButton);
+
+ return;
+ }
+
+ if(c->num() == num)
+ {
+ QMessageBox::critical(this,
+ tr("MusE: Cannot add common controller"),
+ tr("A controller number ") + QString().setNum(num) + tr(" already exists."),
+ QMessageBox::Ok,
+ Qt::NoButton,
+ Qt::NoButton);
+
+ return;
+ }
+ }
+
+ MidiController* ctrl = new MidiController();
+ ctrl->setNum(num);
+ ctrl->setMinVal(0);
+ ctrl->setMaxVal(127);
+ ctrl->setInitVal(CTRL_VAL_UNKNOWN);
+ ctrl->setName(name);
+
+ workingInstrument.controller()->add(ctrl);
+
+ QTreeWidgetItem* item = addControllerToView(ctrl);
+
+ viewController->blockSignals(true);
+ item->setSelected(true);
+ viewController->blockSignals(false);
+
+ controllerChanged();
+
+ workingInstrument.setDirty(true);
+}
+
+/*
+//---------------------------------------------------------
+// deleteSysexClicked
+//---------------------------------------------------------
+
+void EditInstrument::deleteSysexClicked()
+ {
+ //QListWidgetItem* item = instrumentList->currentItem();
+ //QListWidgetItem* item2 = sysexList->currentItem();
+ //if (item == 0 || item2 == 0)
+ // return;
+
+ //MidiInstrument* instrument = (MidiInstrument*)item->data(Qt::UserRole).value<void*>();
+ //SysEx* sysex = (SysEx*)item2->data(Qt::UserRole).value<void*>();
+ //QList<SysEx*> sl = instrument->sysex();
+ //instrument->removeSysex(sysex);
+ //delete item2;
+ //instrument->setDirty(true);
+
+
+
+ ListBoxData* item = (ListBoxData*)sysexList->selectedItem();
+ if(!item)
+ return;
+
+ EventList* el = (EventList*)item->data();
+ if(!el)
+ return;
+
+ }
+*/
+
+//---------------------------------------------------------
+// updatePatchGroup
+//---------------------------------------------------------
+
+void EditInstrument::updatePatchGroup(MidiInstrument* instrument, PatchGroup* pg)
+ {
+ QString a = pg->name;
+ QString b = patchNameEdit->text();
+ if (pg->name != patchNameEdit->text()) {
+ pg->name = patchNameEdit->text();
+ instrument->setDirty(true);
+ }
+ }
+
+//---------------------------------------------------------
+// updatePatch
+//---------------------------------------------------------
+
+void EditInstrument::updatePatch(MidiInstrument* instrument, Patch* p)
+ {
+ if (p->name != patchNameEdit->text()) {
+ p->name = patchNameEdit->text();
+ instrument->setDirty(true);
+ }
+
+ signed char hb = (spinBoxHBank->value() - 1) & 0xff;
+ //if (p->hbank != (spinBoxHBank->value() & 0xff)) {
+ // p->hbank = spinBoxHBank->value() & 0xff;
+ if (p->hbank != hb) {
+ p->hbank = hb;
+
+ instrument->setDirty(true);
+ }
+
+ signed char lb = (spinBoxLBank->value() - 1) & 0xff;
+ //if (p->lbank != (spinBoxLBank->value() & 0xff)) {
+ // p->lbank = spinBoxLBank->value() & 0xff;
+ if (p->lbank != lb) {
+ p->lbank = lb;
+
+ instrument->setDirty(true);
+ }
+
+ signed char pr = (spinBoxProgram->value() - 1) & 0xff;
+ if (p->prog != pr) {
+ p->prog = pr;
+
+ instrument->setDirty(true);
+ }
+
+ if (p->drum != checkBoxDrum->isChecked()) {
+ p->drum = checkBoxDrum->isChecked();
+ instrument->setDirty(true);
+ }
+
+ // there is no logical xor in c++
+ bool a = p->typ & 1;
+ bool b = p->typ & 2;
+ bool c = p->typ & 4;
+ bool aa = checkBoxGM->isChecked();
+ bool bb = checkBoxGS->isChecked();
+ bool cc = checkBoxXG->isChecked();
+ if ((a ^ aa) || (b ^ bb) || (c ^ cc)) {
+ int value = 0;
+ if (checkBoxGM->isChecked())
+ value |= 1;
+ if (checkBoxGS->isChecked())
+ value |= 2;
+ if (checkBoxXG->isChecked())
+ value |= 4;
+ p->typ = value;
+ instrument->setDirty(true);
+ }
+
+ //if (p->categorie != category->currentIndex()) {
+ // p->categorie = category->currentIndex();
+ // instrument->setDirty(true);
+ // }
+ }
+
+/*
+//---------------------------------------------------------
+// updateController
+//---------------------------------------------------------
+
+void EditInstrument::updateController(MidiInstrument* instrument, MidiController* oc)
+ {
+ printf("updateController: A\n");
+
+ int ctrlH = spinBoxHCtrlNo->value();
+ int ctrlL = spinBoxLCtrlNo->value();
+ //MidiController::ControllerType type = (MidiController::ControllerType)ctrlType->currentIndex();
+ MidiController::ControllerType type = (MidiController::ControllerType)ctrlType->currentItem();
+ int num = MidiController::genNum(type, ctrlH, ctrlL);
+ //int num = (ctrlH << 8) & 0x7f + ctrlL & 0x7f;
+
+ printf("updateController: B\n");
+
+ if (num != oc->num()) {
+
+ printf("updateController: num changed, setting dirty. num:%d c->num:%d\n", num, oc->num());
+
+ oc->setNum(num);
+ instrument->setDirty(true);
+ }
+
+ if(type != MidiController::Pitch && type != MidiController::Program)
+ {
+ if (spinBoxMin->value() != oc->minVal()) {
+
+ printf("updateController: min changed, setting dirty. min:%d c->min:%d\n", spinBoxMin->value(), oc->minVal());
+
+ oc->setMinVal(spinBoxMin->value());
+ instrument->setDirty(true);
+ }
+ if (spinBoxMax->value() != oc->maxVal()) {
+
+ printf("updateController: max changed, setting dirty. num:%d max:%d c->max:%d\n", num, spinBoxMax->value(), oc->maxVal());
+
+ oc->setMaxVal(spinBoxMax->value());
+ instrument->setDirty(true);
+ }
+
+ int dv = spinBoxDefault->value();
+ if(dv == oc->minVal() - 1)
+ dv = CTRL_VAL_UNKNOWN;
+
+ //if (spinBoxDefault->value() != oc->initVal()) {
+ if(dv != oc->initVal()) {
+ //oc->setInitVal(spinBoxDefault->value());
+ oc->setInitVal(dv);
+
+ printf("updateController: default changed, setting dirty. def:%d c->init:%d\n", dv, oc->initVal());
+
+ instrument->setDirty(true);
+ }
+ }
+
+
+ printf("updateController: C\n");
+
+ //if (moveWithPart->isChecked() ^ oc->moveWithPart()) {
+ // oc->setMoveWithPart(moveWithPart->isChecked());
+ // instrument->setDirty(true);
+ // }
+ if (ctrlName->text() != oc->name()) {
+ oc->setName(ctrlName->text());
+
+ printf("updateController: name changed, setting dirty. name:%s c->name:%s\n", ctrlName->text().toLatin1().constData(), oc->name().toLatin1().constData());
+
+ instrument->setDirty(true);
+ }
+ //if (ctrlComment->toPlainText() != oc->comment()) {
+ // oc->setComment(ctrlComment->toPlainText());
+ // instrument->setDirty(true);
+ // }
+
+ printf("updateController: D\n");
+
+ }
+*/
+
+//---------------------------------------------------------
+// updateInstrument
+//---------------------------------------------------------
+
+void EditInstrument::updateInstrument(MidiInstrument* instrument)
+ {
+ //QListWidgetItem* sysexItem = sysexList->currentItem();
+ //ListBoxData* sysexItem = sysexList->currentItem();
+ //if (sysexItem) {
+ // SysEx* so = (SysEx*)sysexItem->data(Qt::UserRole).value<void*>();
+ // updateSysex(instrument, so);
+ // }
+
+ //QListWidgetItem* ctrlItem = listController->currentItem();
+ //ListBoxData* ctrlItem = (ListBoxData*)listController->currentItem();
+ //ListBoxData* ctrlItem = (ListBoxData*)listController->selectedItem();
+// ListViewData* ctrlItem = (ListViewData*)viewController->selectedItem();
+
+// if (ctrlItem) {
+ //MidiController* ctrl = (MidiController*)ctrlItem->data(Qt::UserRole).value<void*>();
+
+// printf("updateInstrument: AB\n");
+
+// MidiController* ctrl = (MidiController*)ctrlItem->data();
+
+// printf("updateInstrument: AC\n");
+
+// updateController(instrument, ctrl);
+// }
+
+// printf("updateInstrument: B\n");
+
+ QTreeWidgetItem* patchItem = patchView->currentItem();
+
+ if (patchItem)
+ {
+ //Patch* p = (Patch*)patchItem->data(0, Qt::UserRole).value<void*>();
+
+ // If the item has a parent, it's a patch item.
+ if(patchItem->parent())
+ updatePatch(instrument, (Patch*)patchItem->data(0, Qt::UserRole).value<void*>());
+ else
+ updatePatchGroup(instrument, (PatchGroup*)patchItem->data(0, Qt::UserRole).value<void*>());
+
+ }
+ }
+
+//---------------------------------------------------------
+// checkDirty
+// return true on Abort
+//---------------------------------------------------------
+
+int EditInstrument::checkDirty(MidiInstrument* i, bool isClose)
+ {
+ updateInstrument(i);
+ if (!i->dirty())
+ //return false;
+ return 0;
+ int n;
+ if(isClose)
+ n = QMessageBox::warning(this, tr("MusE"),
+ tr("The current Instrument contains unsaved data\n"
+ "Save Current Instrument?"),
+ tr("&Save"), tr("&Nosave"), tr("&Abort"), 0, 2);
+ else
+ n = QMessageBox::warning(this, tr("MusE"),
+ tr("The current Instrument contains unsaved data\n"
+ "Save Current Instrument?"),
+ tr("&Save"), tr("&Nosave"), 0, 1);
+ if (n == 0) {
+ if (i->filePath().isEmpty())
+ {
+ //fileSaveAs();
+ saveAs();
+ }
+ else {
+ //QFile f(i->filePath());
+ //if (!f.open(QIODevice::WriteOnly))
+ FILE* f = fopen(i->filePath().toLatin1().constData(), "w");
+ if(f == 0)
+ //fileSaveAs();
+ saveAs();
+ else {
+ //f.close();
+ if(fclose(f) != 0)
+ printf("EditInstrument::checkDirty: Error closing file\n");
+
+ if(fileSave(i, i->filePath()))
+ i->setDirty(false);
+ }
+ }
+ //return false;
+ return 0;
+ }
+ //return n == 2;
+ return n;
+ }
+
+//---------------------------------------------------------
+// getPatchItemText
+//---------------------------------------------------------
+
+QString EditInstrument::getPatchItemText(int val)
+{
+ QString s;
+ if(val == CTRL_VAL_UNKNOWN)
+ s = "---";
+ else
+ {
+ int hb = ((val >> 16) & 0xff) + 1;
+ if (hb == 0x100)
+ hb = 0;
+ int lb = ((val >> 8) & 0xff) + 1;
+ if (lb == 0x100)
+ lb = 0;
+ int pr = (val & 0xff) + 1;
+ if (pr == 0x100)
+ pr = 0;
+ s.sprintf("%d-%d-%d", hb, lb, pr);
+ }
+
+ return s;
+}
+
+//---------------------------------------------------------
+// enableDefaultControls
+//---------------------------------------------------------
+
+void EditInstrument::enableDefaultControls(bool enVal, bool enPatch)
+{
+ spinBoxDefault->setEnabled(enVal);
+ patchButton->setEnabled(enPatch);
+ if(!enPatch)
+ {
+ patchButton->blockSignals(true);
+ patchButton->setText("---");
+ patchButton->blockSignals(false);
+ }
+ defPatchH->setEnabled(enPatch);
+ defPatchL->setEnabled(enPatch);
+ defPatchProg->setEnabled(enPatch);
+}
+
+//---------------------------------------------------------
+// setDefaultPatchName
+//---------------------------------------------------------
+
+void EditInstrument::setDefaultPatchName(int val)
+{
+ patchButton->blockSignals(true);
+ patchButton->setText(getPatchName(val));
+ patchButton->blockSignals(false);
+}
+
+//---------------------------------------------------------
+// getDefaultPatchNumber
+//---------------------------------------------------------
+
+int EditInstrument::getDefaultPatchNumber()
+{
+ int hval = defPatchH->value() - 1;
+ int lval = defPatchL->value() - 1;
+ int prog = defPatchProg->value() - 1;
+ if(hval == -1)
+ hval = 0xff;
+ if(lval == -1)
+ lval = 0xff;
+ if(prog == -1)
+ prog = 0xff;
+
+ return ((hval & 0xff) << 16) + ((lval & 0xff) << 8) + (prog & 0xff);
+}
+
+//---------------------------------------------------------
+// setDefaultPatchNumbers
+//---------------------------------------------------------
+
+void EditInstrument::setDefaultPatchNumbers(int val)
+{
+ int hb;
+ int lb;
+ int pr;
+
+ if(val == CTRL_VAL_UNKNOWN)
+ hb = lb = pr = 0;
+ else
+ {
+ hb = ((val >> 16) & 0xff) + 1;
+ if (hb == 0x100)
+ hb = 0;
+ lb = ((val >> 8) & 0xff) + 1;
+ if (lb == 0x100)
+ lb = 0;
+ pr = (val & 0xff) + 1;
+ if (pr == 0x100)
+ pr = 0;
+ }
+
+ defPatchH->blockSignals(true);
+ defPatchL->blockSignals(true);
+ defPatchProg->blockSignals(true);
+ defPatchH->setValue(hb);
+ defPatchL->setValue(lb);
+ defPatchProg->setValue(pr);
+ defPatchH->blockSignals(false);
+ defPatchL->blockSignals(false);
+ defPatchProg->blockSignals(false);
+}
+
+//---------------------------------------------------------
+// setDefaultPatchControls
+//---------------------------------------------------------
+
+void EditInstrument::setDefaultPatchControls(int val)
+{
+ setDefaultPatchNumbers(val);
+ setDefaultPatchName(val);
+}
+
+//---------------------------------------------------------
+// getPatchName
+//---------------------------------------------------------
+
+QString EditInstrument::getPatchName(int prog)
+{
+ int pr = prog & 0xff;
+ if(prog == CTRL_VAL_UNKNOWN || pr == 0xff)
+ return "---";
+
+ //int hbank = (prog >> 16) & 0x7f;
+ //int lbank = (prog >> 8) & 0x7f;
+ int hbank = (prog >> 16) & 0xff;
+ int lbank = (prog >> 8) & 0xff;
+
+ PatchGroupList* pg = workingInstrument.groups();
+
+ for(ciPatchGroup i = pg->begin(); i != pg->end(); ++i) {
+ const PatchList& pl = (*i)->patches;
+ for (ciPatch ipl = pl.begin(); ipl != pl.end(); ++ipl) {
+ const Patch* mp = *ipl;
+ if (//(mp->typ & tmask) &&
+ (pr == mp->prog)
+ //&& ((drum && mode != MT_GM) ||
+ // (mp->drum == drumchan))
+
+ //&& (hbank == mp->hbank || !hb || mp->hbank == -1)
+ //&& (lbank == mp->lbank || !lb || mp->lbank == -1))
+ && (hbank == mp->hbank || mp->hbank == -1)
+ && (lbank == mp->lbank || mp->lbank == -1))
+ return mp->name;
+ }
+ }
+ return "---";
+}
+
diff --git a/attic/muse2-oom/muse2/muse/instruments/editinstrument.h b/attic/muse2-oom/muse2/muse/instruments/editinstrument.h
new file mode 100644
index 00000000..b3c6b5e0
--- /dev/null
+++ b/attic/muse2-oom/muse2/muse/instruments/editinstrument.h
@@ -0,0 +1,91 @@
+//=========================================================
+// MusE
+// Linux Music Editor
+// $Id: editinstrument.h,v 1.1.1.1.2.4 2009/05/31 05:12:12 terminator356 Exp $
+//
+// (C) Copyright 2003 Werner Schweer (ws@seh.de)
+//=========================================================
+
+#ifndef __EDITINSTRUMENT_H__
+#define __EDITINSTRUMENT_H__
+
+#include "ui_editinstrumentbase.h"
+#include "minstrument.h"
+#include "midictrl.h"
+
+class QDialog;
+class QMenu;
+class QCloseEvent;
+
+//---------------------------------------------------------
+// EditInstrument
+//---------------------------------------------------------
+
+class EditInstrument : public QMainWindow, public Ui::EditInstrumentBase {
+ Q_OBJECT
+
+ MidiInstrument workingInstrument;
+ QListWidgetItem* oldMidiInstrument;
+ QTreeWidgetItem* oldPatchItem;
+ void closeEvent(QCloseEvent*);
+ int checkDirty(MidiInstrument*, bool isClose = false);
+ bool fileSave(MidiInstrument*, const QString&);
+ void saveAs();
+ void updateInstrument(MidiInstrument*);
+ void updatePatch(MidiInstrument*, Patch*);
+ void updatePatchGroup(MidiInstrument*, PatchGroup*);
+ void changeInstrument();
+ QTreeWidgetItem* addControllerToView(MidiController* mctrl);
+ QString getPatchItemText(int);
+ void enableDefaultControls(bool, bool);
+ void setDefaultPatchName(int);
+ int getDefaultPatchNumber();
+ void setDefaultPatchNumbers(int);
+ void setDefaultPatchControls(int);
+ QString getPatchName(int);
+ void deleteInstrument(QListWidgetItem*);
+ ///QMenu* patchpopup;
+
+ private slots:
+ virtual void fileNew();
+ virtual void fileOpen();
+ virtual void fileSave();
+ virtual void fileSaveAs();
+ virtual void fileExit();
+ virtual void helpWhatsThis();
+ void instrumentChanged();
+ void tabChanged(QWidget*);
+ void patchChanged();
+ void controllerChanged();
+ //void instrumentNameChanged(const QString&);
+ void instrumentNameReturn();
+ void patchNameReturn();
+ void deletePatchClicked();
+ void newPatchClicked();
+ void newGroupClicked();
+ void patchButtonClicked();
+ void defPatchChanged(int);
+ //void newCategoryClicked();
+ void deleteControllerClicked();
+ void newControllerClicked();
+ void addControllerClicked();
+ void ctrlTypeChanged(int);
+ //void ctrlNameChanged(const QString&);
+ void ctrlNameReturn();
+ void ctrlHNumChanged(int);
+ void ctrlLNumChanged(int);
+ void ctrlMinChanged(int);
+ void ctrlMaxChanged(int);
+ void ctrlDefaultChanged(int);
+ //void sysexChanged();
+ //void deleteSysexClicked();
+ //void newSysexClicked();
+ void ctrlNullParamHChanged(int);
+ void ctrlNullParamLChanged(int);
+
+ public:
+ EditInstrument(QWidget* parent = 0, Qt::WFlags fl = Qt::Window);
+ };
+
+#endif
+
diff --git a/attic/muse2-oom/muse2/muse/instruments/editinstrumentbase.ui b/attic/muse2-oom/muse2/muse/instruments/editinstrumentbase.ui
new file mode 100644
index 00000000..3337cfc0
--- /dev/null
+++ b/attic/muse2-oom/muse2/muse/instruments/editinstrumentbase.ui
@@ -0,0 +1,1649 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>EditInstrumentBase</class>
+ <widget class="QMainWindow" name="EditInstrumentBase">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>802</width>
+ <height>505</height>
+ </rect>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>802</width>
+ <height>464</height>
+ </size>
+ </property>
+ <property name="windowTitle">
+ <string>MusE: Instrument Editor</string>
+ </property>
+ <widget class="QWidget" name="widget">
+ <layout class="QVBoxLayout">
+ <item>
+ <widget class="QSplitter" name="splitter4">
+ <property name="minimumSize">
+ <size>
+ <width>780</width>
+ <height>365</height>
+ </size>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <widget class="QWidget" name="layout26">
+ <layout class="QVBoxLayout">
+ <item>
+ <widget class="QLabel" name="textLabel2">
+ <property name="text">
+ <string>Instrument Name:</string>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="instrumentName">
+ <property name="toolTip">
+ <string/>
+ </property>
+ <property name="whatsThis">
+ <string>Selected instrument name.</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QListWidget" name="instrumentList">
+ <property name="whatsThis">
+ <string>List of defined instruments.</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QTabWidget" name="tabWidget3">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="currentIndex">
+ <number>0</number>
+ </property>
+ <widget class="QWidget" name="patchesTab">
+ <attribute name="title">
+ <string>Pa&amp;tches</string>
+ </attribute>
+ <layout class="QVBoxLayout">
+ <item>
+ <widget class="QSplitter" name="splitter5">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <widget class="QTreeWidget" name="patchView">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip">
+ <string/>
+ </property>
+ <property name="whatsThis">
+ <string>List of groups and patches.</string>
+ </property>
+ <property name="rootIsDecorated">
+ <bool>true</bool>
+ </property>
+ <property name="allColumnsShowFocus">
+ <bool>true</bool>
+ </property>
+ <column>
+ <property name="text">
+ <string>Group/Patch</string>
+ </property>
+ </column>
+ </widget>
+ <widget class="QWidget" name="layout27">
+ <layout class="QVBoxLayout">
+ <item>
+ <widget class="QGroupBox" name="groupBox2">
+ <property name="title">
+ <string>Properties</string>
+ </property>
+ <layout class="QVBoxLayout">
+ <item>
+ <widget class="QLabel" name="textLabelPatchName">
+ <property name="text">
+ <string>Name:</string>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="patchNameEdit">
+ <property name="toolTip">
+ <string>Group or patch name</string>
+ </property>
+ <property name="whatsThis">
+ <string>Group or patch name</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="textLabel2_2">
+ <property name="text">
+ <string>High Bank:</string>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout">
+ <item>
+ <widget class="QSpinBox" name="spinBoxHBank">
+ <property name="toolTip">
+ <string>Patch high bank number</string>
+ </property>
+ <property name="whatsThis">
+ <string>Patch high bank number. --- means don't care.</string>
+ </property>
+ <property name="specialValueText">
+ <string comment="dont care">---</string>
+ </property>
+ <property name="minimum">
+ <number>0</number>
+ </property>
+ <property name="maximum">
+ <number>128</number>
+ </property>
+ <property name="value">
+ <number>0</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="spacer8">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>373</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QLabel" name="textLabel3_2">
+ <property name="text">
+ <string>Low Bank:</string>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout">
+ <item>
+ <widget class="QSpinBox" name="spinBoxLBank">
+ <property name="toolTip">
+ <string>Patch low bank number</string>
+ </property>
+ <property name="whatsThis">
+ <string>Patch low bank number. --- means don't care.</string>
+ </property>
+ <property name="specialValueText">
+ <string>---</string>
+ </property>
+ <property name="minimum">
+ <number>0</number>
+ </property>
+ <property name="maximum">
+ <number>128</number>
+ </property>
+ <property name="value">
+ <number>0</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="spacer9">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>373</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QLabel" name="textLabel4_3">
+ <property name="text">
+ <string>Program:</string>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout">
+ <item>
+ <widget class="QSpinBox" name="spinBoxProgram">
+ <property name="toolTip">
+ <string>Patch program number</string>
+ </property>
+ <property name="whatsThis">
+ <string>Patch program number</string>
+ </property>
+ <property name="minimum">
+ <number>1</number>
+ </property>
+ <property name="maximum">
+ <number>128</number>
+ </property>
+ <property name="value">
+ <number>1</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="spacer10">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>373</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout">
+ <item>
+ <widget class="QCheckBox" name="checkBoxDrum">
+ <property name="toolTip">
+ <string>Drum patch</string>
+ </property>
+ <property name="whatsThis">
+ <string>If set, the patch is available only for drum channels.</string>
+ </property>
+ <property name="text">
+ <string>Drum</string>
+ </property>
+ <property name="shortcut">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="checkBoxGM">
+ <property name="toolTip">
+ <string>GM patch</string>
+ </property>
+ <property name="whatsThis">
+ <string>If set, the patch is available in a 'GM' or 'NO' midi song type.</string>
+ </property>
+ <property name="text">
+ <string>GM</string>
+ </property>
+ <property name="shortcut">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="checkBoxGS">
+ <property name="toolTip">
+ <string>GS patch</string>
+ </property>
+ <property name="whatsThis">
+ <string>If set, the patch is available in a 'GS' or 'NO' midi song type.</string>
+ </property>
+ <property name="text">
+ <string>GS</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="checkBoxXG">
+ <property name="toolTip">
+ <string>XG patch</string>
+ </property>
+ <property name="whatsThis">
+ <string>If set, the patch is available in an 'XG' or 'NO' midi song type.</string>
+ </property>
+ <property name="text">
+ <string>XG</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <spacer name="spacer7">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>90</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <layout class="QHBoxLayout">
+ <item>
+ <widget class="QToolButton" name="patchDelete">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip">
+ <string>Delete group or patch</string>
+ </property>
+ <property name="text">
+ <string>&amp;Delete</string>
+ </property>
+ <property name="shortcut">
+ <string>Alt+D</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="patchNew">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip">
+ <string>New patch</string>
+ </property>
+ <property name="text">
+ <string>New &amp;Patch</string>
+ </property>
+ <property name="shortcut">
+ <string>Alt+P</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="patchNewGroup">
+ <property name="toolTip">
+ <string>New group</string>
+ </property>
+ <property name="text">
+ <string>New &amp;Group</string>
+ </property>
+ <property name="shortcut">
+ <string>Alt+G</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="spacer11">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>240</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="controllerTab">
+ <attribute name="title">
+ <string>Contro&amp;ller</string>
+ </attribute>
+ <layout class="QVBoxLayout">
+ <item>
+ <widget class="QSplitter" name="splitter6">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <widget class="QWidget" name="layout13">
+ <layout class="QVBoxLayout">
+ <item>
+ <widget class="QLabel" name="textLabel1">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Common:</string>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QListWidget" name="listController">
+ <property name="toolTip">
+ <string/>
+ </property>
+ <property name="whatsThis">
+ <string>This is a list of commonly used midi controllers.
+Note that in MusE pitch and program changes are
+handled like normal controllers.</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="layout17">
+ <layout class="QVBoxLayout">
+ <item>
+ <widget class="QTreeWidget" name="viewController">
+ <property name="toolTip">
+ <string>List of defined controllers</string>
+ </property>
+ <property name="whatsThis">
+ <string>List of defined controllers.</string>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::StyledPanel</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Sunken</enum>
+ </property>
+ <property name="allColumnsShowFocus">
+ <bool>true</bool>
+ </property>
+ <column>
+ <property name="text">
+ <string>Name </string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Type </string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>H-Ctrl</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>L-Ctrl</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Min </string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Max </string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Def </string>
+ </property>
+ </column>
+ </widget>
+ </item>
+ <item>
+ <widget class="QGroupBox" name="GroupBox1">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title">
+ <string>Properties</string>
+ </property>
+ <layout class="QVBoxLayout">
+ <item>
+ <layout class="QHBoxLayout">
+ <item>
+ <widget class="QLabel" name="TextLabel1_3">
+ <property name="text">
+ <string>Name:</string>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="ctrlName">
+ <property name="toolTip">
+ <string/>
+ </property>
+ <property name="whatsThis">
+ <string>Midi controller name</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout">
+ <item>
+ <widget class="QLabel" name="TextLabel2_4">
+ <property name="text">
+ <string>Type:</string>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="ctrlType">
+ <property name="toolTip">
+ <string>Midi controller type</string>
+ </property>
+ <property name="whatsThis">
+ <string>Midi controller type</string>
+ </property>
+ <item>
+ <property name="text">
+ <string>Control7</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Control14</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>RPN</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>NRPN</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>RPN14</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>NRPN14</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Pitch</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string>Program</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item>
+ <spacer name="spacer15">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QLabel" name="TextLabel3_2">
+ <property name="text">
+ <string>H-Ctrl</string>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ <property name="indent">
+ <number>10</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="spinBoxHCtrlNo">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip">
+ <string>Midi controller number high byte</string>
+ </property>
+ <property name="whatsThis">
+ <string>Midi controller number high byte</string>
+ </property>
+ <property name="minimum">
+ <number>0</number>
+ </property>
+ <property name="maximum">
+ <number>127</number>
+ </property>
+ <property name="value">
+ <number>0</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="spacer16">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QLabel" name="TextLabel2_3_2">
+ <property name="text">
+ <string>L-Ctrl</string>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ <property name="indent">
+ <number>10</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="spinBoxLCtrlNo">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip">
+ <string>Midi controller number low byte (* means drum controller)</string>
+ </property>
+ <property name="whatsThis">
+ <string>Midi controller number low byte.
+If low byte is * then the controller is a
+ 'drum controller'. For drum tracks and
+ GS/XG type songs and instruments.
+Allows controllers for each instrument in
+ Muse's drum map. The low byte will be
+ replaced by the 'ANote' in the drum map.
+Examples: The GS and XG instruments'
+ Drum controllers.</string>
+ </property>
+ <property name="specialValueText">
+ <string comment="wild card">*</string>
+ </property>
+ <property name="minimum">
+ <number>-1</number>
+ </property>
+ <property name="maximum">
+ <number>127</number>
+ </property>
+ <property name="value">
+ <number>0</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QHBoxLayout">
+ <item>
+ <widget class="QLabel" name="textLabel4_2">
+ <property name="text">
+ <string>Range:</string>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="spacer17">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QLabel" name="TextLabel1_2_2">
+ <property name="text">
+ <string>Min</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ <property name="indent">
+ <number>10</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="spinBoxMin">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip">
+ <string>Minimum value. If negative, auto-translate.</string>
+ </property>
+ <property name="whatsThis">
+ <string>Minimum value. If the minimum value
+ is negative, the range will automatically
+ be translated to a positive range.
+
+Useful for controllers which should be
+ displayed with zero bias. For example,
+'Pan': Minimum: -64 Maximum: 63
+True range: Min: 0 Max: 127 (bias = 64)
+'CoarseTuning': Min: -24 Max: 23
+True range: Min: 40 Max: 87 (bias = 64)
+
+Bias is determined from controller type:
+7-bit Controller7 / RPN: Bias = 64
+14-bit Controller14 / RPN14: Bias = 8192
+
+Type 'Pitch' is the exception. It is biased
+ at zero, even with a negative minimum:
+'Pitch': Min: -8192 Max: 8191
+True range: Min: -8192 Max: 8191 (bias 0)</string>
+ </property>
+ <property name="minimum">
+ <number>-16384</number>
+ </property>
+ <property name="maximum">
+ <number>16383</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="spacer18">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QLabel" name="TextLabel2_2_2">
+ <property name="text">
+ <string>Max</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ <property name="indent">
+ <number>10</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="spinBoxMax">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip">
+ <string>Maximum value</string>
+ </property>
+ <property name="whatsThis">
+ <string>Maximum value</string>
+ </property>
+ <property name="minimum">
+ <number>-16384</number>
+ </property>
+ <property name="maximum">
+ <number>16383</number>
+ </property>
+ <property name="value">
+ <number>127</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QGridLayout">
+ <item row="1" column="0" colspan="2">
+ <spacer name="spacer13_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="0" column="0">
+ <widget class="QLabel" name="textLabel1_3">
+ <property name="text">
+ <string>Default:</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignVCenter</set>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="6">
+ <widget class="QLabel" name="textLabel2_4">
+ <property name="text">
+ <string>L-Bank</string>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="5">
+ <widget class="QSpinBox" name="defPatchH">
+ <property name="specialValueText">
+ <string>off</string>
+ </property>
+ <property name="minimum">
+ <number>0</number>
+ </property>
+ <property name="maximum">
+ <number>128</number>
+ </property>
+ <property name="value">
+ <number>0</number>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="7">
+ <widget class="QSpinBox" name="defPatchL">
+ <property name="specialValueText">
+ <string>off</string>
+ </property>
+ <property name="minimum">
+ <number>0</number>
+ </property>
+ <property name="maximum">
+ <number>128</number>
+ </property>
+ <property name="value">
+ <number>0</number>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="6">
+ <widget class="QLabel" name="textLabel3">
+ <property name="text">
+ <string>Progr.</string>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="7">
+ <widget class="QSpinBox" name="defPatchProg">
+ <property name="specialValueText">
+ <string>off</string>
+ </property>
+ <property name="minimum">
+ <number>0</number>
+ </property>
+ <property name="maximum">
+ <number>128</number>
+ </property>
+ <property name="value">
+ <number>0</number>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2" colspan="4">
+ <widget class="QPushButton" name="patchButton">
+ <property name="enabled">
+ <bool>true</bool>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>210</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="text">
+ <string>???</string>
+ </property>
+ <property name="shortcut">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="4">
+ <widget class="QLabel" name="textLabel1_5">
+ <property name="text">
+ <string>H-Bank</string>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="3">
+ <spacer name="spacer12_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="0" column="1" colspan="2">
+ <widget class="QSpinBox" name="spinBoxDefault">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="minimumSize">
+ <size>
+ <width>0</width>
+ <height>0</height>
+ </size>
+ </property>
+ <property name="maximumSize">
+ <size>
+ <width>85</width>
+ <height>32767</height>
+ </size>
+ </property>
+ <property name="toolTip">
+ <string>Default value. Off: No default.</string>
+ </property>
+ <property name="whatsThis">
+ <string>Default (initial) value. Off means no default.
+
+If a default value is chosen, the value will be sent
+ to the controller when the controller is added to
+ the song (in piano roll or event editor). When
+ the song is re-loaded, the value is sent again.
+Otherwise the controller remains at its last value.
+Controllers are also automatically added to a
+ song upon reception of a midi controller event.
+
+Caution! Watch out for controllers such as
+ 'Sustain' and 'ResetAllController' with default
+ values. You should probably turn 'off' their
+ default (in piano roll or drum edit, and
+ instrument editor).</string>
+ </property>
+ <property name="specialValueText">
+ <string comment="dont care">off</string>
+ </property>
+ <property name="minimum">
+ <number>-1</number>
+ </property>
+ <property name="maximum">
+ <number>16383</number>
+ </property>
+ <property name="value">
+ <number>-1</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout">
+ <item>
+ <widget class="QToolButton" name="addController">
+ <property name="toolTip">
+ <string>Add common controller</string>
+ </property>
+ <property name="text">
+ <string>&amp;Add</string>
+ </property>
+ <property name="shortcut">
+ <string>Alt+A</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="deleteController">
+ <property name="toolTip">
+ <string>Delete controller</string>
+ </property>
+ <property name="text">
+ <string>&amp;Delete</string>
+ </property>
+ <property name="shortcut">
+ <string>Alt+D</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="newController">
+ <property name="toolTip">
+ <string>Create a new controller</string>
+ </property>
+ <property name="text">
+ <string>New &amp;Controller</string>
+ </property>
+ <property name="shortcut">
+ <string>Alt+C</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="spacer13">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>200</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QLabel" name="nullValLabelH">
+ <property name="text">
+ <string>Null Param Hi:</string>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="nullParamSpinBoxH">
+ <property name="toolTip">
+ <string>Null parameter number High byte</string>
+ </property>
+ <property name="whatsThis">
+ <string>If set, these 'null' parameter numbers will
+ be sent after each RPN/NRPN event.
+This prevents subsequent 'data' events
+ from corrupting the RPN/NRPN controller.
+Typically, set to 127/127, or an unused
+ RPN/NRPN controller number.</string>
+ </property>
+ <property name="specialValueText">
+ <string>off</string>
+ </property>
+ <property name="minimum">
+ <number>-1</number>
+ </property>
+ <property name="maximum">
+ <number>127</number>
+ </property>
+ <property name="value">
+ <number>127</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="spacer13_3">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>200</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QLabel" name="nullValLabelL">
+ <property name="text">
+ <string> Lo:</string>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="nullParamSpinBoxL">
+ <property name="toolTip">
+ <string>Null parameter number Low byte</string>
+ </property>
+ <property name="whatsThis">
+ <string>If set, these 'null' parameter numbers will
+ be sent after each RPN/NRPN event.
+This prevents subsequent 'data' events
+ from corrupting the RPN/NRPN controller.
+Typically, set to 127/127, or an unused
+ RPN/NRPN controller number.</string>
+ </property>
+ <property name="specialValueText">
+ <string>off</string>
+ </property>
+ <property name="minimum">
+ <number>-1</number>
+ </property>
+ <property name="maximum">
+ <number>127</number>
+ </property>
+ <property name="value">
+ <number>127</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="sysExTab">
+ <attribute name="title">
+ <string>S&amp;ysEx</string>
+ </attribute>
+ <layout class="QVBoxLayout">
+ <item>
+ <widget class="QSplitter" name="splitter2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <widget class="QWidget" name="layout12">
+ <layout class="QVBoxLayout">
+ <item>
+ <widget class="QLabel" name="textLabel2_3">
+ <property name="text">
+ <string>SysEx List:</string>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QListWidget" name="sysexList">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="layout11">
+ <layout class="QVBoxLayout">
+ <item>
+ <widget class="QLabel" name="textLabel1_4">
+ <property name="text">
+ <string>Name:</string>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="sysexName"/>
+ </item>
+ <item>
+ <widget class="QLabel" name="textLabel1_2">
+ <property name="text">
+ <string>Hex Entry:</string>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QTextEdit" name="sysexData"/>
+ </item>
+ <item>
+ <layout class="QHBoxLayout">
+ <item>
+ <widget class="QToolButton" name="deleteSysex">
+ <property name="text">
+ <string>&amp;Delete</string>
+ </property>
+ <property name="shortcut">
+ <string>Alt+D</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="newSysex">
+ <property name="text">
+ <string>New SysE&amp;x</string>
+ </property>
+ <property name="shortcut">
+ <string>Alt+X</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="spacer12">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>60</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QToolBar" name="toolBar">
+ <property name="label" stdset="0">
+ <string>Tools</string>
+ </property>
+ <attribute name="toolBarArea">
+ <enum>TopToolBarArea</enum>
+ </attribute>
+ <attribute name="toolBarBreak">
+ <bool>false</bool>
+ </attribute>
+ <addaction name="fileNewAction"/>
+ <addaction name="fileOpenAction"/>
+ <addaction name="fileSaveAction"/>
+ <addaction name="fileSaveAsAction"/>
+ </widget>
+ <widget class="QMenuBar" name="MenuBar">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>802</width>
+ <height>21</height>
+ </rect>
+ </property>
+ <property name="defaultUp">
+ <bool>false</bool>
+ </property>
+ <widget class="QMenu" name="fileMenu">
+ <property name="title">
+ <string>&amp;File</string>
+ </property>
+ <addaction name="fileNewAction"/>
+ <addaction name="fileOpenAction"/>
+ <addaction name="fileSaveAction"/>
+ <addaction name="fileSaveAsAction"/>
+ <addaction name="separator"/>
+ <addaction name="fileExitAction"/>
+ </widget>
+ <widget class="QMenu" name="Help">
+ <property name="title">
+ <string>&amp;Help</string>
+ </property>
+ </widget>
+ <addaction name="fileMenu"/>
+ <addaction name="Help"/>
+ </widget>
+ <action name="fileNewAction">
+ <property name="text">
+ <string>&amp;New</string>
+ </property>
+ <property name="iconText">
+ <string>New</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+N</string>
+ </property>
+ <property name="name" stdset="0">
+ <cstring>fileNewAction</cstring>
+ </property>
+ </action>
+ <action name="fileOpenAction">
+ <property name="enabled">
+ <bool>false</bool>
+ </property>
+ <property name="text">
+ <string>&amp;Open...</string>
+ </property>
+ <property name="iconText">
+ <string>Open</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+O</string>
+ </property>
+ <property name="visible">
+ <bool>false</bool>
+ </property>
+ <property name="name" stdset="0">
+ <cstring>fileOpenAction</cstring>
+ </property>
+ </action>
+ <action name="fileSaveAction">
+ <property name="text">
+ <string>&amp;Save</string>
+ </property>
+ <property name="iconText">
+ <string>Save</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+S</string>
+ </property>
+ <property name="name" stdset="0">
+ <cstring>fileSaveAction</cstring>
+ </property>
+ </action>
+ <action name="fileSaveAsAction">
+ <property name="text">
+ <string>Save &amp;As...</string>
+ </property>
+ <property name="iconText">
+ <string>Save As</string>
+ </property>
+ <property name="shortcut">
+ <string/>
+ </property>
+ <property name="name" stdset="0">
+ <cstring>fileSaveAsAction</cstring>
+ </property>
+ </action>
+ <action name="fileExitAction">
+ <property name="text">
+ <string>E&amp;xit</string>
+ </property>
+ <property name="iconText">
+ <string>Exit</string>
+ </property>
+ <property name="shortcut">
+ <string/>
+ </property>
+ <property name="name" stdset="0">
+ <cstring>fileExitAction</cstring>
+ </property>
+ </action>
+ <action name="filenew_itemAction">
+ <property name="text">
+ <string>new item</string>
+ </property>
+ <property name="iconText">
+ <string>new item</string>
+ </property>
+ <property name="name" stdset="0">
+ <cstring>filenew_itemAction</cstring>
+ </property>
+ </action>
+ <action name="whatsThisAction">
+ <property name="text">
+ <string>What's this?</string>
+ </property>
+ <property name="iconText">
+ <string>What's this?</string>
+ </property>
+ <property name="name" stdset="0">
+ <cstring>whatsThisAction</cstring>
+ </property>
+ </action>
+ </widget>
+ <layoutdefault spacing="6" margin="11"/>
+ <tabstops>
+ <tabstop>instrumentName</tabstop>
+ <tabstop>instrumentList</tabstop>
+ <tabstop>tabWidget3</tabstop>
+ <tabstop>patchView</tabstop>
+ <tabstop>patchNameEdit</tabstop>
+ <tabstop>spinBoxHBank</tabstop>
+ <tabstop>spinBoxLBank</tabstop>
+ <tabstop>spinBoxProgram</tabstop>
+ <tabstop>checkBoxDrum</tabstop>
+ <tabstop>checkBoxGM</tabstop>
+ <tabstop>checkBoxGS</tabstop>
+ <tabstop>checkBoxXG</tabstop>
+ <tabstop>listController</tabstop>
+ <tabstop>viewController</tabstop>
+ <tabstop>ctrlName</tabstop>
+ <tabstop>ctrlType</tabstop>
+ <tabstop>spinBoxHCtrlNo</tabstop>
+ <tabstop>spinBoxLCtrlNo</tabstop>
+ <tabstop>spinBoxMin</tabstop>
+ <tabstop>spinBoxMax</tabstop>
+ <tabstop>spinBoxDefault</tabstop>
+ <tabstop>sysexList</tabstop>
+ <tabstop>sysexName</tabstop>
+ <tabstop>sysexData</tabstop>
+ </tabstops>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>fileNewAction</sender>
+ <signal>activated()</signal>
+ <receiver>EditInstrumentBase</receiver>
+ <slot>fileNew()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>-1</x>
+ <y>-1</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>20</x>
+ <y>20</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>fileOpenAction</sender>
+ <signal>activated()</signal>
+ <receiver>EditInstrumentBase</receiver>
+ <slot>fileOpen()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>-1</x>
+ <y>-1</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>20</x>
+ <y>20</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>fileSaveAction</sender>
+ <signal>activated()</signal>
+ <receiver>EditInstrumentBase</receiver>
+ <slot>fileSave()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>-1</x>
+ <y>-1</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>20</x>
+ <y>20</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>fileSaveAsAction</sender>
+ <signal>activated()</signal>
+ <receiver>EditInstrumentBase</receiver>
+ <slot>fileSaveAs()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>-1</x>
+ <y>-1</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>20</x>
+ <y>20</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>fileExitAction</sender>
+ <signal>activated()</signal>
+ <receiver>EditInstrumentBase</receiver>
+ <slot>fileExit()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>-1</x>
+ <y>-1</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>20</x>
+ <y>20</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>whatsThisAction</sender>
+ <signal>activated()</signal>
+ <receiver>EditInstrumentBase</receiver>
+ <slot>helpWhatsThis()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>-1</x>
+ <y>-1</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>20</x>
+ <y>20</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/attic/muse2-oom/muse2/muse/instruments/midictrledit.cpp b/attic/muse2-oom/muse2/muse/instruments/midictrledit.cpp
new file mode 100644
index 00000000..9dcac628
--- /dev/null
+++ b/attic/muse2-oom/muse2/muse/instruments/midictrledit.cpp
@@ -0,0 +1,725 @@
+//=========================================================
+// MusE
+// Linux Music Editor
+// $Id: midictrledit.cpp,v 1.1.1.1.2.2 2008/08/18 00:15:24 terminator356 Exp $
+//
+// (C) Copyright 2003 Werner Schweer (ws@seh.de)
+//=========================================================
+
+#include <stdio.h>
+
+#include "app.h"
+#include "midiport.h"
+#include "mididev.h"
+#include "midictrl.h"
+#include "midictrledit.h"
+#include "minstrument.h"
+#include "song.h"
+#include "xml.h"
+#include "filedialog.h"
+#include "globals.h"
+
+MidiControllerEditDialog* midiControllerEditDialog;
+
+static MidiController predefinedMidiController[] = {
+ MidiController(QString("Pitch"), 0x40000, -8192, +8191, 0),
+ };
+enum {
+ COL_NAME = 0, COL_TYPE,
+ COL_HNUM, COL_LNUM, COL_MIN, COL_MAX
+ };
+//---------------------------------------------------------
+// addControllerToView
+//---------------------------------------------------------
+
+void MidiControllerEditDialog::addControllerToView(MidiController* mctrl)
+ {
+ QString hnum;
+ QString lnum;
+ QString min;
+ QString max;
+ int n = mctrl->num();
+ int h = (n >> 8) & 0x7f;
+ int l = n & 0x7f;
+ MidiController::ControllerType t = midiControllerType(n);
+ switch(t)
+ {
+ case MidiController::Controller7:
+ hnum = "---";
+ lnum.setNum(l);
+ min.setNum(mctrl->minVal());
+ max.setNum(mctrl->maxVal());
+ break;
+ case MidiController::RPN:
+ case MidiController::NRPN:
+ case MidiController::RPN14:
+ case MidiController::NRPN14:
+ case MidiController::Controller14:
+ hnum.setNum(h);
+ lnum.setNum(l);
+ min.setNum(mctrl->minVal());
+ max.setNum(mctrl->maxVal());
+ break;
+ case MidiController::Pitch:
+ hnum = "---";
+ lnum = "---";
+ min.setNum(mctrl->minVal());
+ max.setNum(mctrl->maxVal());
+ break;
+ default:
+ hnum = "---";
+ lnum = "---";
+ min.setNum(0);
+ max.setNum(0);
+ break;
+ }
+
+ new Q3ListViewItem(viewController,
+ mctrl->name(),
+ int2ctrlType(t),
+ hnum, lnum, min, max
+ );
+
+ }
+//---------------------------------------------------------
+// MidiControllerEditDialog
+//---------------------------------------------------------
+
+MidiControllerEditDialog::MidiControllerEditDialog(QWidget* parent, const char* name, bool modal, Qt::WFlags fl)
+ : MidiControllerEditDialogBase(parent, name, modal, fl)
+ {
+ _lastPort = midiPortsList->currentItem();
+ viewController->setColumnAlignment(COL_HNUM, Qt::AlignCenter);
+ viewController->setColumnAlignment(COL_LNUM, Qt::AlignCenter);
+ viewController->setColumnAlignment(COL_MIN, Qt::AlignCenter);
+ viewController->setColumnAlignment(COL_MAX, Qt::AlignCenter);
+ viewController->setColumnWidthMode(COL_NAME, Q3ListView::Maximum);
+
+ // populate list of predefined controller
+ updatePredefinedList();
+
+ // populate ports pulldown
+ updateMidiPortsList();
+ connect(buttonNew, SIGNAL(clicked()), SLOT(ctrlAdd()));
+ connect(buttonDelete, SIGNAL(clicked()), SLOT(ctrlDelete()));
+ connect(entryName, SIGNAL(textChanged(const QString&)), SLOT(nameChanged(const QString&)));
+ connect(comboType, SIGNAL(activated(const QString&)), SLOT(typeChanged(const QString&)));
+ connect(spinboxHCtrlNo, SIGNAL(valueChanged(int)), SLOT(valueHChanged(int)));
+ connect(spinboxLCtrlNo, SIGNAL(valueChanged(int)), SLOT(valueLChanged(int)));
+ connect(spinboxMin, SIGNAL(valueChanged(int)), SLOT(minChanged(int)));
+ connect(spinboxMax, SIGNAL(valueChanged(int)), SLOT(maxChanged(int)));
+ connect(viewController, SIGNAL(selectionChanged()), SLOT(controllerChanged()));
+ connect(buttonApply, SIGNAL(clicked()), SLOT(apply()));
+ connect(midiPortsList, SIGNAL(activated(int)), SLOT(portChanged(int)));
+
+ updateViewController();
+ _modified = false;
+ buttonApply->setEnabled(false);
+ connect(song, SIGNAL(songChanged(int)), SLOT(songChanged(int)));
+ }
+
+//---------------------------------------------------------
+// songChanged
+//---------------------------------------------------------
+
+void MidiControllerEditDialog::songChanged(int flags)
+{
+ // Is it simply a midi controller value adjustment? Forget it.
+ if(flags == SC_MIDI_CONTROLLER)
+ return;
+
+ if(flags & (SC_CONFIG | SC_MIDI_CONTROLLER))
+ //if(flags & (SC_CONFIG | SC_MIDI_CONTROLLER_ADD))
+ {
+ //listController->blockSignals(true);
+ midiPortsList->blockSignals(true);
+ //viewController->blockSignals(true);
+ updatePredefinedList();
+ updateMidiPortsList();
+ updateViewController();
+ //viewController->setCurrentItem(viewController->firstChild());
+ //controllerChanged(viewController->currentItem());
+ //listController->blockSignals(false);
+ midiPortsList->blockSignals(false);
+ //viewController->blockSignals(false);
+ }
+}
+
+//---------------------------------------------------------
+// updatePredefinedList
+//---------------------------------------------------------
+
+void MidiControllerEditDialog::updatePredefinedList()
+{
+ listController->clear();
+ int size = sizeof(predefinedMidiController) / sizeof(*predefinedMidiController);
+ for (int i = 0; i < size; ++i)
+ listController->insertItem(predefinedMidiController[i].name());
+ listController->setSelected(0, true);
+}
+
+//---------------------------------------------------------
+// updateMidiPortsList
+//---------------------------------------------------------
+
+void MidiControllerEditDialog::updateMidiPortsList()
+{
+ midiPortsList->clear();
+ for (int i = 0; i < MIDI_PORTS; ++i) {
+ MidiPort* port = &midiPorts[i];
+ MidiDevice* dev = port->device();
+ QString name;
+ name.sprintf("%d(%s)", port->portno()+1,
+ dev ? dev->name().toLatin1() : "none");
+ midiPortsList->insertItem(name, i);
+ }
+ _lastPort = midiPortsList->currentItem();
+}
+
+//---------------------------------------------------------
+// updateViewController
+//---------------------------------------------------------
+
+void MidiControllerEditDialog::updateViewController()
+{
+ //for (iMidiController i = midiControllerList.begin();
+ // i != midiControllerList.end(); ++i) {
+ // addControllerToView(&*i);
+ int mpidx = midiPortsList->currentItem();
+
+ viewController->clear();
+ //MidiControllerList* mcl;
+ MidiInstrument* mi = midiPorts[mpidx].instrument();
+ //if(mi)
+ MidiControllerList* mcl = mi->controller();
+ //else
+ // mcl = &defaultMidiController;
+ for (iMidiController i = mcl->begin(); i != mcl->end(); ++i)
+ addControllerToView(*i);
+
+ viewController->blockSignals(true);
+ viewController->setCurrentItem(viewController->firstChild());
+ controllerChanged(viewController->currentItem());
+ viewController->blockSignals(false);
+
+ setModified(false);
+}
+
+//---------------------------------------------------------
+// reject
+//---------------------------------------------------------
+
+void MidiControllerEditDialog::setModified(bool v)
+{
+ if(v == _modified)
+ return;
+
+ _modified = v;
+
+ if(v)
+ {
+ buttonApply->setEnabled(true);
+ }
+ else
+ {
+ buttonApply->setEnabled(false);
+ }
+}
+
+//---------------------------------------------------------
+// reject
+//---------------------------------------------------------
+
+void MidiControllerEditDialog::reject()
+ {
+ //MidiControllerList* mcl;
+// MidiInstrument* mi = midiPorts[mpidx].instrument();
+ //if(mi)
+// MidiControllerList* mcl = mi->controller();
+ //else
+ // mcl = &defaultMidiController;
+// for (iMidiController i = mcl->begin(); i != mcl->end(); ++i)
+// addControllerToView(*i);
+
+ // Restore the list before closing this dialog.
+ updateViewController();
+ //setModified(false);
+
+ MidiControllerEditDialogBase::reject();
+ }
+
+//---------------------------------------------------------
+// apply
+//---------------------------------------------------------
+
+void MidiControllerEditDialog::apply()
+{
+ int mpidx = midiPortsList->currentItem();
+ //MidiControllerList* mcl;
+ MidiInstrument* mi = midiPorts[mpidx].instrument();
+ //if(mi)
+ MidiControllerList* mcl = mi->controller();
+ //else
+ // mcl = &defaultMidiController;
+ mcl->clear();
+
+
+ Q3ListViewItem* item = viewController->firstChild();
+ int hval;
+ int lval;
+ while (item) {
+ hval = item->text(COL_HNUM).toInt();
+ lval = item->text(COL_LNUM).toInt();
+ MidiController* c = new MidiController();
+ c->setName(item->text(COL_NAME));
+
+ MidiController::ControllerType type = ctrlType2Int(item->text(COL_TYPE));
+
+ switch(type) {
+ case MidiController::Controller7:
+ c->setNum(lval);
+ break;
+ case MidiController::Controller14:
+ c->setNum((hval << 8 | lval) | CTRL_14_OFFSET);
+ break;
+ case MidiController::RPN:
+ c->setNum((hval << 8 | lval) | CTRL_RPN_OFFSET);
+ break;
+ case MidiController::NRPN:
+ c->setNum((hval << 8 | lval) | CTRL_NRPN_OFFSET);
+ break;
+ case MidiController::RPN14:
+ c->setNum((hval << 8 | lval) | CTRL_RPN14_OFFSET);
+ break;
+ case MidiController::NRPN14:
+ c->setNum((hval << 8 | lval) | CTRL_NRPN14_OFFSET);
+ break;
+ case MidiController::Program:
+ c->setNum(CTRL_PROGRAM);
+ break;
+ case MidiController::Pitch:
+ c->setNum(CTRL_PITCH);
+ break;
+ default:
+ break;
+ }
+ if(type == MidiController::Program)
+ {
+ c->setMinVal(0);
+ c->setMaxVal(0xffffff);
+ }
+ else
+ {
+ c->setMinVal(item->text(COL_MIN).toInt());
+ c->setMaxVal(item->text(COL_MAX).toInt());
+ }
+
+ mcl->push_back(c);
+
+ item = item->nextSibling();
+ }
+
+ // Update the list before closing this dialog.
+ //updateViewController();
+ //setModified(false);
+ song->update(SC_CONFIG | SC_MIDI_CONTROLLER);
+}
+
+//---------------------------------------------------------
+// ctrlAdd
+//---------------------------------------------------------
+
+void MidiControllerEditDialog::ctrlAdd()
+ {
+ Q3ListBoxItem* item = listController->selectedItem();
+ if (item == 0)
+ return;
+ QString name = item->text();
+ int size = sizeof(predefinedMidiController) / sizeof(*predefinedMidiController);
+ for (int i = 0; i < size; ++i) {
+ MidiController* c = &predefinedMidiController[i];
+ if (c->name() != name)
+ continue;
+ MidiController::ControllerType t = midiControllerType(c->num());
+ QString type = int2ctrlType(t);
+ QString min, max;
+ QString hno, lno;
+ int h = (c->num() >> 8) & 0x7f;
+ int l = c->num() & 0x7f;
+
+ switch(t) {
+ case MidiController::Controller7:
+ min.setNum(c->minVal());
+ max.setNum(c->maxVal());
+ hno = "---";
+ lno.setNum(l);
+ break;
+ case MidiController::RPN:
+ case MidiController::NRPN:
+ case MidiController::RPN14:
+ case MidiController::NRPN14:
+ case MidiController::Controller14:
+ min.setNum(c->minVal());
+ max.setNum(c->maxVal());
+ hno.setNum(h);
+ lno.setNum(l);
+ break;
+ case MidiController::Pitch:
+ min.setNum(c->minVal());
+ max.setNum(c->maxVal());
+ hno = "---";
+ lno = "---";
+ break;
+ default:
+ hno = "---";
+ lno = "---";
+ min.setNum(0);
+ max.setNum(0);
+ break;
+ }
+
+ Q3ListViewItem* item = new Q3ListViewItem(viewController,
+ name, type, hno, lno, min, max);
+
+ viewController->blockSignals(true);
+ viewController->setCurrentItem(item);
+ controllerChanged(item);
+ viewController->blockSignals(false);
+
+ setModified(true);
+ break;
+ }
+ }
+
+//---------------------------------------------------------
+// ctrlDelete
+//---------------------------------------------------------
+
+void MidiControllerEditDialog::ctrlDelete()
+ {
+ Q3ListViewItem* item = viewController->currentItem();
+ if (item == 0)
+ return;
+ delete item;
+
+ setModified(true);
+ }
+
+//---------------------------------------------------------
+// accept
+//---------------------------------------------------------
+
+void MidiControllerEditDialog::accept()
+ {
+ apply();
+ MidiControllerEditDialogBase::accept();
+ }
+
+//---------------------------------------------------------
+// portChanged
+//---------------------------------------------------------
+
+void MidiControllerEditDialog::portChanged(int n)
+ {
+ if(n == _lastPort)
+ return;
+ _lastPort = n;
+
+ //listController->blockSignals(true);
+ //midiPortsList->blockSignals(true);
+ //viewController->blockSignals(true);
+ //updatePredefinedList();
+ //updateMidiPortsList();
+ //reject(); // populate list
+ updateViewController();
+ //viewController->setCurrentItem(viewController->firstChild());
+ //controllerChanged(viewController->currentItem());
+ //listController->blockSignals(false);
+ //midiPortsList->blockSignals(false);
+ //viewController->blockSignals(false);
+ }
+
+//---------------------------------------------------------
+// nameChanged
+//---------------------------------------------------------
+
+void MidiControllerEditDialog::nameChanged(const QString& s)
+ {
+ Q3ListViewItem* item = viewController->currentItem();
+ if (item == 0)
+ return;
+ item->setText(COL_NAME, s);
+
+ setModified(true);
+ }
+
+//---------------------------------------------------------
+// typeChanged
+//---------------------------------------------------------
+
+void MidiControllerEditDialog::typeChanged(const QString& s)
+ {
+ Q3ListViewItem* item = viewController->currentItem();
+ if (item == 0)
+ return;
+ item->setText(COL_TYPE, s);
+ switch(ctrlType2Int(s)) {
+ case MidiController::Controller14:
+ case MidiController::RPN14:
+ case MidiController::NRPN14:
+ item->setText(COL_LNUM, QString("0"));
+ item->setText(COL_HNUM, QString("0"));
+ item->setText(COL_MIN, QString("0"));
+ item->setText(COL_MAX, QString("16383"));
+ break;
+ case MidiController::Controller7:
+ item->setText(COL_MIN, QString("0"));
+ item->setText(COL_MAX, QString("127"));
+ item->setText(COL_LNUM, QString("0"));
+ item->setText(COL_HNUM, QString("---"));
+ break;
+ case MidiController::RPN:
+ case MidiController::NRPN:
+ item->setText(COL_MIN, QString("0"));
+ item->setText(COL_MAX, QString("127"));
+ item->setText(COL_LNUM, QString("0"));
+ item->setText(COL_HNUM, QString("0"));
+ break;
+
+ case MidiController::Program:
+
+ item->setText(COL_MIN, QString("---"));
+ item->setText(COL_MAX, QString("---"));
+ item->setText(COL_LNUM, QString("---"));
+ item->setText(COL_HNUM, QString("---"));
+ break;
+ case MidiController::Pitch:
+ item->setText(COL_MIN, QString("-8192"));
+ item->setText(COL_MAX, QString("8191"));
+ item->setText(COL_LNUM, QString("---"));
+ item->setText(COL_HNUM, QString("---"));
+ break;
+ default:
+ break;
+ }
+
+ setModified(true);
+
+ controllerChanged(item);
+ }
+
+//---------------------------------------------------------
+// valueHChanged
+//---------------------------------------------------------
+
+void MidiControllerEditDialog::valueHChanged(int val)
+ {
+ Q3ListViewItem* item = viewController->currentItem();
+ if (item == 0)
+ return;
+ QString s;
+ s.setNum(val);
+ item->setText(COL_HNUM, s);
+
+ setModified(true);
+ }
+
+//---------------------------------------------------------
+// valueLChanged
+//---------------------------------------------------------
+
+void MidiControllerEditDialog::valueLChanged(int val)
+ {
+ Q3ListViewItem* item = viewController->currentItem();
+ if (item == 0)
+ return;
+ QString s;
+ s.setNum(val);
+ item->setText(COL_LNUM, s);
+
+ setModified(true);
+ }
+
+//---------------------------------------------------------
+// controllerChanged
+//---------------------------------------------------------
+
+void MidiControllerEditDialog::controllerChanged()
+ {
+ Q3ListViewItem* item = viewController->selectedItem();
+ controllerChanged(item);
+ }
+
+void MidiControllerEditDialog::controllerChanged(Q3ListViewItem* item)
+ {
+ if (item == 0) {
+ entryName->setEnabled(false);
+ comboType->setEnabled(false);
+ spinboxHCtrlNo->setEnabled(false);
+ spinboxLCtrlNo->setEnabled(false);
+ spinboxMin->setEnabled(false);
+ spinboxMax->setEnabled(false);
+ return;
+ }
+
+ entryName->blockSignals(true);
+ comboType->blockSignals(true);
+ spinboxHCtrlNo->blockSignals(true);
+ spinboxLCtrlNo->blockSignals(true);
+ spinboxMin->blockSignals(true);
+ spinboxMax->blockSignals(true);
+
+ entryName->setEnabled(true);
+ entryName->setText(item->text(COL_NAME));
+ comboType->setCurrentItem(int(ctrlType2Int(item->text(COL_TYPE))));
+ switch (ctrlType2Int(item->text(COL_TYPE))) {
+ case MidiController::Controller7:
+ comboType->setEnabled(true);
+ spinboxHCtrlNo->setEnabled(false);
+ spinboxLCtrlNo->setEnabled(true);
+ spinboxMin->setEnabled(true);
+ spinboxMax->setEnabled(true);
+ spinboxHCtrlNo->setValue(0);
+ spinboxLCtrlNo->setValue(item->text(COL_LNUM).toInt());
+ spinboxMin->setRange(0, 127);
+ spinboxMax->setRange(0, 127);
+ spinboxMin->setValue(item->text(COL_MIN).toInt());
+ spinboxMax->setValue(item->text(COL_MAX).toInt());
+ break;
+
+ case MidiController::RPN:
+ case MidiController::NRPN:
+ comboType->setEnabled(true);
+ spinboxHCtrlNo->setEnabled(true);
+ spinboxLCtrlNo->setEnabled(true);
+ spinboxMin->setEnabled(true);
+ spinboxMax->setEnabled(true);
+ spinboxHCtrlNo->setValue(item->text(COL_HNUM).toInt());
+ spinboxLCtrlNo->setValue(item->text(COL_LNUM).toInt());
+ spinboxMin->setRange(0, 127);
+ spinboxMax->setRange(0, 127);
+ spinboxMin->setValue(item->text(COL_MIN).toInt());
+ spinboxMax->setValue(item->text(COL_MAX).toInt());
+ break;
+ case MidiController::Controller14:
+ case MidiController::RPN14:
+ case MidiController::NRPN14:
+ comboType->setEnabled(true);
+ spinboxHCtrlNo->setEnabled(true);
+ spinboxLCtrlNo->setEnabled(true);
+ spinboxMin->setEnabled(true);
+ spinboxMax->setEnabled(true);
+
+ spinboxHCtrlNo->setValue(item->text(COL_HNUM).toInt());
+ spinboxLCtrlNo->setValue(item->text(COL_LNUM).toInt());
+ spinboxMin->setRange(0, 16383);
+ spinboxMax->setRange(0, 16383);
+ spinboxMin->setValue(item->text(COL_MIN).toInt());
+ spinboxMax->setValue(item->text(COL_MAX).toInt());
+ break;
+
+ case MidiController::Pitch:
+ comboType->setEnabled(true);
+ spinboxHCtrlNo->setEnabled(false);
+ spinboxLCtrlNo->setEnabled(false);
+ spinboxMin->setEnabled(true);
+ spinboxMax->setEnabled(true);
+ spinboxHCtrlNo->setValue(0);
+ spinboxLCtrlNo->setValue(0);
+ spinboxMin->setRange(-8192, 8191);
+ spinboxMax->setRange(-8192, 8191);
+ spinboxMin->setValue(item->text(COL_MIN).toInt());
+ spinboxMax->setValue(item->text(COL_MAX).toInt());
+ break;
+
+ case MidiController::Program:
+ comboType->setEnabled(true);
+ spinboxHCtrlNo->setEnabled(false);
+ spinboxLCtrlNo->setEnabled(false);
+ spinboxMin->setEnabled(false);
+ spinboxMax->setEnabled(false);
+ spinboxHCtrlNo->setValue(0);
+ spinboxLCtrlNo->setValue(0);
+ spinboxMin->setRange(0, 0);
+ spinboxMax->setRange(0, 0);
+ spinboxMin->setValue(0);
+ spinboxMax->setValue(0);
+ break;
+ default:
+ break;
+ }
+ entryName->blockSignals(false);
+ comboType->blockSignals(false);
+ spinboxHCtrlNo->blockSignals(false);
+ spinboxLCtrlNo->blockSignals(false);
+ spinboxMin->blockSignals(false);
+ spinboxMax->blockSignals(false);
+ }
+
+//---------------------------------------------------------
+// minChanged
+//---------------------------------------------------------
+
+void MidiControllerEditDialog::minChanged(int val)
+ {
+ Q3ListViewItem* item = viewController->currentItem();
+ if (item == 0)
+ return;
+
+ QString s;
+ s.setNum(val);
+ item->setText(COL_MIN, s);
+
+ if(val > item->text(COL_MAX).toInt())
+ {
+ spinboxMax->blockSignals(true);
+ spinboxMax->setValue(val);
+ item->setText(COL_MAX, s);
+ spinboxMax->blockSignals(false);
+ }
+ setModified(true);
+ }
+
+//---------------------------------------------------------
+// maxChanged
+//---------------------------------------------------------
+
+void MidiControllerEditDialog::maxChanged(int val)
+ {
+ Q3ListViewItem* item = viewController->currentItem();
+ if (item == 0)
+ return;
+
+ QString s;
+ s.setNum(val);
+ item->setText(COL_MAX, s);
+
+ if(val < item->text(COL_MIN).toInt())
+ {
+ spinboxMin->blockSignals(true);
+ spinboxMin->setValue(val);
+ item->setText(COL_MIN, s);
+ spinboxMin->blockSignals(false);
+ }
+ setModified(true);
+ }
+
+//---------------------------------------------------------
+// configMidiController
+//---------------------------------------------------------
+
+void configMidiController()
+ {
+ if (midiControllerEditDialog == 0)
+ {
+ midiControllerEditDialog = new MidiControllerEditDialog();
+ midiControllerEditDialog->show();
+ }
+ else
+ {
+ if(midiControllerEditDialog->isShown())
+ midiControllerEditDialog->hide();
+ else
+ midiControllerEditDialog->show();
+ }
+ }
diff --git a/attic/muse2-oom/muse2/muse/instruments/midictrledit.h b/attic/muse2-oom/muse2/muse/instruments/midictrledit.h
new file mode 100644
index 00000000..e1624f29
--- /dev/null
+++ b/attic/muse2-oom/muse2/muse/instruments/midictrledit.h
@@ -0,0 +1,56 @@
+//=========================================================
+// MusE
+// Linux Music Editor
+// $Id: midictrledit.h,v 1.1.1.1.2.1 2008/08/18 00:15:25 terminator356 Exp $
+//
+// (C) Copyright 1999/2000 Werner Schweer (ws@seh.de)
+//=========================================================
+
+#ifndef __MIDICTRLEDIT_H__
+#define __MIDICTRLEDIT_H__
+
+#include "ccontrolbase.h"
+#include "midictrl.h"
+
+//---------------------------------------------------------
+// MidiControllerEditDialog
+//---------------------------------------------------------
+
+class MidiControllerEditDialog : public MidiControllerEditDialogBase {
+ Q_OBJECT
+
+ int _lastPort;
+ bool _modified;
+
+ void addControllerToView(MidiController* mctrl);
+ void mergeReplace(bool replace);
+ void updatePredefinedList();
+ void updateMidiPortsList();
+ void updateViewController();
+ void setModified(bool);
+
+ private slots:
+ void ctrlAdd();
+ void ctrlDelete();
+ virtual void accept();
+ virtual void reject();
+ void apply();
+ void nameChanged(const QString&);
+ void typeChanged(const QString&);
+ void valueHChanged(int);
+ void valueLChanged(int);
+ void controllerChanged(Q3ListViewItem*);
+ void controllerChanged();
+ void minChanged(int);
+ void maxChanged(int);
+ void portChanged(int);
+ void songChanged(int);
+
+ public:
+ MidiControllerEditDialog(QWidget* parent = 0, const char* name = 0, bool modal = false, Qt::WFlags fl = 0);
+ };
+
+extern MidiControllerEditDialog* midiControllerEditDialog;
+extern void configMidiController();
+#endif
+
diff --git a/attic/muse2-oom/muse2/muse/instruments/minstrument.cpp b/attic/muse2-oom/muse2/muse/instruments/minstrument.cpp
new file mode 100644
index 00000000..8df7d4c7
--- /dev/null
+++ b/attic/muse2-oom/muse2/muse/instruments/minstrument.cpp
@@ -0,0 +1,927 @@
+//=========================================================
+// MusE
+// Linux Music Editor
+// $Id: minstrument.cpp,v 1.10.2.5 2009/03/28 01:46:10 terminator356 Exp $
+//
+// (C) Copyright 2000-2003 Werner Schweer (ws@seh.de)
+//=========================================================
+
+#include <stdio.h>
+
+#include <QAction>
+#include <QDir>
+#include <QFileInfo>
+#include <QMenu>
+#include <QMessageBox>
+#include <QList>
+
+#include "minstrument.h"
+#include "midiport.h"
+#include "globals.h"
+#include "xml.h"
+#include "event.h"
+#include "mpevent.h"
+#include "midictrl.h"
+#include "gconfig.h"
+
+MidiInstrumentList midiInstruments;
+MidiInstrument* genericMidiInstrument;
+
+static const char* gmdrumname = "GM-drums";
+
+//---------------------------------------------------------
+// string2sysex
+//---------------------------------------------------------
+
+int string2sysex(const QString& s, unsigned char** data)
+ {
+ QByteArray ba = s.toLatin1();
+ const char* src = ba.constData();
+ char buffer[2048];
+ char* dst = buffer;
+
+ if(src) {
+ while (*src) {
+ while (*src == ' ' || *src == '\n') {
+ ++src;
+ }
+ char* ep;
+ long val = strtol(src, &ep, 16);
+ if (ep == src) {
+ QMessageBox::information(0,
+ QString("MusE"),
+ QWidget::tr("Cannot convert sysex string"));
+ return 0;
+ }
+ src = ep;
+ *dst++ = val;
+ if (dst - buffer >= 2048) {
+ QMessageBox::information(0,
+ QString("MusE"),
+ QWidget::tr("Hex String too long (2048 bytes limit)"));
+ return 0;
+ }
+ }
+ }
+ int len = dst - buffer;
+ unsigned char* b = new unsigned char[len+1];
+ memcpy(b, buffer, len);
+ b[len] = 0;
+ *data = b;
+ return len;
+ }
+
+//---------------------------------------------------------
+// sysex2string
+//---------------------------------------------------------
+
+QString sysex2string(int len, unsigned char* data)
+ {
+ QString d;
+ QString s;
+ for (int i = 0; i < len; ++i) {
+ if ((i > 0) && ((i % 8)==0)) {
+ d += "\n";
+ }
+ else if (i)
+ d += " ";
+ d += s.sprintf("%02x", data[i]);
+ }
+ return d;
+ }
+
+//---------------------------------------------------------
+// readEventList
+//---------------------------------------------------------
+
+static void readEventList(Xml& xml, EventList* el, const char* name)
+ {
+ for (;;) {
+ Xml::Token token = xml.parse();
+ const QString& tag = xml.s1();
+ switch (token) {
+ case Xml::Error:
+ case Xml::End:
+ return;
+ case Xml::TagStart:
+ if (tag == "event") {
+ Event e(Note);
+ e.read(xml);
+ el->add(e);
+ }
+ else
+ xml.unknown("readEventList");
+ break;
+ case Xml::TagEnd:
+ if (tag == name)
+ return;
+ default:
+ break;
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// read
+//---------------------------------------------------------
+
+//---------------------------------------------------------
+// loadIDF
+//---------------------------------------------------------
+
+static void loadIDF(QFileInfo* fi)
+ {
+/*
+ QFile qf(fi->filePath());
+ if (!qf.open(IO_ReadOnly)) {
+ printf("cannot open file %s\n", fi->fileName().toLatin1());
+ return;
+ }
+ if (debugMsg)
+ printf(" load instrument definition <%s>\n", fi->filePath().local8Bit().data());
+ QDomDocument doc;
+ int line, column;
+ QString err;
+ if (!doc.setContent(&qf, false, &err, &line, &column)) {
+ QString col, ln, error;
+ col.setNum(column);
+ ln.setNum(line);
+ error = err + " at line: " + ln + " col: " + col;
+ printf("error reading file <%s>:\n %s\n",
+ fi->filePath().toLatin1(), error.toLatin1());
+ return;
+ }
+ QDomNode node = doc.documentElement();
+ while (!node.isNull()) {
+ QDomElement e = node.toElement();
+ if (e.isNull())
+ continue;
+ if (e.tagName() == "muse") {
+ QString version = e.attribute(QString("version"));
+ for (QDomNode n = node.firstChild(); !n.isNull(); n = n.nextSibling()) {
+ QDomElement e = n.toElement();
+ if (e.tagName() == "MidiInstrument") {
+ MidiInstrument* i = new MidiInstrument();
+ i->read(n);
+ i->setFilePath(fi->filePath());
+ bool replaced = false;
+ for (int idx = 0; idx < midiInstruments.size(); ++idx) {
+ if (midiInstruments[idx]->iname() == i->iname()) {
+ midiInstruments.replace(idx, i);
+ replaced = true;
+ if (debugMsg)
+ printf("Midi Instrument Definition <%s> overwritten\n",
+ i->iname().toLocal8Bit().data());
+ break;
+ }
+ }
+ if (!replaced)
+ midiInstruments += i;
+ }
+ }
+ }
+ else
+ printf("MusE:laodIDF: %s not supported\n", e.tagName().toLatin1());
+ node = node.nextSibling();
+ }
+ qf.close();
+*/
+
+ FILE* f = fopen(fi->filePath().toAscii().constData(), "r");
+ if (f == 0)
+ return;
+ if (debugMsg)
+ printf("READ IDF %s\n", fi->filePath().toLatin1().constData());
+ Xml xml(f);
+
+ bool skipmode = true;
+ for (;;) {
+ Xml::Token token = xml.parse();
+ const QString& tag = xml.s1();
+ switch (token) {
+ case Xml::Error:
+ case Xml::End:
+ return;
+ case Xml::TagStart:
+ if (skipmode && tag == "muse")
+ skipmode = false;
+ else if (skipmode)
+ break;
+ else if (tag == "MidiInstrument") {
+ MidiInstrument* i = new MidiInstrument();
+ i->setFilePath(fi->filePath());
+ i->read(xml);
+ // Ignore duplicate named instruments.
+ iMidiInstrument ii = midiInstruments.begin();
+ for(; ii != midiInstruments.end(); ++ii)
+ {
+ if((*ii)->iname() == i->iname())
+ break;
+ }
+ if(ii == midiInstruments.end())
+ midiInstruments.push_back(i);
+ else
+ delete i;
+ }
+ else
+ xml.unknown("muse");
+ break;
+ case Xml::Attribut:
+ break;
+ case Xml::TagEnd:
+ if (!skipmode && tag == "muse") {
+ return;
+ }
+ default:
+ break;
+ }
+ }
+ fclose(f);
+
+
+ }
+
+//---------------------------------------------------------
+// initMidiInstruments
+//---------------------------------------------------------
+
+void initMidiInstruments()
+ {
+ genericMidiInstrument = new MidiInstrument(QWidget::tr("generic midi"));
+ midiInstruments.push_back(genericMidiInstrument);
+ if (debugMsg)
+ printf("load user instrument definitions from <%s>\n", museUserInstruments.toLatin1().constData());
+ QDir usrInstrumentsDir(museUserInstruments, QString("*.idf"));
+ if (usrInstrumentsDir.exists()) {
+ QFileInfoList list = usrInstrumentsDir.entryInfoList();
+ QFileInfoList::iterator it=list.begin(); // ddskrjo
+ while(it != list.end()) { // ddskrjo
+ loadIDF(&*it);
+ ++it;
+ }
+ }
+ //else
+ //{
+ // if(usrInstrumentsDir.mkdir(museUserInstruments))
+ // printf("Created user instrument directory: %s\n", museUserInstruments.toLatin1());
+ // else
+ // printf("Unable to create user instrument directory: %s\n", museUserInstruments.toLatin1());
+ //}
+
+ if (debugMsg)
+ printf("load instrument definitions from <%s>\n", museInstruments.toLatin1().constData());
+ QDir instrumentsDir(museInstruments, QString("*.idf"));
+ if (instrumentsDir.exists()) {
+ QFileInfoList list = instrumentsDir.entryInfoList();
+ QFileInfoList::iterator it=list.begin(); // ddskrjo
+ while(it!=list.end()) {
+ loadIDF(&*it);
+ ++it;
+ }
+ }
+ else
+ printf("Instrument directory not found: %s\n", museInstruments.toLatin1().constData());
+
+ }
+
+//---------------------------------------------------------
+// registerMidiInstrument
+//---------------------------------------------------------
+
+MidiInstrument* registerMidiInstrument(const QString& name)
+ {
+ for (iMidiInstrument i = midiInstruments.begin();
+ i != midiInstruments.end(); ++i) {
+ if ((*i)->iname() == name)
+ return *i;
+ }
+ return genericMidiInstrument;
+ }
+
+//---------------------------------------------------------
+// removeMidiInstrument
+//---------------------------------------------------------
+
+void removeMidiInstrument(const QString& name)
+ {
+ for (iMidiInstrument i = midiInstruments.begin();
+ i != midiInstruments.end(); ++i) {
+ if ((*i)->iname() == name) {
+ midiInstruments.erase(i);
+ return;
+ }
+ }
+ }
+
+void removeMidiInstrument(const MidiInstrument* instr)
+ {
+ for (iMidiInstrument i = midiInstruments.begin();
+ i != midiInstruments.end(); ++i) {
+ if (*i == instr) {
+ midiInstruments.erase(i);
+ return;
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// MidiInstrument
+//---------------------------------------------------------
+
+void MidiInstrument::init()
+ {
+ _nullvalue = -1;
+ _initScript = 0;
+ _midiInit = new EventList();
+ _midiReset = new EventList();
+ _midiState = new EventList();
+ _controller = new MidiControllerList;
+
+ // add some default controller to controller list
+ // this controllers are always available for all instruments
+ //
+ MidiController* prog = new MidiController("Program", CTRL_PROGRAM, 0, 0xffffff, 0);
+ _controller->add(prog);
+ _dirty = false;
+ }
+
+MidiInstrument::MidiInstrument()
+ {
+ init();
+ }
+
+//---------------------------------------------------------
+// MidiInstrument
+//---------------------------------------------------------
+
+MidiInstrument::MidiInstrument(const QString& txt)
+ {
+ _name = txt;
+ init();
+ }
+
+//---------------------------------------------------------
+// MidiInstrument
+//---------------------------------------------------------
+
+MidiInstrument::~MidiInstrument()
+ {
+ for (ciPatchGroup g = pg.begin(); g != pg.end(); ++g)
+ {
+ PatchGroup* pgp = *g;
+ const PatchList& pl = pgp->patches;
+ for (ciPatch p = pl.begin(); p != pl.end(); ++p)
+ {
+ delete *p;
+ }
+ delete pgp;
+ }
+
+
+ delete _midiInit;
+ delete _midiReset;
+ delete _midiState;
+ for(iMidiController i = _controller->begin(); i != _controller->end(); ++i)
+ delete i->second;
+ delete _controller;
+
+ if (_initScript)
+ delete _initScript;
+ }
+
+/*
+//---------------------------------------------------------
+// uniqueCopy
+//---------------------------------------------------------
+
+MidiInstrument& MidiInstrument::uniqueCopy(const MidiInstrument& ins)
+{
+ _initScript = 0;
+ _midiInit = new EventList();
+ _midiReset = new EventList();
+ _midiState = new EventList();
+ //---------------------------------------------------------
+ // TODO: Copy the init script, and the lists.
+ //---------------------------------------------------------
+ _controller = new MidiControllerList(*(ins._controller));
+
+ // Assignment
+ pg = ins.pg;
+
+ _name = ins._name;
+ _filePath = ins._filePath;
+
+ // Hmm, dirty, yes? But init sets it to false...
+ //_dirty = ins._dirty;
+ //_dirty = false;
+ _dirty = true;
+
+ return *this;
+}
+*/
+
+//---------------------------------------------------------
+// assign
+//---------------------------------------------------------
+
+MidiInstrument& MidiInstrument::assign(const MidiInstrument& ins)
+{
+ //---------------------------------------------------------
+ // TODO: Copy the _initScript, and _midiInit, _midiReset, and _midiState lists.
+ //---------------------------------------------------------
+
+ for(iMidiController i = _controller->begin(); i != _controller->end(); ++i)
+ delete i->second;
+ _controller->clear();
+
+ _nullvalue = ins._nullvalue;
+
+ // Assignment
+ // *_controller = *(ins._controller);
+ for(ciMidiController i = ins._controller->begin(); i != ins._controller->end(); ++i)
+ {
+ MidiController* mc = i->second;
+ _controller->add(new MidiController(*mc));
+ }
+
+// pg.clear();
+// for(iPatchGroup ipg = pg.begin(); ipg != pg.end(); ++ipg)
+// {
+ //ipg->patches.clear();
+
+ //const PatchGroup& g = *ipg;
+ //for(ciPatch ip = ipg->begin(); ip != ipg->end(); ++ipg)
+ //{
+
+ //}
+// }
+
+ for (ciPatchGroup g = pg.begin(); g != pg.end(); ++g)
+ {
+ PatchGroup* pgp = *g;
+ const PatchList& pl = pgp->patches;
+ for (ciPatch p = pl.begin(); p != pl.end(); ++p)
+ {
+ delete *p;
+ }
+
+ delete pgp;
+ }
+ pg.clear();
+
+ // Assignment
+// pg = ins.pg;
+ for(ciPatchGroup g = ins.pg.begin(); g != ins.pg.end(); ++g)
+ {
+ PatchGroup* pgp = *g;
+ const PatchList& pl = pgp->patches;
+ PatchGroup* npg = new PatchGroup;
+ npg->name = pgp->name;
+ pg.push_back(npg);
+ for (ciPatch p = pl.begin(); p != pl.end(); ++p)
+ {
+ Patch* pp = *p;
+ Patch* np = new Patch;
+ np->typ = pp->typ;
+ np->hbank = pp->hbank;
+ np->lbank = pp->lbank;
+ np->prog = pp->prog;
+ np->name = pp->name;
+ np->drum = pp->drum;
+ npg->patches.push_back(np);
+ }
+ }
+
+ _name = ins._name;
+ _filePath = ins._filePath;
+
+ // Hmm, dirty, yes? But init sets it to false...
+ //_dirty = ins._dirty;
+ //_dirty = false;
+ //_dirty = true;
+
+ return *this;
+}
+
+//---------------------------------------------------------
+// reset
+// send note off to all channels
+//---------------------------------------------------------
+
+void MidiInstrument::reset(int portNo, MType)
+ {
+ MidiPlayEvent ev;
+ ev.setType(0x90);
+ MidiPort* port = &midiPorts[portNo];
+ if (port == 0)
+ return;
+ ev.setPort(portNo);
+ for (int chan = 0; chan < MIDI_CHANNELS; ++chan) {
+ ev.setChannel(chan);
+ for (int pitch = 0; pitch < 128; ++pitch) {
+ ev.setA(pitch);
+ ev.setB(0);
+ port->sendEvent(ev);
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// readPatchGroup
+//---------------------------------------------------------
+
+void PatchGroup::read(Xml& xml)
+ {
+ for (;;) {
+ Xml::Token token = xml.parse();
+ const QString& tag = xml.s1();
+ switch (token) {
+ case Xml::Error:
+ case Xml::End:
+ return;
+ case Xml::TagStart:
+ if (tag == "Patch") {
+ Patch* patch = new Patch;
+ patch->read(xml);
+ patches.push_back(patch);
+ }
+ else
+ xml.unknown("PatchGroup");
+ break;
+ case Xml::Attribut:
+ if (tag == "name")
+ name = xml.s2();
+ break;
+ case Xml::TagEnd:
+ if (tag == "PatchGroup")
+ return;
+ default:
+ break;
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// read
+//---------------------------------------------------------
+
+void Patch::read(Xml& xml)
+ {
+ typ = -1;
+ hbank = -1;
+ lbank = -1;
+ prog = 0;
+ drum = false;
+ for (;;) {
+ Xml::Token token = xml.parse();
+ const QString& tag = xml.s1();
+ switch (token) {
+ case Xml::Error:
+ case Xml::End:
+ return;
+ case Xml::TagStart:
+ xml.unknown("Patch");
+ break;
+ case Xml::Attribut:
+ if (tag == "name")
+ name = xml.s2();
+ else if (tag == "mode")
+ typ = xml.s2().toInt();
+ else if (tag == "hbank")
+ hbank = xml.s2().toInt();
+ else if (tag == "lbank")
+ lbank = xml.s2().toInt();
+ else if (tag == "prog")
+ prog = xml.s2().toInt();
+ else if (tag == "drum")
+ drum = xml.s2().toInt();
+ break;
+ case Xml::TagEnd:
+ if (tag == "Patch")
+ return;
+ default:
+ break;
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// write
+//---------------------------------------------------------
+
+void Patch::write(int level, Xml& xml)
+ {
+ //if (drumMap == 0)
+ //{
+ //QString s = QString("Patch name=\"%1\"").arg(Xml::xmlString(name));
+ //if (typ != -1)
+ // s += QString(" mode=\"%d\"").arg(typ);
+ //s += QString(" hbank=\"%1\" lbank=\"%2\" prog=\"%3\"").arg(hbank).arg(lbank).arg(prog);
+ //xml.tagE(s);
+ xml.nput(level, "<Patch name=\"%s\"", Xml::xmlString(name).toLatin1().constData());
+ if(typ != -1)
+ xml.nput(" mode=\"%d\"", typ);
+
+ if(hbank != -1)
+ xml.nput(" hbank=\"%d\"", hbank);
+
+ if(lbank != -1)
+ xml.nput(" lbank=\"%d\"", lbank);
+
+ xml.nput(" prog=\"%d\"", prog);
+
+ //xml.nput(level, " hbank=\"%d\" lbank=\"%d\" prog=\"%d\"", hbank, lbank, prog);
+ if(drum)
+ //xml.nput(level, " drum=\"%d\"", int(drum));
+ xml.nput(" drum=\"%d\"", int(drum));
+ //xml.put(level, " />");
+ xml.put(" />");
+
+ //return;
+ //}
+
+ //QString s = QString("drummap name=\"%1\"").arg(Xml::xmlString(name));
+ //s += QString(" hbank=\"%1\" lbank=\"%2\" prog=\"%3\"").arg(hbank).arg(lbank).arg(prog);
+ //xml.stag(s);
+ //for (int i = 0; i < DRUM_MAPSIZE; ++i) {
+ // DrumMapEntry* dm = drumMap->entry(i);
+ // dm->write(xml);
+ // }
+ //xml.etag("drummap");
+ }
+
+//---------------------------------------------------------
+// readMidiState
+//---------------------------------------------------------
+
+void MidiInstrument::readMidiState(Xml& xml)
+ {
+ _midiState->read(xml, "midistate", true);
+ }
+
+//---------------------------------------------------------
+// read
+//---------------------------------------------------------
+
+void MidiInstrument::read(Xml& xml)
+ {
+ bool ok;
+ int base = 10;
+ _nullvalue = -1;
+ for (;;) {
+ Xml::Token token = xml.parse();
+ const QString& tag = xml.s1();
+ switch (token) {
+ case Xml::Error:
+ case Xml::End:
+ return;
+ case Xml::TagStart:
+ if (tag == "Patch") {
+ Patch* patch = new Patch;
+ patch->read(xml);
+ if (pg.empty()) {
+ PatchGroup* p = new PatchGroup;
+ p->patches.push_back(patch);
+ pg.push_back(p);
+ }
+ else
+ pg[0]->patches.push_back(patch);
+ }
+ else if (tag == "PatchGroup") {
+ PatchGroup* p = new PatchGroup;
+ p->read(xml);
+ pg.push_back(p);
+ }
+ else if (tag == "Controller") {
+ MidiController* mc = new MidiController();
+ mc->read(xml);
+ // Added by Tim. Copied from muse 2.
+ //
+ // HACK: make predefined "Program" controller overloadable
+ //
+ if (mc->name() == "Program") {
+ for (iMidiController i = _controller->begin(); i != _controller->end(); ++i) {
+ if (i->second->name() == mc->name()) {
+ delete i->second;
+ _controller->erase(i);
+ break;
+ }
+ }
+ }
+
+ _controller->add(mc);
+ }
+ else if (tag == "Init")
+ readEventList(xml, _midiInit, "Init");
+ else if (tag == "Reset")
+ readEventList(xml, _midiReset, "Reset");
+ else if (tag == "State")
+ readEventList(xml, _midiState, "State");
+ else if (tag == "InitScript") {
+ if (_initScript)
+ delete _initScript;
+ QByteArray ba = xml.parse1().toLatin1();
+ const char* istr = ba.constData();
+ int len = strlen(istr) +1;
+ if (len > 1) {
+ _initScript = new char[len];
+ memcpy(_initScript, istr, len);
+ }
+ }
+
+ else
+ xml.unknown("MidiInstrument");
+ break;
+ case Xml::Attribut:
+ if (tag == "name")
+ setIName(xml.s2());
+ else if(tag == "nullparam") {
+ _nullvalue = xml.s2().toInt(&ok, base);
+ }
+ break;
+ case Xml::TagEnd:
+ if (tag == "MidiInstrument")
+ return;
+ default:
+ break;
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// write
+//---------------------------------------------------------
+
+void MidiInstrument::write(int level, Xml& xml)
+ {
+ xml.header();
+ //xml.stag("muse version=\"2.1\"");
+ xml.tag(level, "muse version=\"1.0\"");
+ //xml.stag(QString("MidiInstrument name=\"%1\"").arg(Xml::xmlString(iname())));
+ level++;
+ //xml.tag(level, "MidiInstrument name=\"%s\"", Xml::xmlString(iname()).toLatin1().constData());
+ xml.nput(level, "<MidiInstrument name=\"%s\"", Xml::xmlString(iname()).toLatin1().constData());
+
+ if(_nullvalue != -1)
+ {
+ QString nv;
+ nv.setNum(_nullvalue);
+ xml.nput(" nullparam=\"%s\"", nv.toLatin1().constData());
+ }
+ xml.put(">");
+
+ // -------------
+ // What about Init, Reset, State, and InitScript ?
+ // -------------
+
+ //std::vector<PatchGroup>* pg = groups();
+ //for (std::vector<PatchGroup>::iterator g = pg->begin(); g != pg->end(); ++g) {
+ level++;
+ //for (std::vector<PatchGroup>::iterator g = pg.begin(); g != pg.end(); ++g) {
+ for (ciPatchGroup g = pg.begin(); g != pg.end(); ++g) {
+ PatchGroup* pgp = *g;
+ const PatchList& pl = pgp->patches;
+ //xml.stag(QString("PatchGroup name=\"%1\"").arg(Xml::xmlString(g->name)));
+ //xml.tag(level, "PatchGroup name=\"%s\"", Xml::xmlString(g->name).toLatin1().constData());
+ xml.tag(level, "PatchGroup name=\"%s\"", Xml::xmlString(pgp->name).toLatin1().constData());
+ level++;
+ //for (iPatch p = g->patches.begin(); p != g->patches.end(); ++p)
+ for (ciPatch p = pl.begin(); p != pl.end(); ++p)
+ //(*p)->write(xml);
+ //p->write(level, xml);
+ (*p)->write(level, xml);
+ level--;
+ //xml.etag("PatchGroup");
+ xml.etag(level, "PatchGroup");
+ }
+ for (iMidiController ic = _controller->begin(); ic != _controller->end(); ++ic)
+ //(*ic)->write(xml);
+ ic->second->write(level, xml);
+ //xml.etag("MidiInstrument");
+ level--;
+ xml.etag(level, "MidiInstrument");
+ //xml.etag("muse");
+ level--;
+ xml.etag(level, "muse");
+ }
+
+//---------------------------------------------------------
+// getPatchName
+//---------------------------------------------------------
+
+QString MidiInstrument::getPatchName(int channel, int prog, MType mode, bool drum)
+ {
+ int pr = prog & 0xff;
+ if(prog == CTRL_VAL_UNKNOWN || pr == 0xff)
+ return "<unknown>";
+
+ int hbank = (prog >> 16) & 0xff;
+ int lbank = (prog >> 8) & 0xff;
+ int tmask = 1;
+ bool drumchan = channel == 9;
+ bool hb = false;
+ bool lb = false;
+ switch (mode) {
+ case MT_GS:
+ tmask = 2;
+ hb = true;
+ break;
+ case MT_XG:
+ hb = true;
+ lb = true;
+ tmask = 4;
+ break;
+ case MT_GM:
+ if(drumchan)
+ return gmdrumname;
+ tmask = 1;
+ break;
+ default:
+ hb = true; // MSB bank matters
+ lb = true; // LSB bank matters
+ break;
+ }
+ for (ciPatchGroup i = pg.begin(); i != pg.end(); ++i) {
+ const PatchList& pl = (*i)->patches;
+ for (ciPatch ipl = pl.begin(); ipl != pl.end(); ++ipl) {
+ const Patch* mp = *ipl;
+ if ((mp->typ & tmask)
+ && (pr == mp->prog)
+ && ((drum && mode != MT_GM) ||
+ (mp->drum == drumchan))
+
+ && (hbank == mp->hbank || !hb || mp->hbank == -1)
+ && (lbank == mp->lbank || !lb || mp->lbank == -1))
+ return mp->name;
+ }
+ }
+ return "<unknown>";
+ }
+
+//---------------------------------------------------------
+// populatePatchPopup
+//---------------------------------------------------------
+
+void MidiInstrument::populatePatchPopup(QMenu* menu, int chan, MType songType, bool drum)
+ {
+ menu->clear();
+ int mask = 0;
+ bool drumchan = chan == 9;
+ switch (songType) {
+ case MT_XG: mask = 4; break;
+ case MT_GS: mask = 2; break;
+ case MT_GM:
+ if(drumchan)
+ return;
+ mask = 1;
+ break;
+ case MT_UNKNOWN: mask = 7; break;
+ }
+ if (pg.size() > 1) {
+ for (ciPatchGroup i = pg.begin(); i != pg.end(); ++i) {
+ PatchGroup* pgp = *i;
+ QMenu* pm = menu->addMenu(pgp->name);
+ pm->setFont(config.fonts[0]);
+ const PatchList& pl = pgp->patches;
+ QString& gname = pgp->name;
+ for (ciPatch ipl = pl.begin(); ipl != pl.end(); ++ipl) {
+ const Patch* mp = *ipl;
+ if ((mp->typ & mask) &&
+ ((drum && songType != MT_GM) ||
+ (mp->drum == drumchan)) )
+ {
+ int id = ((mp->hbank & 0xff) << 16)
+ + ((mp->lbank & 0xff) << 8) + (mp->prog & 0xff);
+ QAction* act = pm->addAction(mp->name);
+ //act->setCheckable(true);
+ QString strId = QString::number(id);
+ QStringList _data = (QStringList() << strId << gname);
+ //_data->append(strId);
+ //_data->append(gname);
+ //act->setData(id);
+ act->setData(_data);
+ }
+
+ }
+ }
+ }
+ else if (pg.size() == 1 ){
+ // no groups
+ const PatchList& pl = pg.front()->patches;
+ for (ciPatch ipl = pl.begin(); ipl != pl.end(); ++ipl) {
+ const Patch* mp = *ipl;
+ if (mp->typ & mask) {
+ int id = ((mp->hbank & 0xff) << 16)
+ + ((mp->lbank & 0xff) << 8) + (mp->prog & 0xff);
+ QAction* act = menu->addAction(mp->name);
+ //act->setCheckable(true);
+ QString strId = QString::number(id);
+ QStringList _data = (QStringList() << strId);
+ //_data->append(strId);
+ //act->setData(id);
+ act->setData(_data);
+ }
+ }
+ }
+ }
+
diff --git a/attic/muse2-oom/muse2/muse/instruments/minstrument.h b/attic/muse2-oom/muse2/muse/instruments/minstrument.h
new file mode 100644
index 00000000..0c37701f
--- /dev/null
+++ b/attic/muse2-oom/muse2/muse/instruments/minstrument.h
@@ -0,0 +1,145 @@
+//=========================================================
+// MusE
+// Linux Music Editor
+// $Id: minstrument.h,v 1.3.2.3 2009/03/09 02:05:18 terminator356 Exp $
+//
+// (C) Copyright 2000 Werner Schweer (ws@seh.de)
+//=========================================================
+
+#ifndef __MINSTRUMENT_H__
+#define __MINSTRUMENT_H__
+
+#include "globaldefs.h"
+#include <list>
+#include <vector>
+
+class MidiPort;
+class QMenu;
+class MidiPlayEvent;
+class Xml;
+class EventList;
+class MidiControllerList;
+class QString;
+
+//---------------------------------------------------------
+// Patch
+//---------------------------------------------------------
+
+struct Patch {
+ signed char typ; // 1 - GM 2 - GS 4 - XG
+ signed char hbank, lbank, prog;
+ QString name;
+ bool drum;
+ void read(Xml&);
+ void write(int level, Xml&);
+ };
+
+typedef std::list<Patch*> PatchList;
+typedef PatchList::iterator iPatch;
+typedef PatchList::const_iterator ciPatch;
+
+//---------------------------------------------------------
+// PatchGroup
+//---------------------------------------------------------
+
+struct PatchGroup {
+ QString name;
+ PatchList patches;
+ void read(Xml&);
+ };
+
+typedef std::vector<PatchGroup*> PatchGroupList;
+typedef PatchGroupList::iterator iPatchGroup;
+typedef PatchGroupList::const_iterator ciPatchGroup;
+
+struct SysEx {
+ QString name;
+ QString comment;
+ int dataLen;
+ unsigned char* data;
+ };
+
+//---------------------------------------------------------
+// MidiInstrument
+//---------------------------------------------------------
+
+class MidiInstrument {
+ PatchGroupList pg;
+ MidiControllerList* _controller;
+ QList<SysEx*> _sysex;
+ bool _dirty;
+ int _nullvalue;
+
+ void init();
+
+ protected:
+ EventList* _midiInit;
+ EventList* _midiReset;
+ EventList* _midiState;
+ char* _initScript;
+ QString _name;
+ QString _filePath;
+
+ public:
+ MidiInstrument();
+ virtual ~MidiInstrument();
+ MidiInstrument(const QString& txt);
+ const QString& iname() const { return _name; }
+ void setIName(const QString& txt) { _name = txt; }
+
+ //MidiInstrument& uniqueCopy(const MidiInstrument&);
+ // Assign will 'delete' all existing patches and groups from the instrument.
+ MidiInstrument& assign(const MidiInstrument&);
+ QString filePath() const { return _filePath; }
+ void setFilePath(const QString& s) { _filePath = s; }
+ bool dirty() const { return _dirty; }
+ void setDirty(bool v) { _dirty = v; }
+
+ const QList<SysEx*>& sysex() const { return _sysex; }
+ void removeSysex(SysEx* sysex) { _sysex.removeAll(sysex); }
+ void addSysex(SysEx* sysex) { _sysex.append(sysex); }
+
+ EventList* midiInit() const { return _midiInit; }
+ EventList* midiReset() const { return _midiReset; }
+ EventList* midiState() const { return _midiState; }
+ const char* initScript() const { return _initScript; }
+ MidiControllerList* controller() const { return _controller; }
+ int nullSendValue() { return _nullvalue; }
+ void setNullSendValue(int v) { _nullvalue = v; }
+
+ void readMidiState(Xml& xml);
+ virtual bool guiVisible() const { return false; }
+ virtual void showGui(bool) {}
+ virtual bool hasGui() const { return false; }
+ virtual void writeToGui(const MidiPlayEvent&) {}
+
+ virtual void reset(int, MType);
+ virtual QString getPatchName(int,int,MType,bool);
+ virtual void populatePatchPopup(QMenu*, int, MType, bool);
+ void read(Xml&);
+ void write(int level, Xml&);
+
+ PatchGroupList* groups() { return &pg; }
+ };
+
+//---------------------------------------------------------
+// MidiInstrumentList
+//---------------------------------------------------------
+
+class MidiInstrumentList : public std::list<MidiInstrument*> {
+
+ public:
+ MidiInstrumentList() {}
+ };
+
+typedef MidiInstrumentList::iterator iMidiInstrument;
+
+extern MidiInstrumentList midiInstruments;
+extern MidiInstrument* genericMidiInstrument;
+extern void initMidiInstruments();
+extern MidiInstrument* registerMidiInstrument(const QString&);
+extern void removeMidiInstrument(const QString& name);
+extern void removeMidiInstrument(const MidiInstrument* instr);
+
+#endif
+