summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWerner Schweer <ws.seh.de>2006-12-06 16:01:13 +0000
committerWerner Schweer <ws.seh.de>2006-12-06 16:01:13 +0000
commit036482a3fea264fdc7a4c9404466be9f49904100 (patch)
tree9d4781d5d8bfb2c542f407d7a540a93802b04847
parentc8b8ebd93489afc58315d252f5807a011a56468e (diff)
instrument editor updates
-rw-r--r--muse/muse/conf.cpp1
-rw-r--r--muse/muse/ctrl.cpp4
-rw-r--r--muse/muse/ctrl.h4
-rw-r--r--muse/muse/gconfig.cpp1
-rw-r--r--muse/muse/gconfig.h1
-rw-r--r--muse/muse/instruments/editinstrument.cpp634
-rw-r--r--muse/muse/instruments/editinstrument.h20
-rw-r--r--muse/muse/instruments/editinstrument.ui812
-rw-r--r--muse/muse/instruments/minstrument.cpp61
-rw-r--r--muse/muse/instruments/minstrument.h14
-rw-r--r--muse/muse/midictrl.h6
-rw-r--r--muse/muse/muse.cpp71
-rw-r--r--muse/muse/preferences.cpp2
-rw-r--r--muse/muse/preferences.ui86
14 files changed, 1247 insertions, 470 deletions
diff --git a/muse/muse/conf.cpp b/muse/muse/conf.cpp
index 87b6fcb7..b926ddb5 100644
--- a/muse/muse/conf.cpp
+++ b/muse/muse/conf.cpp
@@ -483,6 +483,7 @@ void MusE::writeGlobalConfiguration(Xml& xml) const
xml.tag("createDefaultMidiInput", config.createDefaultMidiInput);
xml.tag("projectPath", config.projectPath);
xml.tag("templatePath", config.templatePath);
+ xml.tag("instrumentPath", config.instrumentPath);
xml.tag("importMidiPath", config.importMidiPath);
xml.tag("importWavePath", config.importWavePath);
diff --git a/muse/muse/ctrl.cpp b/muse/muse/ctrl.cpp
index e4d58247..e6f6540b 100644
--- a/muse/muse/ctrl.cpp
+++ b/muse/muse/ctrl.cpp
@@ -36,6 +36,7 @@ Ctrl::Ctrl(int id, const QString& s, int t)
_curVal.f = 0.0f;
_touched = false;
_changed = false;
+ _moveWithPart = false;
}
Ctrl::Ctrl(int id, const QString& s, int t, float a, float b)
@@ -49,6 +50,7 @@ Ctrl::Ctrl(int id, const QString& s, int t, float a, float b)
_curVal.f = 0.0f;
_touched = false;
_changed = false;
+ _moveWithPart = false;
}
Ctrl::Ctrl()
@@ -60,6 +62,7 @@ Ctrl::Ctrl()
_curVal.f = 0.0f;
_touched = false;
_changed = false;
+ _moveWithPart = false;
}
Ctrl::Ctrl(const MidiController* mc)
@@ -72,6 +75,7 @@ Ctrl::Ctrl(const MidiController* mc)
_name = mc->name();
_touched = false;
_changed = false;
+ _moveWithPart = false;
}
//---------------------------------------------------------
diff --git a/muse/muse/ctrl.h b/muse/muse/ctrl.h
index f4f0922a..929a11d3 100644
--- a/muse/muse/ctrl.h
+++ b/muse/muse/ctrl.h
@@ -165,6 +165,7 @@ class Ctrl : public CTRL {
CVal min, max;
bool _changed;
bool _touched;
+ bool _moveWithPart;
public:
Ctrl();
@@ -200,6 +201,9 @@ class Ctrl : public CTRL {
void setRange(CVal, CVal);
CVal minVal() const { return min; }
CVal maxVal() const { return max; }
+ bool moveWithPart() const { return _moveWithPart; }
+ void setMoveWithPart(bool v) { _moveWithPart = v; }
+
void read(QDomNode node, bool midi);
void write(Xml&);
int val2pixelR(CVal, int maxpixel);
diff --git a/muse/muse/gconfig.cpp b/muse/muse/gconfig.cpp
index 231238ad..840e75f7 100644
--- a/muse/muse/gconfig.cpp
+++ b/muse/muse/gconfig.cpp
@@ -123,6 +123,7 @@ GlobalConfigValues config = {
true, // createDefaultMidiInput
QString("MusE/projects"), // projectPath
QString("MusE/templates"), // templatePath
+ QString("MusE/instruments"), // instrumentPath
QString("MusE/"), // midi import path
QString("MusE/"), // wave import path
};
diff --git a/muse/muse/gconfig.h b/muse/muse/gconfig.h
index 00ef43d5..1356fb22 100644
--- a/muse/muse/gconfig.h
+++ b/muse/muse/gconfig.h
@@ -123,6 +123,7 @@ struct GlobalConfigValues {
bool createDefaultMidiInput;
QString projectPath;
QString templatePath;
+ QString instrumentPath;
QString importMidiPath;
QString importWavePath;
};
diff --git a/muse/muse/instruments/editinstrument.cpp b/muse/muse/instruments/editinstrument.cpp
index 25fdac10..4736f918 100644
--- a/muse/muse/instruments/editinstrument.cpp
+++ b/muse/muse/instruments/editinstrument.cpp
@@ -23,6 +23,7 @@
#include "ctrl.h"
#include "midictrl.h"
#include "al/xml.h"
+#include "gconfig.h"
//---------------------------------------------------------
// EditInstrument
@@ -41,31 +42,453 @@ EditInstrument::EditInstrument(QWidget* parent)
}
instrumentList->setItemSelected(instrumentList->item(0), true);
connect(instrumentList, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)),
- SLOT(instrumentChanged(QListWidgetItem*)));
+ SLOT(instrumentChanged(QListWidgetItem*,QListWidgetItem*)));
connect(patchView, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)),
- SLOT(patchChanged(QTreeWidgetItem*)));
- instrumentChanged(instrumentList->item(0));
+ SLOT(patchChanged(QTreeWidgetItem*, QTreeWidgetItem*)));
+ instrumentChanged(instrumentList->item(0), instrumentList->item(0));
connect(listController, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)),
SLOT(controllerChanged(QListWidgetItem*)));
+ connect(sysexList, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)),
+ SLOT(sysexChanged(QListWidgetItem*)));
connect(instrumentName, SIGNAL(textChanged(const QString&)), SLOT(instrumentNameChanged(const QString&)));
connect(fileSaveAsAction, SIGNAL(triggered()), SLOT(fileSaveAs()));
connect(fileSaveAction, SIGNAL(triggered()), SLOT(fileSave()));
+ connect(fileNewAction, SIGNAL(triggered()), SLOT(fileNew()));
+
+ connect(deletePatch, SIGNAL(clicked()), SLOT(deletePatchClicked()));
+ connect(newPatch, SIGNAL(clicked()), SLOT(newPatchClicked()));
+ connect(newGroup, SIGNAL(clicked()), SLOT(newGroupClicked()));
+ connect(newCategory, SIGNAL(clicked()), SLOT(newCategoryClicked()));
+ connect(deleteController, SIGNAL(clicked()), SLOT(deleteControllerClicked()));
+ connect(newController, SIGNAL(clicked()), SLOT(newControllerClicked()));
+ connect(deleteSysex, SIGNAL(clicked()), SLOT(deleteSysexClicked()));
+ connect(newSysex, SIGNAL(clicked()), SLOT(newSysexClicked()));
+ }
+
+//---------------------------------------------------------
+// fileNew
+//---------------------------------------------------------
+
+void EditInstrument::fileNew()
+ {
+ 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) {
+ MidiInstrument* ni = new MidiInstrument(s);
+ midiInstruments.append(ni);
+ QListWidgetItem* item = new QListWidgetItem(ni->iname());
+ QVariant v = qVariantFromValue((void*)(ni));
+ item->setData(Qt::UserRole, v);
+ instrumentList->addItem(item);
+ instrumentList->setCurrentItem(item);
+ break;
+ }
+ }
+ }
+
+//---------------------------------------------------------
+// fileSave
+//---------------------------------------------------------
+
+void EditInstrument::fileSave()
+ {
+ QListWidgetItem* item = instrumentList->currentItem();
+ if (item == 0)
+ return;
+ MidiInstrument* instrument = (MidiInstrument*)item->data(Qt::UserRole).value<void*>();
+ if (instrument->filePath().isEmpty())
+ fileSaveAs();
+ else {
+ QFile f(instrument->filePath());
+ if (!f.open(QIODevice::WriteOnly))
+ fileSaveAs();
+ else {
+ f.close();
+ if (fileSave(instrument, instrument->filePath()))
+ instrument->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);
+ instrument->write(xml);
+ f.close();
+ if (f.error()) {
+ QString s = QString("Write File\n") + f.fileName() + QString("\nfailed: ")
+ + f.errorString();
+ QMessageBox::critical(this, tr("MusE: Write File failed"), s);
+ return false;
+ }
+ return true;
+ }
+
+//---------------------------------------------------------
+// fileSaveAs
+//---------------------------------------------------------
+
+void EditInstrument::fileSaveAs()
+ {
+ QListWidgetItem* item = instrumentList->currentItem();
+ if (item == 0)
+ return;
+ MidiInstrument* instrument = (MidiInstrument*)item->data(Qt::UserRole).value<void*>();
+ QString path = QDir::homePath() + "/" + config.instrumentPath;
+ path += QString("/%1.idf").arg(instrument->iname());
+ QString s = QFileDialog::getSaveFileName(this,
+ tr("MusE: Save Instrument Definition"),
+ path,
+ tr("Instrument Definition (*.idf)"));
+ if (s.isEmpty())
+ return;
+ instrument->setFilePath(s);
+ if (fileSave(instrument, s))
+ instrument->setDirty(false);
+ }
+
+//---------------------------------------------------------
+// closeEvent
+//---------------------------------------------------------
+
+void EditInstrument::closeEvent(QCloseEvent* ev)
+ {
+ QListWidgetItem* item = instrumentList->currentItem();
+ if (item) {
+ MidiInstrument* instrument = (MidiInstrument*)item->data(Qt::UserRole).value<void*>();
+ if (checkDirty(instrument)) {
+ ev->ignore();
+ return;
+ }
+ }
+ QMainWindow::closeEvent(ev);
+ }
+
+//---------------------------------------------------------
+// instrumentNameChanged
+//---------------------------------------------------------
+
+void EditInstrument::instrumentNameChanged(const QString& s)
+ {
+ QListWidgetItem* item = instrumentList->currentItem();
+ if (item == 0)
+ return;
+ if (s != item->text()) {
+ item->setText(s);
+ MidiInstrument* instrument = (MidiInstrument*)item->data(Qt::UserRole).value<void*>();
+ instrument->setDirty(true);
+ }
+ }
+
+//---------------------------------------------------------
+// deletePatchClicked
+//---------------------------------------------------------
+
+void EditInstrument::deletePatchClicked()
+ {
+ QListWidgetItem* item = instrumentList->currentItem();
+ if (item == 0)
+ return;
+ MidiInstrument* instrument = (MidiInstrument*)item->data(Qt::UserRole).value<void*>();
+ QTreeWidgetItem* pi = patchView->currentItem();
+ if (pi == 0)
+ return;
+ void* p = pi->data(0, Qt::UserRole).value<void*>();
+ if (p == 0)
+ return;
+ 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");
+ }
+
+//---------------------------------------------------------
+// newPatchClicked
+//---------------------------------------------------------
+
+void EditInstrument::newPatchClicked()
+ {
+ QListWidgetItem* item = instrumentList->currentItem();
+ if (item == 0)
+ return;
+ MidiInstrument* instrument = (MidiInstrument*)item->data(Qt::UserRole).value<void*>();
+ std::vector<PatchGroup>* pg = instrument->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 (iPatch p = g->patches.begin(); p != g->patches.end(); ++p) {
+ if ((*p)->name == patchName) {
+ found = true;
+ break;
+ }
+ }
+ if (found)
+ break;
+ }
+ if (!found)
+ break;
+ }
+
+ //
+ // search current patch group
+ //
+ PatchGroup* pGroup = 0;
+ QTreeWidgetItem* pi = patchView->currentItem();
+ if (pi == 0)
+ return;
+ if (pi->data(0, Qt::UserRole).value<void*>())
+ pi = pi->parent();
+ for (std::vector<PatchGroup>::iterator 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;
+ }
+ Patch* patch = new Patch;
+ patch->name = patchName;
+ pGroup->patches.push_back(patch);
+ QTreeWidgetItem* sitem = new QTreeWidgetItem;
+ sitem->setText(0, patch->name);
+ QVariant v = QVariant::fromValue((void*)(patch));
+ sitem->setData(0, Qt::UserRole, v);
+
+ pi->addChild(sitem);
+ patchView->setCurrentItem(sitem);
+ instrument->setDirty(true);
+ }
+
+//---------------------------------------------------------
+// newGroupClicked
+//---------------------------------------------------------
+
+void EditInstrument::newGroupClicked()
+ {
+ QListWidgetItem* item = instrumentList->currentItem();
+ if (item == 0)
+ return;
+ MidiInstrument* instrument = (MidiInstrument*)item->data(Qt::UserRole).value<void*>();
+ std::vector<PatchGroup>* pg = instrument->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) {
+ if (g->name == groupName) {
+ found = true;
+ break;
+ }
+ }
+ if (!found)
+ break;
+ }
+
+ PatchGroup pGroup;
+ pGroup.name = groupName;
+ pg->push_back(pGroup);
+
+ QTreeWidgetItem* sitem = new QTreeWidgetItem;
+ sitem->setText(0, groupName);
+ QVariant v = QVariant::fromValue((void*)0);
+ sitem->setData(0, Qt::UserRole, v);
+ patchView->addTopLevelItem(sitem);
+ patchView->setCurrentItem(sitem);
+ instrument->setDirty(true);
+ }
+
+//---------------------------------------------------------
+// newCategoryClicked
+//---------------------------------------------------------
+
+void EditInstrument::newCategoryClicked()
+ {
+ QListWidgetItem* item = instrumentList->currentItem();
+ if (item == 0)
+ return;
+ MidiInstrument* instrument = (MidiInstrument*)item->data(Qt::UserRole).value<void*>();
+ bool ok;
+ QString cat = QInputDialog::getText(this,
+ tr("MusE: Enter new Category"),
+ tr("Enter new Category:"),
+ QLineEdit::Normal, "", &ok
+ );
+ if (ok && !cat.isEmpty()) {
+ category->addItem(cat);
+ instrument->addCategory(cat);
+ instrument->setDirty(true);
+ }
+ }
+
+//---------------------------------------------------------
+// deleteControllerClicked
+//---------------------------------------------------------
+
+void EditInstrument::deleteControllerClicked()
+ {
+ QListWidgetItem* item = instrumentList->currentItem();
+ QListWidgetItem* item2 = listController->currentItem();
+ if (item == 0 || item2 == 0)
+ return;
+ MidiInstrument* instrument = (MidiInstrument*)item->data(Qt::UserRole).value<void*>();
+ MidiController* ctrl = (MidiController*)item2->data(Qt::UserRole).value<void*>();
+ MidiControllerList* cl = instrument->controller();
+ cl->removeAll(ctrl);
+ delete item2;
+ instrument->setDirty(true);
+ }
+
+//---------------------------------------------------------
+// newControllerClicked
+//---------------------------------------------------------
+
+void EditInstrument::newControllerClicked()
+ {
+ QListWidgetItem* item = instrumentList->currentItem();
+ if (item == 0)
+ return;
+ MidiInstrument* instrument = (MidiInstrument*)item->data(Qt::UserRole).value<void*>();
+
+ QString ctrlName;
+ MidiControllerList* cl = instrument->controller();
+ for (int i = 1;; ++i) {
+ ctrlName = QString("Controller-%d").arg(i);
+
+ bool found = false;
+ for (iMidiController ic = cl->begin(); ic != cl->end(); ++ic) {
+ MidiController* c = *ic;
+ if (c->name() == ctrlName) {
+ found = true;
+ break;
+ }
+ }
+ if (!found)
+ break;
+ }
+
+ MidiController* ctrl = new MidiController();
+ ctrl->setName(ctrlName);
+ item = new QListWidgetItem(ctrlName);
+ QVariant v = qVariantFromValue((void*)(ctrl));
+ item->setData(Qt::UserRole, v);
+ listController->addItem(item);
+ listController->setCurrentItem(item);
+ instrument->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);
+ }
+
+//---------------------------------------------------------
+// newSysexClicked
+//---------------------------------------------------------
+
+void EditInstrument::newSysexClicked()
+ {
+ QListWidgetItem* item = instrumentList->currentItem();
+ if (item == 0)
+ return;
+ MidiInstrument* instrument = (MidiInstrument*)item->data(Qt::UserRole).value<void*>();
+
+ QString sysexName;
+ for (int i = 1;; ++i) {
+ sysexName = QString("Sysex-%d").arg(i);
+
+ bool found = false;
+ foreach(const SysEx* s, instrument->sysex()) {
+ if (s->name == sysexName) {
+ found = true;
+ break;
+ }
+ }
+ if (!found)
+ break;
+ }
+ SysEx* nsysex = new SysEx;
+ nsysex->name = sysexName;
+ instrument->addSysex(nsysex);
+
+ item = new QListWidgetItem(sysexName);
+ QVariant v = QVariant::fromValue((void*)item);
+ item->setData(Qt::UserRole, v);
+ sysexList->addItem(item);
+ sysexList->setCurrentItem(item);
+ instrument->setDirty(true);
}
//---------------------------------------------------------
// instrumentChanged
//---------------------------------------------------------
-void EditInstrument::instrumentChanged(QListWidgetItem* sel)
+void EditInstrument::instrumentChanged(QListWidgetItem* sel, QListWidgetItem* old)
{
patchView->clear();
listController->clear();
+ category->clear();
+ sysexList->clear();
if (sel == 0)
return;
+ if (old) {
+ MidiInstrument* oi = (MidiInstrument*)old->data(Qt::UserRole).value<void*>();
+ checkDirty(oi);
+ oi->setDirty(false);
+ }
+
// populate patch list
MidiInstrument* instrument = (MidiInstrument*)sel->data(Qt::UserRole).value<void*>();
+ instrument->setDirty(false);
+
instrumentName->setText(instrument->iname());
std::vector<PatchGroup>* pg = instrument->groups();
for (std::vector<PatchGroup>::iterator g = pg->begin(); g != pg->end(); ++g) {
@@ -78,7 +501,7 @@ void EditInstrument::instrumentChanged(QListWidgetItem* sel)
Patch* patch = *p;
QTreeWidgetItem* sitem = new QTreeWidgetItem;
sitem->setText(0, patch->name);
- QVariant v = QVariant::fromValue((void*)(patch));
+ QVariant v = QVariant::fromValue((void*)patch);
sitem->setData(0, Qt::UserRole, v);
item->addChild(sitem);
}
@@ -87,12 +510,94 @@ void EditInstrument::instrumentChanged(QListWidgetItem* sel)
for (iMidiController ic = cl->begin(); ic != cl->end(); ++ic) {
MidiController* c = *ic;
QListWidgetItem* item = new QListWidgetItem(c->name());
- QVariant v = qVariantFromValue((void*)(c));
+ QVariant v = QVariant::fromValue((void*)c);
item->setData(Qt::UserRole, v);
listController->addItem(item);
}
- listController->setItemSelected(listController->item(0), true);
- controllerChanged(listController->item(0));
+
+ category->addItems(instrument->categories());
+
+ foreach(const SysEx* s, instrument->sysex()) {
+ QListWidgetItem* item = new QListWidgetItem(s->name);
+ QVariant v = QVariant::fromValue((void*)item);
+ item->setData(Qt::UserRole, v);
+ sysexList->addItem(item);
+ }
+ if (!instrument->sysex().isEmpty()) {
+ sysexList->setItemSelected(sysexList->item(0), true);
+ sysexChanged(sysexList->item(0));
+ }
+ if (!cl->empty()) {
+ listController->setItemSelected(listController->item(0), true);
+ controllerChanged(listController->item(0));
+ }
+ }
+
+//---------------------------------------------------------
+// patchChanged
+//---------------------------------------------------------
+
+void EditInstrument::patchChanged(QTreeWidgetItem* sel, QTreeWidgetItem* old)
+ {
+ if (old && old->data(0, Qt::UserRole).value<void*>()) {
+ 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*>();
+ if (p->name != patchNameEdit->text()) {
+ p->name = patchNameEdit->text();
+ instrument->setDirty(true);
+ }
+ if (p->hbank != spinBoxHBank->value()) {
+ p->hbank = spinBoxHBank->value();
+ instrument->setDirty(true);
+ }
+ if (p->lbank != spinBoxLBank->value()) {
+ p->hbank = spinBoxHBank->value();
+ instrument->setDirty(true);
+ }
+ if (p->prog != spinBoxProgram->value()) {
+ p->prog = spinBoxProgram->value();
+ 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);
+ }
+ }
+ if (sel == 0 || sel->data(0, Qt::UserRole).value<void*>() == 0) {
+ patchNameEdit->setText("");
+ return;
+ }
+ Patch* p = (Patch*)sel->data(0, Qt::UserRole).value<void*>();
+ patchNameEdit->setText(p->name);
+ spinBoxHBank->setValue(p->hbank);
+ spinBoxLBank->setValue(p->lbank);
+ spinBoxProgram->setValue(p->prog);
+ checkBoxDrum->setChecked(p->drumMap);
+ checkBoxGM->setChecked(p->typ & 1);
+ checkBoxGS->setChecked(p->typ & 2);
+ checkBoxXG->setChecked(p->typ & 4);
+ category->setCurrentIndex(p->categorie);
}
//---------------------------------------------------------
@@ -136,101 +641,42 @@ void EditInstrument::controllerChanged(QListWidgetItem* sel)
}
//---------------------------------------------------------
-// patchChanged
-//---------------------------------------------------------
-
-void EditInstrument::patchChanged(QTreeWidgetItem* sel)
- {
- if (sel == 0 || sel->data(0, Qt::UserRole).value<void*>() == 0) {
- patchNameEdit->setText("");
- return;
- }
- Patch* p = (Patch*)sel->data(0, Qt::UserRole).value<void*>();
- patchNameEdit->setText(p->name);
- spinBoxHBank->setValue(p->hbank);
- spinBoxLBank->setValue(p->lbank);
- spinBoxProgram->setValue(p->prog);
- checkBoxDrum->setChecked(p->drumMap);
- checkBoxGM->setChecked(p->typ & 1);
- checkBoxGS->setChecked(p->typ & 2);
- checkBoxXG->setChecked(p->typ & 4);
- }
-
-//---------------------------------------------------------
-// fileNew
-//---------------------------------------------------------
-
-void EditInstrument::fileNew()
- {
-
- }
-
-//---------------------------------------------------------
-// fileSave
-//---------------------------------------------------------
-
-void EditInstrument::fileSave()
- {
-
- }
-
-//---------------------------------------------------------
-// fileSaveAs
-//---------------------------------------------------------
-
-void EditInstrument::fileSaveAs()
- {
- QListWidgetItem* item = instrumentList->currentItem();
- if (item == 0)
- return;
- MidiInstrument* instrument = (MidiInstrument*)item->data(Qt::UserRole).value<void*>();
- QString path = QDir::homePath() + "/MusE/instruments";
- path += QString("/%1.idf").arg(instrument->iname());
- QString s = QFileDialog::getSaveFileName(this,
- tr("MusE: Save Instrument Definition"),
- path,
- tr("Instrument Definition (*.idf)"));
- if (s.isEmpty())
- return;
- QFile f(s);
- if (!f.open(QIODevice::WriteOnly)) {
- QString s("Creating file failed: ");
- s += strerror(errno);
- QMessageBox::critical(this,
- tr("MusE: Create file failed"), s);
- return;
- }
- Xml xml(&f);
- instrument->write(xml);
- f.close();
- if (f.error()) {
- QString s = QString("Write File\n") + f.fileName() + QString("\nfailed: ")
- + f.errorString();
- QMessageBox::critical(this, tr("MusE: Write File failed"), s);
- }
- }
-
-//---------------------------------------------------------
-// fileExit
+// sysexChanged
//---------------------------------------------------------
-void EditInstrument::fileExit()
+void EditInstrument::sysexChanged(QListWidgetItem*)
{
+ printf("sysexChanged\n");
}
//---------------------------------------------------------
-// instrumentNameChanged
+// checkDirty
+// return true on Abort
//---------------------------------------------------------
-void EditInstrument::instrumentNameChanged(const QString& s)
+bool EditInstrument::checkDirty(MidiInstrument* i)
{
- QListWidgetItem* item = instrumentList->currentItem();
- if (item == 0)
- return;
- if (s != item->text()) {
- item->setText(s);
- MidiInstrument* instrument = (MidiInstrument*)item->data(Qt::UserRole).value<void*>();
- instrument->setDirty(true);
+ if (!i->dirty())
+ return false;
+ int 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);
+ if (n == 0) {
+ if (i->filePath().isEmpty())
+ fileSaveAs();
+ else {
+ QFile f(i->filePath());
+ if (!f.open(QIODevice::WriteOnly))
+ fileSaveAs();
+ else {
+ f.close();
+ if (fileSave(i, i->filePath()))
+ i->setDirty(false);
+ }
+ }
+ return false;
}
+ return n == 2;
}
diff --git a/muse/muse/instruments/editinstrument.h b/muse/muse/instruments/editinstrument.h
index 2714814a..660ba3cc 100644
--- a/muse/muse/instruments/editinstrument.h
+++ b/muse/muse/instruments/editinstrument.h
@@ -23,6 +23,8 @@
#include "ui_editinstrument.h"
+class MidiInstrument;
+
//---------------------------------------------------------
// EditInstrument
//---------------------------------------------------------
@@ -30,15 +32,27 @@
class EditInstrument : public QMainWindow, public Ui::EditInstrumentBase {
Q_OBJECT
+ bool fileSave(MidiInstrument*, const QString& name);
+ void closeEvent(QCloseEvent*);
+ bool checkDirty(MidiInstrument*);
+
private slots:
virtual void fileNew();
virtual void fileSave();
virtual void fileSaveAs();
- virtual void fileExit();
- void instrumentChanged(QListWidgetItem*);
- void patchChanged(QTreeWidgetItem*);
+ void instrumentChanged(QListWidgetItem*, QListWidgetItem*);
+ void patchChanged(QTreeWidgetItem*, QTreeWidgetItem*);
void controllerChanged(QListWidgetItem* sel);
+ void sysexChanged(QListWidgetItem* sel);
void instrumentNameChanged(const QString&);
+ void deletePatchClicked();
+ void newPatchClicked();
+ void newGroupClicked();
+ void newCategoryClicked();
+ void deleteControllerClicked();
+ void newControllerClicked();
+ void deleteSysexClicked();
+ void newSysexClicked();
public:
EditInstrument(QWidget* parent = 0);
diff --git a/muse/muse/instruments/editinstrument.ui b/muse/muse/instruments/editinstrument.ui
index c8f1916b..2a7b525a 100644
--- a/muse/muse/instruments/editinstrument.ui
+++ b/muse/muse/instruments/editinstrument.ui
@@ -5,8 +5,8 @@
<rect>
<x>0</x>
<y>0</y>
- <width>819</width>
- <height>505</height>
+ <width>821</width>
+ <height>551</height>
</rect>
</property>
<property name="windowTitle" >
@@ -21,7 +21,7 @@
<number>6</number>
</property>
<item>
- <widget class="QSplitter" name="splitter_2" >
+ <widget class="QSplitter" name="splitter_3" >
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
@@ -57,7 +57,7 @@
<item>
<widget class="QTabWidget" name="tabWidget3" >
<property name="currentIndex" >
- <number>1</number>
+ <number>0</number>
</property>
<widget class="QWidget" name="tab" >
<attribute name="title" >
@@ -111,23 +111,23 @@
</property>
</widget>
</item>
- <item row="3" column="0" >
+ <item row="4" column="0" >
<widget class="QLabel" name="textLabel4_3" >
<property name="text" >
<string>Program:</string>
</property>
</widget>
</item>
- <item row="6" column="0" colspan="3" >
+ <item row="7" column="0" colspan="3" >
<layout class="QHBoxLayout" >
<property name="margin" >
- <number>5</number>
+ <number>0</number>
</property>
<property name="spacing" >
<number>6</number>
</property>
<item>
- <widget class="QToolButton" name="patchDelete" >
+ <widget class="QToolButton" name="deletePatch" >
<property name="sizePolicy" >
<sizepolicy>
<hsizetype>5</hsizetype>
@@ -145,7 +145,7 @@
</widget>
</item>
<item>
- <widget class="QToolButton" name="patchNew" >
+ <widget class="QToolButton" name="newPatch" >
<property name="sizePolicy" >
<sizepolicy>
<hsizetype>5</hsizetype>
@@ -163,7 +163,7 @@
</widget>
</item>
<item>
- <widget class="QToolButton" name="patchNewGroup" >
+ <widget class="QToolButton" name="newGroup" >
<property name="text" >
<string>New Group</string>
</property>
@@ -185,9 +185,16 @@
</property>
</spacer>
</item>
+ <item>
+ <widget class="QPushButton" name="newCategory" >
+ <property name="text" >
+ <string>New Category</string>
+ </property>
+ </widget>
+ </item>
</layout>
</item>
- <item row="2" column="2" >
+ <item row="3" column="2" >
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
@@ -203,7 +210,7 @@
</property>
</spacer>
</item>
- <item row="3" column="2" >
+ <item row="4" column="2" >
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
@@ -219,7 +226,7 @@
</property>
</spacer>
</item>
- <item row="1" column="2" >
+ <item row="2" column="2" >
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
@@ -235,7 +242,7 @@
</property>
</spacer>
</item>
- <item row="2" column="1" >
+ <item row="3" column="1" >
<widget class="QSpinBox" name="spinBoxLBank" >
<property name="specialValueText" >
<string>d.c.</string>
@@ -251,21 +258,21 @@
</property>
</widget>
</item>
- <item row="1" column="0" >
+ <item row="2" column="0" >
<widget class="QLabel" name="textLabel2_2" >
<property name="text" >
<string>High Bank:</string>
</property>
</widget>
</item>
- <item row="2" column="0" >
+ <item row="3" column="0" >
<widget class="QLabel" name="textLabel3_2" >
<property name="text" >
<string>Low Bank:</string>
</property>
</widget>
</item>
- <item row="5" column="2" >
+ <item row="6" column="2" >
<spacer>
<property name="orientation" >
<enum>Qt::Vertical</enum>
@@ -281,7 +288,7 @@
</property>
</spacer>
</item>
- <item row="1" column="1" >
+ <item row="2" column="1" >
<widget class="QSpinBox" name="spinBoxHBank" >
<property name="specialValueText" >
<string>d.c.</string>
@@ -297,13 +304,13 @@
</property>
</widget>
</item>
- <item row="3" column="1" >
+ <item row="4" column="1" >
<widget class="QSpinBox" name="spinBoxProgram" />
</item>
- <item row="4" column="0" colspan="3" >
+ <item row="5" column="0" colspan="3" >
<layout class="QHBoxLayout" >
<property name="margin" >
- <number>6</number>
+ <number>0</number>
</property>
<property name="spacing" >
<number>6</number>
@@ -338,6 +345,20 @@
</item>
</layout>
</item>
+ <item row="1" column="1" >
+ <widget class="QComboBox" name="category" >
+ <property name="editable" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" >
+ <widget class="QLabel" name="label_6" >
+ <property name="text" >
+ <string>Category:</string>
+ </property>
+ </widget>
+ </item>
</layout>
</widget>
</widget>
@@ -348,264 +369,332 @@
<attribute name="title" >
<string>Controller</string>
</attribute>
- <layout class="QGridLayout" >
+ <layout class="QVBoxLayout" >
<property name="margin" >
<number>9</number>
</property>
<property name="spacing" >
<number>6</number>
</property>
- <item row="0" column="0" >
- <widget class="QLabel" name="textLabel1" >
- <property name="sizePolicy" >
- <sizepolicy>
- <hsizetype>5</hsizetype>
- <vsizetype>0</vsizetype>
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="text" >
- <string>Controller List:</string>
- </property>
- </widget>
- </item>
- <item rowspan="2" row="0" column="1" >
- <spacer>
+ <item>
+ <widget class="QSplitter" name="splitter_2" >
<property name="orientation" >
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeHint" >
- <size>
- <width>20</width>
- <height>111</height>
- </size>
+ <enum>Qt::Horizontal</enum>
</property>
- </spacer>
- </item>
- <item rowspan="2" row="1" column="0" >
- <widget class="QListWidget" name="listController" >
- <property name="whatsThis" >
- <string>This is a list of commonly used midi controllers.
+ <widget class="QWidget" name="layoutWidget" >
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="textLabel1" >
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>5</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Controller List:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QListWidget" name="listController" >
+ <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>
- <item row="2" column="1" >
- <widget class="QGroupBox" name="GroupBox1" >
- <property name="sizePolicy" >
- <sizepolicy>
- <hsizetype>1</hsizetype>
- <vsizetype>5</vsizetype>
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="title" >
- <string>Properties</string>
- </property>
- <layout class="QGridLayout" >
- <property name="margin" >
- <number>10</number>
- </property>
- <property name="spacing" >
- <number>6</number>
- </property>
- <item row="0" column="0" >
- <widget class="QLabel" name="TextLabel1_3" >
- <property name="text" >
- <string>Name</string>
- </property>
- </widget>
- </item>
- <item row="1" column="0" >
- <widget class="QLabel" name="TextLabel2_4" >
- <property name="text" >
- <string>Type</string>
- </property>
- </widget>
- </item>
- <item row="1" column="1" >
- <layout class="QHBoxLayout" >
- <property name="margin" >
- <number>2</number>
- </property>
- <property name="spacing" >
- <number>6</number>
- </property>
- <item>
- <widget class="QComboBox" name="spinBoxType" >
- <item>
- <property name="text" >
- <string>Controller-7Bit</string>
- </property>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="layoutWidget" >
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QGroupBox" name="GroupBox1" >
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>5</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title" >
+ <string>Properties</string>
+ </property>
+ <layout class="QGridLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item row="0" column="0" >
+ <widget class="QLabel" name="TextLabel1_3" >
+ <property name="text" >
+ <string>Name</string>
+ </property>
+ </widget>
</item>
- <item>
- <property name="text" >
- <string>Controller-14Bit</string>
- </property>
+ <item row="0" column="2" >
+ <widget class="QLineEdit" name="entryName" />
</item>
- <item>
- <property name="text" >
- <string>RPN-7Bit</string>
- </property>
+ <item row="1" column="0" colspan="2" >
+ <widget class="QLabel" name="label_2" >
+ <property name="text" >
+ <string>Comment</string>
+ </property>
+ </widget>
</item>
- <item>
- <property name="text" >
- <string>NRPN-7Bit</string>
- </property>
+ <item row="1" column="2" >
+ <widget class="QTextEdit" name="textEdit" />
</item>
- <item>
- <property name="text" >
- <string>RPN-14Bit</string>
- </property>
+ <item row="2" column="0" >
+ <widget class="QLabel" name="TextLabel2_4" >
+ <property name="text" >
+ <string>Type</string>
+ </property>
+ </widget>
</item>
- <item>
- <property name="text" >
- <string>NRPN-14Bit</string>
- </property>
+ <item row="2" column="1" colspan="2" >
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>2</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QComboBox" name="spinBoxType" >
+ <item>
+ <property name="text" >
+ <string>Controller-7Bit</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Controller-14Bit</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>RPN-7Bit</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>NRPN-7Bit</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>RPN-14Bit</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>NRPN-14Bit</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Pitch</string>
+ </property>
+ </item>
+ <item>
+ <property name="text" >
+ <string>Program</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="TextLabel3_2" >
+ <property name="text" >
+ <string>H-Ctrl</string>
+ </property>
+ <property name="indent" >
+ <number>10</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="spinBoxHCtrlNo" >
+ <property name="toolTip" >
+ <string>Midi Controller Number High Byte</string>
+ </property>
+ <property name="maximum" >
+ <number>127</number>
+ </property>
+ <property name="minimum" >
+ <number>0</number>
+ </property>
+ <property name="value" >
+ <number>1</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="TextLabel2_3_2" >
+ <property name="text" >
+ <string>L-Ctrl</string>
+ </property>
+ <property name="indent" >
+ <number>10</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="spinBoxLCtrlNo" >
+ <property name="toolTip" >
+ <string>Midi Controller Number Low Byte</string>
+ </property>
+ <property name="maximum" >
+ <number>127</number>
+ </property>
+ <property name="minimum" >
+ <number>0</number>
+ </property>
+ <property name="value" >
+ <number>1</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="3" column="0" >
+ <widget class="QLabel" name="textLabel4_2" >
+ <property name="text" >
+ <string>Range</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1" colspan="2" >
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="TextLabel1_2_2" >
+ <property name="text" >
+ <string>Min</string>
+ </property>
+ <property name="indent" >
+ <number>10</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="spinBoxMin" >
+ <property name="maximum" >
+ <number>16384</number>
+ </property>
+ <property name="minimum" >
+ <number>-16385</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="TextLabel2_2_2" >
+ <property name="text" >
+ <string>Max</string>
+ </property>
+ <property name="indent" >
+ <number>10</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="spinBoxMax" >
+ <property name="maximum" >
+ <number>16384</number>
+ </property>
+ <property name="minimum" >
+ <number>-16385</number>
+ </property>
+ <property name="value" >
+ <number>127</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="textLabel1_3" >
+ <property name="text" >
+ <string>Default</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="spinBoxDefault" />
+ </item>
+ </layout>
+ </item>
+ <item row="4" column="0" colspan="3" >
+ <widget class="QCheckBox" name="moveWithPart" >
+ <property name="text" >
+ <string>Move Controller Values with Part</string>
+ </property>
+ </widget>
</item>
- <item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QPushButton" name="deleteController" >
<property name="text" >
- <string>Pitch</string>
+ <string>Delete</string>
</property>
- </item>
- <item>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="newController" >
<property name="text" >
- <string>Program</string>
+ <string>New Controller</string>
</property>
- </item>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="TextLabel3_2" >
- <property name="text" >
- <string>H-Ctrl</string>
- </property>
- <property name="indent" >
- <number>10</number>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QSpinBox" name="spinBoxHCtrlNo" >
- <property name="toolTip" >
- <string>Midi Controller Number High Byte</string>
- </property>
- <property name="maximum" >
- <number>127</number>
- </property>
- <property name="minimum" >
- <number>0</number>
- </property>
- <property name="value" >
- <number>1</number>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="TextLabel2_3_2" >
- <property name="text" >
- <string>L-Ctrl</string>
- </property>
- <property name="indent" >
- <number>10</number>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QSpinBox" name="spinBoxLCtrlNo" >
- <property name="toolTip" >
- <string>Midi Controller Number Low Byte</string>
- </property>
- <property name="maximum" >
- <number>127</number>
- </property>
- <property name="minimum" >
- <number>0</number>
- </property>
- <property name="value" >
- <number>1</number>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item row="0" column="1" >
- <widget class="QLineEdit" name="entryName" />
- </item>
- <item row="2" column="0" >
- <widget class="QLabel" name="textLabel4_2" >
- <property name="text" >
- <string>Range</string>
- </property>
- </widget>
- </item>
- <item row="2" column="1" >
- <layout class="QHBoxLayout" >
- <property name="margin" >
- <number>0</number>
- </property>
- <property name="spacing" >
- <number>6</number>
- </property>
- <item>
- <widget class="QLabel" name="TextLabel1_2_2" >
- <property name="text" >
- <string>Min</string>
- </property>
- <property name="indent" >
- <number>10</number>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QSpinBox" name="spinBoxMin" >
- <property name="maximum" >
- <number>16384</number>
- </property>
- <property name="minimum" >
- <number>-16385</number>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="TextLabel2_2_2" >
- <property name="text" >
- <string>Max</string>
- </property>
- <property name="indent" >
- <number>10</number>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QSpinBox" name="spinBoxMax" >
- <property name="maximum" >
- <number>16384</number>
- </property>
- <property name="minimum" >
- <number>-16385</number>
- </property>
- <property name="value" >
- <number>127</number>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="textLabel1_3" >
- <property name="text" >
- <string>Default</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QSpinBox" name="spinBoxDefault" />
- </item>
- </layout>
- </item>
- </layout>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
</widget>
</item>
</layout>
@@ -614,49 +703,139 @@ handled like normal controllers.</string>
<attribute name="title" >
<string>SysEx</string>
</attribute>
- <layout class="QGridLayout" >
+ <layout class="QVBoxLayout" >
<property name="margin" >
- <number>0</number>
+ <number>9</number>
</property>
<property name="spacing" >
<number>6</number>
</property>
- <item row="2" column="1" >
- <spacer>
+ <item>
+ <widget class="QSplitter" name="splitter_4" >
<property name="orientation" >
- <enum>Qt::Vertical</enum>
- </property>
- <property name="sizeType" >
- <enum>QSizePolicy::Expanding</enum>
- </property>
- <property name="sizeHint" >
- <size>
- <width>20</width>
- <height>130</height>
- </size>
- </property>
- </spacer>
- </item>
- <item rowspan="3" row="0" column="0" >
- <widget class="QListWidget" name="listBox2" >
- <property name="sizePolicy" >
- <sizepolicy>
- <hsizetype>1</hsizetype>
- <vsizetype>7</vsizetype>
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- </widget>
- </item>
- <item row="1" column="1" >
- <widget class="QTextEdit" name="initSysEx" />
- </item>
- <item row="0" column="1" >
- <widget class="QLabel" name="textLabel1_2" >
- <property name="text" >
- <string>Hex Entry:</string>
+ <enum>Qt::Horizontal</enum>
</property>
+ <widget class="QWidget" name="layoutWidget" >
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="label_3" >
+ <property name="text" >
+ <string>SYSEX-List:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QListWidget" name="sysexList" >
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>1</hsizetype>
+ <vsizetype>7</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QWidget" name="layoutWidget" >
+ <layout class="QVBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QGroupBox" name="groupBox" >
+ <property name="title" >
+ <string>Properties</string>
+ </property>
+ <layout class="QGridLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item row="0" column="0" >
+ <widget class="QLabel" name="label_4" >
+ <property name="text" >
+ <string>Name:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" >
+ <widget class="QLineEdit" name="sysexName" />
+ </item>
+ <item row="1" column="0" >
+ <widget class="QLabel" name="label_5" >
+ <property name="text" >
+ <string>Comment:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" >
+ <widget class="QTextEdit" name="sysexComment" />
+ </item>
+ <item row="2" column="0" >
+ <widget class="QLabel" name="textLabel1_2" >
+ <property name="text" >
+ <string>Data:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1" >
+ <widget class="QTextEdit" name="sysexData" />
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <widget class="QPushButton" name="deleteSysex" >
+ <property name="text" >
+ <string>Delete</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="newSysex" >
+ <property name="text" >
+ <string>New Sysex</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
</widget>
</item>
</layout>
@@ -674,7 +853,7 @@ handled like normal controllers.</string>
<rect>
<x>0</x>
<y>0</y>
- <width>819</width>
+ <width>821</width>
<height>32</height>
</rect>
</property>
@@ -687,7 +866,7 @@ handled like normal controllers.</string>
<x>434</x>
<y>167</y>
<width>146</width>
- <height>166</height>
+ <height>168</height>
</rect>
</property>
<property name="title" >
@@ -701,9 +880,20 @@ handled like normal controllers.</string>
</widget>
<addaction name="fileMenu" />
</widget>
+ <widget class="QToolBar" name="toolBar" >
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <attribute name="toolBarArea" >
+ <number>4</number>
+ </attribute>
+ <addaction name="fileExitAction" />
+ <addaction name="fileNewAction" />
+ <addaction name="fileSaveAction" />
+ </widget>
<action name="fileNewAction" >
<property name="icon" >
- <iconset>image0</iconset>
+ <iconset resource="../muse.qrc" >:/xpm/filenew.png</iconset>
</property>
<property name="text" >
<string>&amp;New</string>
@@ -717,7 +907,7 @@ handled like normal controllers.</string>
</action>
<action name="fileOpenAction" >
<property name="icon" >
- <iconset>image1</iconset>
+ <iconset resource="../muse.qrc" >:/xpm/fileopen.png</iconset>
</property>
<property name="text" >
<string>&amp;Open...</string>
@@ -731,7 +921,7 @@ handled like normal controllers.</string>
</action>
<action name="fileSaveAction" >
<property name="icon" >
- <iconset>image2</iconset>
+ <iconset resource="../muse.qrc" >:/xpm/filesave.png</iconset>
</property>
<property name="text" >
<string>&amp;Save</string>
@@ -758,6 +948,9 @@ handled like normal controllers.</string>
</property>
</action>
<action name="fileExitAction" >
+ <property name="icon" >
+ <iconset resource="../muse.qrc" >:/xpm/off.svg</iconset>
+ </property>
<property name="text" >
<string>E&amp;xit</string>
</property>
@@ -773,5 +966,22 @@ handled like normal controllers.</string>
<resources>
<include location="../muse.qrc" />
</resources>
- <connections/>
+ <connections>
+ <connection>
+ <sender>toolBar</sender>
+ <signal>actionTriggered(QAction*)</signal>
+ <receiver>EditInstrumentBase</receiver>
+ <slot>close()</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>34</x>
+ <y>58</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>161</x>
+ <y>546</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
</ui>
diff --git a/muse/muse/instruments/minstrument.cpp b/muse/muse/instruments/minstrument.cpp
index ae02dd3c..3e353a13 100644
--- a/muse/muse/instruments/minstrument.cpp
+++ b/muse/muse/instruments/minstrument.cpp
@@ -31,6 +31,25 @@ MidiInstrumentList midiInstruments;
MidiInstrument* genericMidiInstrument;
//---------------------------------------------------------
+// string2sysex
+//---------------------------------------------------------
+
+int string2sysex(const QString&, unsigned char** data)
+ {
+ *data = 0;
+ return 0;
+ }
+
+//---------------------------------------------------------
+// sysex2string
+//---------------------------------------------------------
+
+QString sysex2string(int, unsigned char*)
+ {
+ return QString("");
+ }
+
+//---------------------------------------------------------
// Patch
//---------------------------------------------------------
@@ -57,6 +76,8 @@ static void loadIDF(QFileInfo* fi)
printf("cannot open file %s\n", fi->fileName().toLatin1().data());
return;
}
+ if (debugMsg)
+ printf(" load instrument definition <%s>\n", fi->filePath().toLocal8Bit().data());
QDomDocument doc;
int line, column;
QString err;
@@ -82,7 +103,19 @@ static void loadIDF(QFileInfo* fi)
MidiInstrument* i = new MidiInstrument();
i->read(n);
i->setFilePath(fi->filePath());
- midiInstruments.push_back(i);
+ 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;
}
}
}
@@ -116,6 +149,19 @@ void initMidiInstruments()
loadIDF(&fi);
}
}
+ QString path2 = QDir::homePath() + "/" + config.instrumentPath;
+ if (debugMsg)
+ printf("load instrument definitions from <%s>\n", path2.toLatin1().data());
+ QDir instrumentsDir2(path2, QString("*.idf"),
+ QDir::SortFlags(QDir::Name | QDir::IgnoreCase), QDir::Files);
+ if (instrumentsDir2.exists()) {
+ QFileInfoList list = instrumentsDir2.entryInfoList();
+ int n = list.size();
+ for (int i = 0; i < n; ++i) {
+ QFileInfo fi = list.at(i);
+ loadIDF(&fi);
+ }
+ }
}
//---------------------------------------------------------
@@ -353,19 +399,20 @@ void MidiInstrument::read(QDomNode node)
else if (tag == "Init")
_midiInit->read(node.firstChild(), true);
else if (tag == "SysEx") {
- SysEx se;
- se.name = e.attribute("name");
+ SysEx* se = new SysEx;
+ se->name = e.attribute("name");
for (QDomNode nnode = node.firstChild(); !nnode.isNull(); nnode = nnode.nextSibling()) {
e = nnode.toElement();
QString tag(e.tagName());
if (tag == "comment")
- se.comment = e.text();
- else if (tag == "data")
- se.data = e.text();
+ se->comment = e.text();
+ else if (tag == "data") {
+ se->dataLen = string2sysex(e.text(), &(se->data));
+ }
else
printf("MidiInstrument::read():SysEx: unknown tag %s\n", tag.toLatin1().data());
}
- sysex.push_back(se);
+ _sysex.append(se);
}
else if (!tag.isEmpty()) {
printf("MidiInstrument::read(): unknown tag %s\n", tag.toLatin1().data());
diff --git a/muse/muse/instruments/minstrument.h b/muse/muse/instruments/minstrument.h
index 5c7b081e..5bcf2616 100644
--- a/muse/muse/instruments/minstrument.h
+++ b/muse/muse/instruments/minstrument.h
@@ -71,7 +71,8 @@ struct PatchGroup {
struct SysEx {
QString name;
QString comment;
- QString data;
+ int dataLen;
+ unsigned char* data;
};
//---------------------------------------------------------
@@ -81,7 +82,7 @@ struct SysEx {
class MidiInstrument {
std::vector<PatchGroup> pg;
MidiControllerList* _controller;
- std::vector<SysEx> sysex;
+ QList<SysEx*> _sysex;
bool _dirty;
bool _readonly;
@@ -127,11 +128,15 @@ class MidiInstrument {
virtual void populatePatchPopup(QMenu*, int);
void read(QDomNode);
void write(Xml& xml);
- std::vector<SysEx>* sysexList() { return &sysex; }
+ const QList<SysEx*>& sysex() const { return _sysex; }
+ void removeSysex(SysEx* sysex) { _sysex.removeAll(sysex); }
+ void addSysex(SysEx* sysex) { _sysex.append(sysex); }
+
MidiController* midiController(int num) const;
- std::vector<PatchGroup>* groups() { return &pg; }
+ std::vector<PatchGroup>* groups() { return &pg; }
const QList<QString>& categories() const { return _categories; }
+ void addCategory(const QString& s) { _categories.append(s); }
};
//---------------------------------------------------------
@@ -144,6 +149,7 @@ class MidiInstrumentList : public QList<MidiInstrument*> {
typedef MidiInstrumentList::iterator iMidiInstrument;
extern MidiInstrumentList midiInstruments;
+
extern MidiInstrument* genericMidiInstrument;
extern void initMidiInstruments();
extern MidiInstrument* registerMidiInstrument(const QString&);
diff --git a/muse/muse/midictrl.h b/muse/muse/midictrl.h
index 895695e0..067aad6a 100644
--- a/muse/muse/midictrl.h
+++ b/muse/muse/midictrl.h
@@ -141,14 +141,10 @@ class MidiController {
// - implicit during import of a midi file
//---------------------------------------------------------
-class MidiControllerList : public std::list<MidiController*> {
- public:
- MidiControllerList() {}
- };
+class MidiControllerList : public QList<MidiController*> {};
typedef MidiControllerList::iterator iMidiController;
typedef MidiControllerList::const_iterator ciMidiController;
-typedef MidiControllerList MidiControllerList;
extern MidiControllerList defaultMidiController;
extern void initMidiController();
diff --git a/muse/muse/muse.cpp b/muse/muse/muse.cpp
index 156683ce..fa37cec5 100644
--- a/muse/muse/muse.cpp
+++ b/muse/muse/muse.cpp
@@ -2763,6 +2763,42 @@ void MusE::setGlobalTempo(int val)
int main(int argc, char* argv[])
{
+ char c;
+ QString opts("mvdDiosP:p");
+
+#ifdef VST_SUPPORT
+ opts += "V";
+#endif
+#ifdef DSSI_SUPPORT
+ opts += "I";
+#endif
+ while ((c = getopt(argc, argv, opts.toLatin1().data())) != EOF) {
+ switch (c) {
+ case 'v': printVersion(argv[0]); return 0;
+ case 'd':
+ debugMode = true;
+ realTimePriority = false;
+ break;
+ case 'm': midiOnly = true; break;
+ case 'D': debugMsg = true; break;
+ case 'i': midiInputTrace = true; break;
+ case 'o': midiOutputTrace = true; break;
+ case 's': debugSync = true; break;
+ case 'p': loadPlugins = false; break;
+ case 'V': loadVST = false; break;
+ case 'I': loadDSSI = false; break;
+ default: usage(argv[0], "bad argument"); return -1;
+ }
+ }
+ if (midiOnly) {
+ loadDSSI = false;
+ loadPlugins = false;
+ loadVST = false;
+ }
+
+
+
+
museUser = QString(getenv("MUSEHOME"));
if (museUser.isEmpty())
museUser = QDir::homePath();
@@ -2810,39 +2846,6 @@ int main(int argc, char* argv[])
}
}
- char c;
- QString opts("mvdDiosP:p");
-
-#ifdef VST_SUPPORT
- opts += "V";
-#endif
-#ifdef DSSI_SUPPORT
- opts += "I";
-#endif
- while ((c = getopt(argc, argv, opts.toLatin1().data())) != EOF) {
- switch (c) {
- case 'v': printVersion(argv[0]); return 0;
- case 'd':
- debugMode = true;
- realTimePriority = false;
- break;
- case 'm': midiOnly = true; break;
- case 'D': debugMsg = true; break;
- case 'i': midiInputTrace = true; break;
- case 'o': midiOutputTrace = true; break;
- case 's': debugSync = true; break;
- case 'p': loadPlugins = false; break;
- case 'V': loadVST = false; break;
- case 'I': loadDSSI = false; break;
- default: usage(argv[0], "bad argument"); return -1;
- }
- }
- if (midiOnly) {
- loadDSSI = false;
- loadPlugins = false;
- loadVST = false;
- }
-
bool useJACK = !(debugMode || midiOnly);
if (useJACK) {
if (initJackAudio()) {
@@ -2988,7 +2991,7 @@ int main(int argc, char* argv[])
// check for instruments directory:
- pd.setPath(QDir::homePath() + "/MusE/instruments");
+ pd.setPath(QDir::homePath() + "/" + config.instrumentPath);
if (!pd.exists()) {
// ask user to create a new instruments directory
QString title(QT_TR_NOOP("MusE: create instruments directory"));
diff --git a/muse/muse/preferences.cpp b/muse/muse/preferences.cpp
index e0b9b4be..bcd1aa02 100644
--- a/muse/muse/preferences.cpp
+++ b/muse/muse/preferences.cpp
@@ -328,6 +328,7 @@ PreferencesDialog::PreferencesDialog(Arranger* a, QWidget* parent)
showSplash->setChecked(config->showSplashScreen);
projectPath->setText(config->projectPath);
templatePath->setText(config->templatePath);
+ instrumentPath->setText(config->instrumentPath);
midiImportPath->setText(config->importMidiPath);
waveImportPath->setText(config->importWavePath);
@@ -590,6 +591,7 @@ void PreferencesDialog::apply()
::config.projectPath = projectPath->text();
::config.templatePath = templatePath->text();
+ ::config.instrumentPath = instrumentPath->text();
::config.importMidiPath = midiImportPath->text();
::config.importWavePath = waveImportPath->text();
diff --git a/muse/muse/preferences.ui b/muse/muse/preferences.ui
index c7adf58f..1c3d5ca5 100644
--- a/muse/muse/preferences.ui
+++ b/muse/muse/preferences.ui
@@ -139,46 +139,88 @@
<property name="spacing" >
<number>6</number>
</property>
- <item row="1" column="3" >
- <widget class="QLineEdit" name="waveImportPath" />
- </item>
- <item row="0" column="3" >
- <widget class="QLineEdit" name="midiImportPath" />
- </item>
- <item row="1" column="1" >
- <widget class="QLineEdit" name="templatePath" />
+ <item row="0" column="0" >
+ <widget class="QLabel" name="label" >
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Projects</string>
+ </property>
+ </widget>
</item>
<item row="0" column="1" >
<widget class="QLineEdit" name="projectPath" />
</item>
<item row="0" column="2" >
<widget class="QLabel" name="label_36" >
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
<property name="text" >
<string>Midi Import</string>
</property>
</widget>
</item>
- <item row="1" column="2" >
- <widget class="QLabel" name="label_37" >
+ <item row="0" column="3" colspan="2" >
+ <widget class="QLineEdit" name="midiImportPath" />
+ </item>
+ <item row="1" column="0" >
+ <widget class="QLabel" name="label_35" >
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
<property name="text" >
- <string>Wave Import</string>
+ <string>Templates</string>
</property>
</widget>
</item>
- <item row="0" column="0" >
- <widget class="QLabel" name="label" >
+ <item row="1" column="1" >
+ <widget class="QLineEdit" name="templatePath" />
+ </item>
+ <item row="1" column="2" >
+ <widget class="QLabel" name="label_37" >
<property name="text" >
- <string>Projects</string>
+ <string>Wave Import</string>
</property>
</widget>
</item>
- <item row="1" column="0" >
- <widget class="QLabel" name="label_35" >
+ <item row="1" column="3" colspan="2" >
+ <widget class="QLineEdit" name="waveImportPath" />
+ </item>
+ <item row="2" column="0" >
+ <widget class="QLabel" name="label_38" >
+ <property name="sizePolicy" >
+ <sizepolicy>
+ <hsizetype>0</hsizetype>
+ <vsizetype>0</vsizetype>
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
<property name="text" >
- <string>Templates</string>
+ <string>Instruments</string>
</property>
</widget>
</item>
+ <item row="2" column="1" >
+ <widget class="QLineEdit" name="instrumentPath" />
+ </item>
</layout>
</widget>
</item>
@@ -2243,6 +2285,11 @@
</widget>
<customwidgets>
<customwidget>
+ <class>RasterCombo</class>
+ <extends>QComboBox</extends>
+ <header>rastercombo.h</header>
+ </customwidget>
+ <customwidget>
<class>QuantCombo</class>
<extends>QComboBox</extends>
<header>quantcombo.h</header>
@@ -2257,11 +2304,6 @@
<extends>QToolButton</extends>
<header>recordbutton.h</header>
</customwidget>
- <customwidget>
- <class>RasterCombo</class>
- <extends>QComboBox</extends>
- <header>rastercombo.h</header>
- </customwidget>
</customwidgets>
<resources/>
<connections>