diff options
-rw-r--r-- | muse/muse/conf.cpp | 1 | ||||
-rw-r--r-- | muse/muse/ctrl.cpp | 4 | ||||
-rw-r--r-- | muse/muse/ctrl.h | 4 | ||||
-rw-r--r-- | muse/muse/gconfig.cpp | 1 | ||||
-rw-r--r-- | muse/muse/gconfig.h | 1 | ||||
-rw-r--r-- | muse/muse/instruments/editinstrument.cpp | 634 | ||||
-rw-r--r-- | muse/muse/instruments/editinstrument.h | 20 | ||||
-rw-r--r-- | muse/muse/instruments/editinstrument.ui | 812 | ||||
-rw-r--r-- | muse/muse/instruments/minstrument.cpp | 61 | ||||
-rw-r--r-- | muse/muse/instruments/minstrument.h | 14 | ||||
-rw-r--r-- | muse/muse/midictrl.h | 6 | ||||
-rw-r--r-- | muse/muse/muse.cpp | 71 | ||||
-rw-r--r-- | muse/muse/preferences.cpp | 2 | ||||
-rw-r--r-- | muse/muse/preferences.ui | 86 |
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>&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>&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>&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&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> |