diff options
Diffstat (limited to 'attic/muse_qt4_evolution/muse/instruments')
8 files changed, 3220 insertions, 0 deletions
diff --git a/attic/muse_qt4_evolution/muse/instruments/CMakeLists.txt b/attic/muse_qt4_evolution/muse/instruments/CMakeLists.txt new file mode 100644 index 00000000..b86764d4 --- /dev/null +++ b/attic/muse_qt4_evolution/muse/instruments/CMakeLists.txt @@ -0,0 +1,41 @@ +#============================================================================= +# MusE +# Linux Music Editor +# $Id:$ +# +# Copyright (C) 2002-2006 by Werner Schweer and others +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +#============================================================================= + +QT4_WRAP_CPP ( instruments_mocs + minstrument.h editinstrument.h + ) + +QT4_WRAP_UI ( instruments_ui_headers + editinstrument.ui + ) + +add_library ( instruments STATIC + minstrument.cpp + editinstrument.cpp + minstrument.h + editinstrument.h + ${instruments_mocs} + ${instruments_ui_headers} + ) + +set_target_properties( instruments + PROPERTIES COMPILE_FLAGS "-include ${PROJECT_BINARY_DIR}/all.h" + ) + diff --git a/attic/muse_qt4_evolution/muse/instruments/editinstrument.cpp b/attic/muse_qt4_evolution/muse/instruments/editinstrument.cpp new file mode 100644 index 00000000..823a20e3 --- /dev/null +++ b/attic/muse_qt4_evolution/muse/instruments/editinstrument.cpp @@ -0,0 +1,844 @@ +//============================================================================= +// MusE +// Linux Music Editor +// $Id:$ +// +// Copyright (C) 2002-2006 by Werner Schweer and others +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +//============================================================================= + +#include "editinstrument.h" +#include "minstrument.h" +#include "ctrl.h" +#include "midictrl.h" +#include "al/xml.h" +#include "gconfig.h" + +extern int string2sysex(const QString& s, unsigned char** data); +extern QString sysex2string(int len, unsigned char* data); + +//--------------------------------------------------------- +// EditInstrument +//--------------------------------------------------------- + +EditInstrument::EditInstrument(QWidget* parent) + : QMainWindow(parent) + { + setupUi(this); + // populate instrument list + for (iMidiInstrument i = midiInstruments.begin(); i != midiInstruments.end(); ++i) { + QListWidgetItem* item = new QListWidgetItem((*i)->iname()); + QVariant v = qVariantFromValue((void*)(*i)); + item->setData(Qt::UserRole, v); + instrumentList->addItem(item); + } + instrumentList->setItemSelected(instrumentList->item(0), true); + connect(instrumentList, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)), + SLOT(instrumentChanged(QListWidgetItem*,QListWidgetItem*))); + connect(patchView, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), + SLOT(patchChanged(QTreeWidgetItem*, QTreeWidgetItem*))); + instrumentChanged(instrumentList->item(0), instrumentList->item(0)); + connect(listController, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)), + SLOT(controllerChanged(QListWidgetItem*, QListWidgetItem*))); + connect(sysexList, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)), + SLOT(sysexChanged(QListWidgetItem*, 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(fileExitAction, SIGNAL(triggered()), SLOT(close())); + + 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())); + + connect(ctrlType,SIGNAL(activated(int)), SLOT(ctrlTypeChanged(int))); + } + +//--------------------------------------------------------- +// 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); + updateInstrument(instrument); + 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; + if (instrument->filePath().isEmpty()) + path += QString("/%1.idf").arg(instrument->iname()); + else { + QFileInfo fi(instrument->filePath()); + path += QString("/%1.idf").arg(fi.baseName()); + } + 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-%1").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*)nsysex); + item->setData(Qt::UserRole, v); + sysexList->addItem(item); + sysexList->setCurrentItem(item); + instrument->setDirty(true); + } + +//--------------------------------------------------------- +// instrumentChanged +//--------------------------------------------------------- + +void EditInstrument::instrumentChanged(QListWidgetItem* sel, QListWidgetItem* old) + { + if (sel == 0) + return; + if (old) { + MidiInstrument* oi = (MidiInstrument*)old->data(Qt::UserRole).value<void*>(); + checkDirty(oi); + oi->setDirty(false); + } + + patchView->clear(); + listController->clear(); + category->clear(); + sysexList->clear(); + + // 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) { + QTreeWidgetItem* item = new QTreeWidgetItem; + item->setText(0, g->name); + QVariant v = QVariant::fromValue((void*)0); + item->setData(0, Qt::UserRole, v); + patchView->addTopLevelItem(item); + for (iPatch p = g->patches.begin(); p != g->patches.end(); ++p) { + Patch* patch = *p; + QTreeWidgetItem* sitem = new QTreeWidgetItem; + sitem->setText(0, patch->name); + QVariant v = QVariant::fromValue((void*)patch); + sitem->setData(0, Qt::UserRole, v); + item->addChild(sitem); + } + } + MidiControllerList* cl = instrument->controller(); + for (iMidiController ic = cl->begin(); ic != cl->end(); ++ic) { + MidiController* c = *ic; + QListWidgetItem* item = new QListWidgetItem(c->name()); + QVariant v = QVariant::fromValue((void*)c); + item->setData(Qt::UserRole, v); + listController->addItem(item); + } + listController->setItemSelected(listController->item(0), true); + controllerChanged(listController->item(0), 0); + + category->addItems(instrument->categories()); + + foreach(const SysEx* s, instrument->sysex()) { + QListWidgetItem* item = new QListWidgetItem(s->name); + QVariant v = QVariant::fromValue((void*)s); + item->setData(Qt::UserRole, v); + sysexList->addItem(item); + } + + sysexList->setItemSelected(sysexList->item(0), true); + sysexChanged(sysexList->item(0), 0); + + if (!cl->empty()) { + listController->setItemSelected(listController->item(0), true); + controllerChanged(listController->item(0), 0); + } + } + +//--------------------------------------------------------- +// updatePatch +//--------------------------------------------------------- + +void EditInstrument::updatePatch(MidiInstrument* instrument, Patch* p) + { + 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); + } + } + +//--------------------------------------------------------- +// 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*>(); + updatePatch(instrument, p); + } + 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); + } + +//--------------------------------------------------------- +// updateController +//--------------------------------------------------------- + +void EditInstrument::updateController(MidiInstrument* instrument, MidiController* oc) + { + int ctrlH = spinBoxHCtrlNo->value(); + int ctrlL = spinBoxLCtrlNo->value(); + MidiController::ControllerType type = (MidiController::ControllerType)ctrlType->currentIndex(); + int num = MidiController::genNum(type, ctrlH, ctrlL); + + if (num != oc->num()) { + oc->setNum(num); + instrument->setDirty(true); + } + if (spinBoxMin->value() != oc->minVal()) { + oc->setMinVal(spinBoxMin->value()); + instrument->setDirty(true); + } + if (spinBoxMax->value() != oc->maxVal()) { + oc->setMaxVal(spinBoxMax->value()); + instrument->setDirty(true); + } + if (spinBoxDefault->value() != oc->initVal()) { + oc->setInitVal(spinBoxDefault->value()); + instrument->setDirty(true); + } + if (moveWithPart->isChecked() ^ oc->moveWithPart()) { + oc->setMoveWithPart(moveWithPart->isChecked()); + instrument->setDirty(true); + } + if (ctrlName->text() != oc->name()) { + oc->setName(ctrlName->text()); + instrument->setDirty(true); + } + if (ctrlComment->toPlainText() != oc->comment()) { + oc->setComment(ctrlComment->toPlainText()); + instrument->setDirty(true); + } + } + +//--------------------------------------------------------- +// controllerChanged +//--------------------------------------------------------- + +void EditInstrument::controllerChanged(QListWidgetItem* sel, QListWidgetItem* old) + { + if (old) { + QListWidgetItem* item = instrumentList->currentItem(); + if (item == 0) + return; + MidiInstrument* instrument = (MidiInstrument*)item->data(Qt::UserRole).value<void*>(); + MidiController* oc = (MidiController*)old->data(Qt::UserRole).value<void*>(); + updateController(instrument, oc); + } + if (sel == 0 || sel->data(Qt::UserRole).value<void*>() == 0) { + ctrlName->setText(""); + ctrlComment->setText(""); + return; + } + MidiController* c = (MidiController*)sel->data(Qt::UserRole).value<void*>(); + ctrlName->setText(c->name()); + ctrlComment->setText(c->comment()); + int ctrlH = (c->num() >> 8) & 0x7f; + int ctrlL = c->num() & 0x7f; + int type = int(c->type()); + ctrlType->setCurrentIndex(type); + ctrlTypeChanged(type); + spinBoxHCtrlNo->setValue(ctrlH); + spinBoxLCtrlNo->setValue(ctrlL); + spinBoxMin->setValue(c->minVal()); + spinBoxMax->setValue(c->maxVal()); + spinBoxDefault->setRange(c->minVal()-1, c->maxVal()); + spinBoxDefault->setValue(c->initVal()); + moveWithPart->setChecked(c->moveWithPart()); + } + +//--------------------------------------------------------- +// updateSysex +//--------------------------------------------------------- + +void EditInstrument::updateSysex(MidiInstrument* instrument, SysEx* so) + { + if (sysexName->text() != so->name) { + so->name = sysexName->text(); + instrument->setDirty(true); + } + if (sysexComment->toPlainText() != so->comment) { + so->comment = sysexComment->toPlainText(); + instrument->setDirty(true); + } + unsigned char* data; + int len = string2sysex(sysexData->toPlainText(), &data); + if (so->dataLen != len || !memcmp(data, so->data, len)) { + delete so->data; + so->data = data; + so->dataLen = len; + } + } + +//--------------------------------------------------------- +// sysexChanged +//--------------------------------------------------------- + +void EditInstrument::sysexChanged(QListWidgetItem* sel, QListWidgetItem* old) + { + if (old) { + QListWidgetItem* item = instrumentList->currentItem(); + if (item == 0) + return; + MidiInstrument* instrument = (MidiInstrument*)item->data(Qt::UserRole).value<void*>(); + SysEx* so = (SysEx*)item->data(Qt::UserRole).value<void*>(); + updateSysex(instrument, so); + } + if (sel == 0) { + sysexName->setText(""); + sysexComment->setText(""); + sysexData->setText(""); + sysexName->setEnabled(false); + sysexComment->setEnabled(false); + sysexData->setEnabled(false); + return; + } + sysexName->setEnabled(true); + sysexComment->setEnabled(true); + sysexData->setEnabled(true); + + SysEx* sx = (SysEx*)sel->data(Qt::UserRole).value<void*>(); + sysexName->setText(sx->name); + sysexComment->setText(sx->comment); + sysexData->setText(sysex2string(sx->dataLen, sx->data)); + } + +//--------------------------------------------------------- +// checkDirty +// return true on Abort +//--------------------------------------------------------- + +bool EditInstrument::checkDirty(MidiInstrument* i) + { + updateInstrument(i); + 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; + } + +//--------------------------------------------------------- +// ctrlTypeChanged +//--------------------------------------------------------- + +void EditInstrument::ctrlTypeChanged(int idx) + { + MidiController::ControllerType t = (MidiController::ControllerType)idx; + switch (t) { + case MidiController::RPN: + case MidiController::NRPN: + case MidiController::Controller7: + spinBoxHCtrlNo->setEnabled(false); + spinBoxLCtrlNo->setEnabled(true); + break; + case MidiController::Controller14: + case MidiController::RPN14: + case MidiController::NRPN14: + spinBoxHCtrlNo->setEnabled(true); + spinBoxLCtrlNo->setEnabled(true); + break; + case MidiController::Pitch: + case MidiController::Program: + spinBoxHCtrlNo->setEnabled(false); + spinBoxLCtrlNo->setEnabled(false); + break; + default: + break; + } + } + +//--------------------------------------------------------- +// updateInstrument +//--------------------------------------------------------- + +void EditInstrument::updateInstrument(MidiInstrument* instrument) + { + QListWidgetItem* sysexItem = sysexList->currentItem(); + if (sysexItem) { + SysEx* so = (SysEx*)sysexItem->data(Qt::UserRole).value<void*>(); + updateSysex(instrument, so); + } + QListWidgetItem* ctrlItem = listController->currentItem(); + if (ctrlItem) { + MidiController* ctrl = (MidiController*)ctrlItem->data(Qt::UserRole).value<void*>(); + updateController(instrument, ctrl); + } + QTreeWidgetItem* patchItem = patchView->currentItem(); + if (patchItem) { + Patch* p = (Patch*)patchItem->data(0, Qt::UserRole).value<void*>(); + updatePatch(instrument, p); + } + } + diff --git a/attic/muse_qt4_evolution/muse/instruments/editinstrument.h b/attic/muse_qt4_evolution/muse/instruments/editinstrument.h new file mode 100644 index 00000000..cefafe74 --- /dev/null +++ b/attic/muse_qt4_evolution/muse/instruments/editinstrument.h @@ -0,0 +1,70 @@ +//============================================================================= +// MusE +// Linux Music Editor +// $Id:$ +// +// Copyright (C) 2002-2006 by Werner Schweer and others +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +//============================================================================= + +#ifndef __EDITINSTRUMENT_H__ +#define __EDITINSTRUMENT_H__ + +#include "ui_editinstrument.h" + +class MidiInstrument; +class SysEx; +class MidiController; +struct Patch; + +//--------------------------------------------------------- +// EditInstrument +//--------------------------------------------------------- + +class EditInstrument : public QMainWindow, public Ui::EditInstrumentBase { + Q_OBJECT + + bool fileSave(MidiInstrument*, const QString& name); + void closeEvent(QCloseEvent*); + bool checkDirty(MidiInstrument*); + void updateInstrument(MidiInstrument*); + void updateSysex(MidiInstrument*, SysEx*); + void updateController(MidiInstrument*, MidiController*); + void updatePatch(MidiInstrument* instrument, Patch* p); + + private slots: + virtual void fileNew(); + virtual void fileSave(); + virtual void fileSaveAs(); + void instrumentChanged(QListWidgetItem*, QListWidgetItem*); + void patchChanged(QTreeWidgetItem*, QTreeWidgetItem*); + void controllerChanged(QListWidgetItem*, QListWidgetItem*); + void sysexChanged(QListWidgetItem*, QListWidgetItem*); + void instrumentNameChanged(const QString&); + void deletePatchClicked(); + void newPatchClicked(); + void newGroupClicked(); + void newCategoryClicked(); + void deleteControllerClicked(); + void newControllerClicked(); + void deleteSysexClicked(); + void newSysexClicked(); + void ctrlTypeChanged(int); + + public: + EditInstrument(QWidget* parent = 0); + }; + +#endif + diff --git a/attic/muse_qt4_evolution/muse/instruments/editinstrument.ui b/attic/muse_qt4_evolution/muse/instruments/editinstrument.ui new file mode 100644 index 00000000..f58d9d28 --- /dev/null +++ b/attic/muse_qt4_evolution/muse/instruments/editinstrument.ui @@ -0,0 +1,998 @@ +<ui version="4.0" > + <class>EditInstrumentBase</class> + <widget class="QMainWindow" name="EditInstrumentBase" > + <property name="geometry" > + <rect> + <x>0</x> + <y>0</y> + <width>821</width> + <height>551</height> + </rect> + </property> + <property name="windowTitle" > + <string>MusE: Instrument Editor</string> + </property> + <widget class="QWidget" name="widget" > + <layout class="QVBoxLayout" > + <property name="margin" > + <number>9</number> + </property> + <property name="spacing" > + <number>6</number> + </property> + <item> + <widget class="QSplitter" name="splitter_3" > + <property name="orientation" > + <enum>Qt::Horizontal</enum> + </property> + <widget class="QListWidget" name="instrumentList" > + <property name="sizePolicy" > + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>7</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="resizeMode" > + <enum>QListView::Adjust</enum> + </property> + <property name="layoutMode" > + <enum>QListView::Batched</enum> + </property> + </widget> + <widget class="QWidget" name="layoutWidget" > + <layout class="QVBoxLayout" > + <property name="margin" > + <number>0</number> + </property> + <property name="spacing" > + <number>6</number> + </property> + <item> + <layout class="QHBoxLayout" > + <property name="margin" > + <number>0</number> + </property> + <property name="spacing" > + <number>6</number> + </property> + <item> + <widget class="QLabel" name="label" > + <property name="text" > + <string>Instrument Name:</string> + </property> + </widget> + </item> + <item> + <widget class="QLineEdit" name="instrumentName" /> + </item> + </layout> + </item> + <item> + <widget class="QTabWidget" name="tabWidget3" > + <property name="currentIndex" > + <number>0</number> + </property> + <widget class="QWidget" name="tab" > + <attribute name="title" > + <string>Patches</string> + </attribute> + <layout class="QVBoxLayout" > + <property name="margin" > + <number>9</number> + </property> + <property name="spacing" > + <number>6</number> + </property> + <item> + <widget class="QSplitter" name="splitter" > + <property name="orientation" > + <enum>Qt::Horizontal</enum> + </property> + <widget class="QTreeWidget" name="patchView" > + <property name="sizePolicy" > + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>7</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="rootIsDecorated" > + <bool>true</bool> + </property> + <column> + <property name="text" > + <string>Patch/Group</string> + </property> + </column> + </widget> + <widget class="QWidget" name="layoutWidget" > + <layout class="QGridLayout" > + <property name="margin" > + <number>0</number> + </property> + <property name="spacing" > + <number>6</number> + </property> + <item row="0" column="1" colspan="2" > + <widget class="QLineEdit" name="patchNameEdit" /> + </item> + <item row="0" column="0" > + <widget class="QLabel" name="textLabelPatchName" > + <property name="text" > + <string>Patch Name:</string> + </property> + </widget> + </item> + <item row="4" column="0" > + <widget class="QLabel" name="textLabel4_3" > + <property name="text" > + <string>Program:</string> + </property> + </widget> + </item> + <item row="7" column="0" colspan="3" > + <layout class="QHBoxLayout" > + <property name="margin" > + <number>0</number> + </property> + <property name="spacing" > + <number>6</number> + </property> + <item> + <widget class="QToolButton" name="deletePatch" > + <property name="sizePolicy" > + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text" > + <string>&Delete</string> + </property> + <property name="shortcut" > + <string>Alt+D</string> + </property> + </widget> + </item> + <item> + <widget class="QToolButton" name="newPatch" > + <property name="sizePolicy" > + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>1</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="text" > + <string>&New Patch</string> + </property> + <property name="shortcut" > + <string>Alt+N</string> + </property> + </widget> + </item> + <item> + <widget class="QToolButton" name="newGroup" > + <property name="text" > + <string>New Group</string> + </property> + </widget> + </item> + <item> + <spacer> + <property name="orientation" > + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType" > + <enum>QSizePolicy::Expanding</enum> + </property> + <property name="sizeHint" > + <size> + <width>240</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="newCategory" > + <property name="text" > + <string>New Category</string> + </property> + </widget> + </item> + </layout> + </item> + <item row="3" column="2" > + <spacer> + <property name="orientation" > + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType" > + <enum>QSizePolicy::Expanding</enum> + </property> + <property name="sizeHint" > + <size> + <width>280</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="4" column="2" > + <spacer> + <property name="orientation" > + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType" > + <enum>QSizePolicy::Expanding</enum> + </property> + <property name="sizeHint" > + <size> + <width>280</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="2" column="2" > + <spacer> + <property name="orientation" > + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeType" > + <enum>QSizePolicy::Expanding</enum> + </property> + <property name="sizeHint" > + <size> + <width>280</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item row="3" column="1" > + <widget class="QSpinBox" name="spinBoxLBank" > + <property name="specialValueText" > + <string>d.c.</string> + </property> + <property name="maximum" > + <number>127</number> + </property> + <property name="minimum" > + <number>-1</number> + </property> + <property name="value" > + <number>-1</number> + </property> + </widget> + </item> + <item row="2" column="0" > + <widget class="QLabel" name="textLabel2_2" > + <property name="text" > + <string>High Bank:</string> + </property> + </widget> + </item> + <item row="3" column="0" > + <widget class="QLabel" name="textLabel3_2" > + <property name="text" > + <string>Low Bank:</string> + </property> + </widget> + </item> + <item row="6" column="2" > + <spacer> + <property name="orientation" > + <enum>Qt::Vertical</enum> + </property> + <property name="sizeType" > + <enum>QSizePolicy::Expanding</enum> + </property> + <property name="sizeHint" > + <size> + <width>20</width> + <height>90</height> + </size> + </property> + </spacer> + </item> + <item row="2" column="1" > + <widget class="QSpinBox" name="spinBoxHBank" > + <property name="specialValueText" > + <string>d.c.</string> + </property> + <property name="maximum" > + <number>127</number> + </property> + <property name="minimum" > + <number>-1</number> + </property> + <property name="value" > + <number>-1</number> + </property> + </widget> + </item> + <item row="4" column="1" > + <widget class="QSpinBox" name="spinBoxProgram" /> + </item> + <item row="5" column="0" colspan="3" > + <layout class="QHBoxLayout" > + <property name="margin" > + <number>0</number> + </property> + <property name="spacing" > + <number>6</number> + </property> + <item> + <widget class="QCheckBox" name="checkBoxDrum" > + <property name="text" > + <string>Drum</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="checkBoxGM" > + <property name="text" > + <string>GM</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="checkBoxGS" > + <property name="text" > + <string>GS</string> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="checkBoxXG" > + <property name="text" > + <string>XG</string> + </property> + </widget> + </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> + </item> + </layout> + </widget> + <widget class="QWidget" name="tab" > + <attribute name="title" > + <string>Controller</string> + </attribute> + <layout class="QVBoxLayout" > + <property name="margin" > + <number>9</number> + </property> + <property name="spacing" > + <number>6</number> + </property> + <item> + <widget class="QSplitter" name="splitter_2" > + <property name="orientation" > + <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="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> + </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 row="0" column="2" > + <widget class="QLineEdit" name="ctrlName" /> + </item> + <item row="1" column="0" colspan="2" > + <widget class="QLabel" name="label_2" > + <property name="text" > + <string>Comment</string> + </property> + </widget> + </item> + <item row="1" column="2" > + <widget class="QTextEdit" name="ctrlComment" /> + </item> + <item row="2" column="0" > + <widget class="QLabel" name="TextLabel2_4" > + <property name="text" > + <string>Type</string> + </property> + </widget> + </item> + <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="ctrlType" > + <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>8388607</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" > + <property name="specialValueText" > + <string>??</string> + </property> + <property name="minimum" > + <number>-1</number> + </property> + </widget> + </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> + </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>Delete</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="newController" > + <property name="text" > + <string>New Controller</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> + </widget> + <widget class="QWidget" name="TabPage" > + <attribute name="title" > + <string>SysEx</string> + </attribute> + <layout class="QVBoxLayout" > + <property name="margin" > + <number>9</number> + </property> + <property name="spacing" > + <number>6</number> + </property> + <item> + <widget class="QSplitter" name="splitter_4" > + <property name="orientation" > + <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>7</hsizetype> + <vsizetype>7</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="resizeMode" > + <enum>QListView::Adjust</enum> + </property> + <property name="uniformItemSizes" > + <bool>true</bool> + </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> + </widget> + </widget> + </item> + </layout> + </widget> + </widget> + </item> + </layout> + </widget> + <widget class="QMenuBar" name="MenuBar" > + <property name="geometry" > + <rect> + <x>0</x> + <y>0</y> + <width>821</width> + <height>32</height> + </rect> + </property> + <property name="defaultUp" > + <bool>false</bool> + </property> + <widget class="QMenu" name="fileMenu" > + <property name="geometry" > + <rect> + <x>434</x> + <y>167</y> + <width>146</width> + <height>168</height> + </rect> + </property> + <property name="title" > + <string>&File</string> + </property> + <addaction name="fileNewAction" /> + <addaction name="fileSaveAction" /> + <addaction name="fileSaveAsAction" /> + <addaction name="separator" /> + <addaction name="fileExitAction" /> + </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 resource="../muse.qrc" >:/xpm/filenew.png</iconset> + </property> + <property name="text" > + <string>&New</string> + </property> + <property name="iconText" > + <string>New</string> + </property> + <property name="shortcut" > + <string>Ctrl+N</string> + </property> + </action> + <action name="fileOpenAction" > + <property name="icon" > + <iconset resource="../muse.qrc" >:/xpm/fileopen.png</iconset> + </property> + <property name="text" > + <string>&Open...</string> + </property> + <property name="iconText" > + <string>Open</string> + </property> + <property name="shortcut" > + <string>Ctrl+O</string> + </property> + </action> + <action name="fileSaveAction" > + <property name="icon" > + <iconset resource="../muse.qrc" >:/xpm/filesave.png</iconset> + </property> + <property name="text" > + <string>&Save</string> + </property> + <property name="iconText" > + <string>Save</string> + </property> + <property name="shortcut" > + <string>Ctrl+S</string> + </property> + </action> + <action name="fileSaveAsAction" > + <property name="icon" > + <iconset resource="../muse.qrc" >:/xpm/fileopen.png</iconset> + </property> + <property name="text" > + <string>Save &As...</string> + </property> + <property name="iconText" > + <string>Save As</string> + </property> + <property name="shortcut" > + <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> + <property name="iconText" > + <string>Exit</string> + </property> + <property name="shortcut" > + <string/> + </property> + </action> + </widget> + <layoutdefault spacing="6" margin="11" /> + <resources> + <include location="../muse.qrc" /> + </resources> + <connections/> +</ui> diff --git a/attic/muse_qt4_evolution/muse/instruments/midictrledit.cpp b/attic/muse_qt4_evolution/muse/instruments/midictrledit.cpp new file mode 100644 index 00000000..b2f33e30 --- /dev/null +++ b/attic/muse_qt4_evolution/muse/instruments/midictrledit.cpp @@ -0,0 +1,418 @@ +//============================================================================= +// MusE +// Linux Music Editor +// $Id:$ +// +// Copyright (C) 2002-2006 by Werner Schweer and others +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +//============================================================================= + +#include "app.h" +#include "driver/mididev.h" +#include "midictrl.h" +#include "midictrledit.h" +#include "xml.h" +#include "filedialog.h" +#include "globals.h" + +MidiControllerEditDialog* midiControllerEditDialog; + +static MidiController predefinedMidiController[] = { + MidiController("Pitch", 0x40000, -10000, +10000), + MidiController("Program", 0x40001, 0, 127), + MidiController("BankSel", 0x10000, 0, 16383) + }; + +enum { + COL_NAME = 0, COL_TYPE, + COL_HNUM, COL_LNUM, COL_MIN, COL_MAX + }; + +//--------------------------------------------------------- +// addControllerToView +//--------------------------------------------------------- + +void MidiControllerEditDialog::addControllerToView(MidiController* mctrl) + { + QString hnum; + hnum.setNum(mctrl->num()); + QString lnum("---"); + QString min; + min.setNum(mctrl->minVal()); + QString max; + max.setNum(mctrl->maxVal()); + new Q3ListViewItem(viewController, + mctrl->name(), + int2ctrlType(mctrl->type()), + hnum, lnum, min, max + ); + } + +//--------------------------------------------------------- +// MidiControllerEditDialog +//--------------------------------------------------------- + +MidiControllerEditDialog::MidiControllerEditDialog(QWidget* parent, const char* name, bool modal, Qt::WFlags fl) + : MidiControllerEditDialogBase(parent, name, modal, fl) + { + viewController->setColumnAlignment(COL_HNUM, AlignCenter); + viewController->setColumnAlignment(COL_LNUM, AlignCenter); + viewController->setColumnAlignment(COL_MIN, AlignCenter); + viewController->setColumnAlignment(COL_MAX, AlignCenter); + viewController->setColumnWidthMode(COL_NAME, Q3ListView::Maximum); + + // populate list of predefined controller + int size = sizeof(predefinedMidiController) / sizeof(*predefinedMidiController); + for (int i = 0; i < size; ++i) + listController->insertItem(predefinedMidiController[i].name()); + listController->setSelected(0, true); + + // populate ports pulldown + for (int i = 0; i < MIDI_PORTS; ++i) { + MidiPort* port = &midiPorts[i]; + MidiDevice* dev = port->device(); + QString name; + name.sprintf("%d(%s)", port->portno()+1, + dev ? dev->name().latin1() : "none"); + midiPortsList->insertItem(name, i); + } + + reject(); // populate list + viewController->setCurrentItem(viewController->firstChild()); + + connect(buttonNew, SIGNAL(clicked()), SLOT(ctrlAdd())); + connect(buttonDelete, SIGNAL(clicked()), SLOT(ctrlDelete())); + connect(entryName, SIGNAL(textChanged(const QString&)), SLOT(nameChanged(const QString&))); + connect(comboType, SIGNAL(activated(const QString&)), SLOT(typeChanged(const QString&))); + connect(spinboxHCtrlNo, SIGNAL(valueChanged(int)), SLOT(valueHChanged(int))); + connect(spinboxLCtrlNo, SIGNAL(valueChanged(int)), SLOT(valueLChanged(int))); + connect(spinboxMin, SIGNAL(valueChanged(int)), SLOT(minChanged(int))); + connect(spinboxMax, SIGNAL(valueChanged(int)), SLOT(maxChanged(int))); + connect(viewController, SIGNAL(selectionChanged()), SLOT(controllerChanged())); + + controllerChanged(viewController->currentItem()); + } + +//--------------------------------------------------------- +// reject +//--------------------------------------------------------- + +void MidiControllerEditDialog::reject() + { + viewController->clear(); + for (iMidiController i = midiControllerList.begin(); + i != midiControllerList.end(); ++i) { + addControllerToView(&*i); + } + MidiControllerEditDialogBase::reject(); + } + +//--------------------------------------------------------- +// ctrlAdd +//--------------------------------------------------------- + +void MidiControllerEditDialog::ctrlAdd() + { + Q3ListBoxItem* item = listController->selectedItem(); + if (item == 0) + return; + QString name = item->text(); + int size = sizeof(predefinedMidiController) / sizeof(*predefinedMidiController); + for (int i = 0; i < size; ++i) { + MidiController* c = &predefinedMidiController[i]; + if (c->name() != name) + continue; + MidiController::ControllerType t = c->type(); + QString type = int2ctrlType(t); + QString min, max; + min.setNum(c->minVal()); + max.setNum(c->maxVal()); + + QString hno, lno; + int h = (c->num() >> 14) & 0x7f; + int l = c->num() & 0x7f; + + switch(t) { + case MidiController::Controller7: + hno = "---"; + lno.setNum(l); + break; + case MidiController::RPN: + case MidiController::NRPN: + case MidiController::Controller14: + hno.setNum(h); + lno.setNum(l); + break; + case MidiController::Pitch: + case MidiController::Program: + hno = "---"; + lno = "---"; + default: + break; + } + + Q3ListViewItem* item = new Q3ListViewItem(viewController, + name, type, hno, lno, min, max); + + viewController->setCurrentItem(item); + controllerChanged(item); + break; + } + } + +//--------------------------------------------------------- +// ctrlDelete +//--------------------------------------------------------- + +void MidiControllerEditDialog::ctrlDelete() + { + Q3ListViewItem* item = viewController->currentItem(); + if (item == 0) + return; + delete item; + } + +//--------------------------------------------------------- +// accept +//--------------------------------------------------------- + +void MidiControllerEditDialog::accept() + { + midiControllerList.clear(); + + Q3ListViewItem* item = viewController->firstChild(); + int hval = item->text(COL_HNUM).toInt(); + int lval = item->text(COL_LNUM).toInt(); + + while (item) { + MidiController c; + c.setName(item->text(COL_NAME)); + MidiController::ControllerType type = ctrlType2Int(item->text(COL_TYPE)); + + switch(type) { + case MidiController::Controller7: + c.setNum(hval); + break; + case MidiController::Controller14: + c.setNum((hval << 8 | lval) | 0x10000); + break; + case MidiController::RPN: + c.setNum((hval << 8 | lval) | 0x20000); + break; + case MidiController::NRPN: + c.setNum((hval << 8 | lval) | 0x30000); + break; + case MidiController::Pitch: + c.setNum(CTRL_PITCH); + break; + default: + break; + } + c.setMinVal(item->text(COL_MIN).toInt()); + c.setMaxVal(item->text(COL_MAX).toInt()); + midiControllerList.push_back(c); + item = item->nextSibling(); + } + MidiControllerEditDialogBase::accept(); + } + +//--------------------------------------------------------- +// nameChanged +//--------------------------------------------------------- + +void MidiControllerEditDialog::nameChanged(const QString& s) + { + Q3ListViewItem* item = viewController->currentItem(); + if (item == 0) + return; + item->setText(COL_NAME, s); + } + +//--------------------------------------------------------- +// typeChanged +//--------------------------------------------------------- + +void MidiControllerEditDialog::typeChanged(const QString& s) + { + Q3ListViewItem* item = viewController->currentItem(); + if (item == 0) + return; + item->setText(COL_TYPE, s); + item->setText(COL_MIN, QString("0")); + switch(ctrlType2Int(s)) { + case 2: // RPN + case 3: // NRPN + case MidiController::Controller14: + item->setText(COL_MAX, QString("16383")); + break; + case MidiController::Controller7: + case MidiController::Program: + item->setText(COL_MAX, QString("127")); + break; + case MidiController::Pitch: + item->setText(COL_MIN, QString("-5000")); + item->setText(COL_MAX, QString("+5000")); + break; + default: + break; + } + controllerChanged(item); + } + +//--------------------------------------------------------- +// valueHChanged +//--------------------------------------------------------- + +void MidiControllerEditDialog::valueHChanged(int val) + { + Q3ListViewItem* item = viewController->currentItem(); + if (item == 0) + return; + QString s; + s.setNum(val); + item->setText(COL_HNUM, s); + } + +//--------------------------------------------------------- +// valueLChanged +//--------------------------------------------------------- + +void MidiControllerEditDialog::valueLChanged(int val) + { + Q3ListViewItem* item = viewController->currentItem(); + if (item == 0) + return; + QString s; + s.setNum(val); + item->setText(COL_LNUM, s); + } + +//--------------------------------------------------------- +// controllerChanged +//--------------------------------------------------------- + +void MidiControllerEditDialog::controllerChanged() + { + Q3ListViewItem* item = viewController->selectedItem(); + controllerChanged(item); + } + +void MidiControllerEditDialog::controllerChanged(Q3ListViewItem* item) + { + if (item == 0) { + entryName->setEnabled(false); + comboType->setEnabled(false); + spinboxHCtrlNo->setEnabled(false); + spinboxLCtrlNo->setEnabled(false); + spinboxMin->setEnabled(false); + spinboxMax->setEnabled(false); + return; + } + + entryName->blockSignals(true); + comboType->blockSignals(true); + spinboxHCtrlNo->blockSignals(true); + spinboxLCtrlNo->blockSignals(true); + spinboxMin->blockSignals(true); + spinboxMax->blockSignals(true); + + entryName->setEnabled(true); + entryName->setText(item->text(COL_NAME)); + comboType->setCurrentItem(int(ctrlType2Int(item->text(COL_TYPE)))); + switch (ctrlType2Int(item->text(COL_TYPE))) { + case MidiController::Controller7: + comboType->setEnabled(true); + spinboxHCtrlNo->setEnabled(false); + spinboxLCtrlNo->setEnabled(true); + spinboxMin->setEnabled(true); + spinboxMax->setEnabled(true); + + spinboxHCtrlNo->setValue(item->text(COL_HNUM).toInt()); + spinboxMin->setValue(item->text(COL_MIN).toInt()); + spinboxMax->setValue(item->text(COL_MAX).toInt()); + item->setText(COL_LNUM, QString("---")); + break; + + case MidiController::Controller14: + case MidiController::RPN: + case MidiController::NRPN: + comboType->setEnabled(true); + spinboxHCtrlNo->setEnabled(true); + spinboxLCtrlNo->setEnabled(true); + spinboxMin->setEnabled(true); + spinboxMax->setEnabled(true); + + spinboxHCtrlNo->setValue(item->text(COL_HNUM).toInt()); + spinboxLCtrlNo->setValue(item->text(COL_LNUM).toInt()); + spinboxMin->setValue(item->text(COL_MIN).toInt()); + spinboxMax->setValue(item->text(COL_MAX).toInt()); + break; + + case MidiController::Pitch: + case MidiController::Program: + comboType->setEnabled(true); + spinboxHCtrlNo->setEnabled(false); + spinboxLCtrlNo->setEnabled(false); + spinboxMin->setEnabled(true); + spinboxMax->setEnabled(true); + break; + default: + break; + } + entryName->blockSignals(false); + comboType->blockSignals(false); + spinboxHCtrlNo->blockSignals(false); + spinboxLCtrlNo->blockSignals(false); + spinboxMin->blockSignals(false); + spinboxMax->blockSignals(false); + } + +//--------------------------------------------------------- +// minChanged +//--------------------------------------------------------- + +void MidiControllerEditDialog::minChanged(int val) + { + Q3ListViewItem* item = viewController->currentItem(); + if (item == 0) + return; + QString s; + s.setNum(val); + item->setText(COL_MIN, s); + } + +//--------------------------------------------------------- +// maxChanged +//--------------------------------------------------------- + +void MidiControllerEditDialog::maxChanged(int val) + { + Q3ListViewItem* item = viewController->currentItem(); + if (item == 0) + return; + QString s; + s.setNum(val); + item->setText(COL_MAX, s); + } + +//--------------------------------------------------------- +// configMidiController +//--------------------------------------------------------- + +void configMidiController() + { + if (midiControllerEditDialog == 0) + midiControllerEditDialog = new MidiControllerEditDialog(); + midiControllerEditDialog->show(); + } diff --git a/attic/muse_qt4_evolution/muse/instruments/midictrledit.h b/attic/muse_qt4_evolution/muse/instruments/midictrledit.h new file mode 100644 index 00000000..321f14b7 --- /dev/null +++ b/attic/muse_qt4_evolution/muse/instruments/midictrledit.h @@ -0,0 +1,58 @@ +//============================================================================= +// MusE +// Linux Music Editor +// $Id:$ +// +// Copyright (C) 2002-2006 by Werner Schweer and others +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +//============================================================================= + +#ifndef __MIDICTRLEDIT_H__ +#define __MIDICTRLEDIT_H__ + +#include "ccontrolbase.h" +#include "midictrl.h" + +//--------------------------------------------------------- +// MidiControllerEditDialog +//--------------------------------------------------------- + +class MidiControllerEditDialog : public MidiControllerEditDialogBase { + Q_OBJECT + + void addControllerToView(MidiController* mctrl); + void mergeReplace(bool replace); + + private slots: + void ctrlAdd(); + void ctrlDelete(); + virtual void accept(); + virtual void reject(); + void nameChanged(const QString&); + void typeChanged(const QString&); + void valueHChanged(int); + void valueLChanged(int); + void controllerChanged(Q3ListViewItem*); + void controllerChanged(); + void minChanged(int); + void maxChanged(int); + + public: + MidiControllerEditDialog(QWidget* parent = 0, const char* name = 0, bool modal = false, Qt::WFlags fl = 0); + }; + +extern MidiControllerEditDialog* midiControllerEditDialog; +extern void configMidiController(); +#endif + diff --git a/attic/muse_qt4_evolution/muse/instruments/minstrument.cpp b/attic/muse_qt4_evolution/muse/instruments/minstrument.cpp new file mode 100644 index 00000000..a189c63d --- /dev/null +++ b/attic/muse_qt4_evolution/muse/instruments/minstrument.cpp @@ -0,0 +1,631 @@ +//============================================================================= +// MusE +// Linux Music Editor +// $Id:$ +// +// Copyright (C) 2002-2006 by Werner Schweer and others +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +//============================================================================= + +#include "minstrument.h" +#include "midioutport.h" +#include "globals.h" +#include "event.h" +#include "midievent.h" +#include "midictrl.h" +#include "gconfig.h" +#include "midiedit/drummap.h" + +MidiInstrumentList midiInstruments; +MidiInstrument* genericMidiInstrument; + +//--------------------------------------------------------- +// string2sysex +//--------------------------------------------------------- + +int string2sysex(const QString& s, unsigned char** data) + { + const char* src = s.toLatin1().data(); + char buffer[2048]; + char* dst = buffer; + + if(src) { + while (*src) { + while (*src == ' ' || *src == '\n') { + ++src; + } + char* ep; + long val = strtol(src, &ep, 16); + if (ep == src) { + QMessageBox::information(0, + QString("MusE"), + QWidget::tr("Cannot convert sysex string")); + return 0; + } + src = ep; + *dst++ = val; + if (dst - buffer >= 2048) { + QMessageBox::information(0, + QString("MusE"), + QWidget::tr("Hex String too long (2048 bytes limit)")); + return 0; + } + } + } + int len = dst - buffer; + unsigned char* b = new unsigned char[len+1]; + memcpy(b, buffer, len); + b[len] = 0; + *data = b; + return len; + } + +//--------------------------------------------------------- +// sysex2string +//--------------------------------------------------------- + +QString sysex2string(int len, unsigned char* data) + { + QString d; + QString s; + for (int i = 0; i < len; ++i) { + if ((i > 0) && ((i % 8)==0)) { + d += "\n"; + } + else if (i) + d += " "; + d += s.sprintf("%02x", data[i]); + } + return d; + } + +//--------------------------------------------------------- +// Patch +//--------------------------------------------------------- + +Patch::Patch() + { + drumMap = 0; + categorie = -1; + } + +Patch::~Patch() + { + if (drumMap) + delete drumMap; + } + +//--------------------------------------------------------- +// loadIDF +//--------------------------------------------------------- + +static void loadIDF(QFileInfo* fi) + { + QFile qf(fi->filePath()); + if (!qf.open(QIODevice::ReadOnly)) { + 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; + if (!doc.setContent(&qf, false, &err, &line, &column)) { + QString col, ln, error; + col.setNum(column); + ln.setNum(line); + error = err + " at line: " + ln + " col: " + col; + printf("error reading file <%s>:\n %s\n", + fi->filePath().toLatin1().data(), error.toLatin1().data()); + return; + } + QDomNode node = doc.documentElement(); + while (!node.isNull()) { + QDomElement e = node.toElement(); + if (e.isNull()) + continue; + if (e.tagName() == "muse") { + QString version = e.attribute(QString("version")); + for (QDomNode n = node.firstChild(); !n.isNull(); n = n.nextSibling()) { + QDomElement e = n.toElement(); + if (e.tagName() == "MidiInstrument") { + MidiInstrument* i = new MidiInstrument(); + i->read(n); + i->setFilePath(fi->filePath()); + bool replaced = false; + for (int idx = 0; idx < midiInstruments.size(); ++idx) { + if (midiInstruments[idx]->iname() == i->iname()) { + midiInstruments.replace(idx, i); + replaced = true; + if (debugMsg) + printf("Midi Instrument Definition <%s> overwritten\n", + i->iname().toLocal8Bit().data()); + break; + } + } + if (!replaced) + midiInstruments += i; + } + } + } + else + printf("MusE:laodIDF: %s not supported\n", e.tagName().toLatin1().data()); + node = node.nextSibling(); + } + qf.close(); + } + +//--------------------------------------------------------- +// initMidiInstruments +//--------------------------------------------------------- + +void initMidiInstruments() + { + genericMidiInstrument = new MidiInstrument(QWidget::tr("generic midi")); + + midiInstruments.push_back(genericMidiInstrument); + QString museGlobalInstruments(museGlobalShare + + QString("/instruments")); + if (debugMsg) + printf("load instrument definitions from <%s>\n", museGlobalInstruments.toLatin1().data()); + QDir instrumentsDir(museGlobalInstruments, QString("*.idf"), + QDir::SortFlags(QDir::Name | QDir::IgnoreCase), QDir::Files); + if (instrumentsDir.exists()) { + QFileInfoList list = instrumentsDir.entryInfoList(); + int n = list.size(); + for (int i = 0; i < n; ++i) { + QFileInfo fi = list.at(i); + 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); + } + } + } + +//--------------------------------------------------------- +// registerMidiInstrument +//--------------------------------------------------------- + +MidiInstrument* registerMidiInstrument(const QString& name) + { + for (iMidiInstrument i = midiInstruments.begin(); + i != midiInstruments.end(); ++i) { + if ((*i)->iname() == name) + return *i; + } + return genericMidiInstrument; + } + +//--------------------------------------------------------- +// removeMidiInstrument +//--------------------------------------------------------- + +void removeMidiInstrument(const QString& name) + { + for (iMidiInstrument i = midiInstruments.begin(); + i != midiInstruments.end(); ++i) { + if ((*i)->iname() == name) { + midiInstruments.erase(i); + return; + } + } + } + +void removeMidiInstrument(const MidiInstrument* instr) + { + for (iMidiInstrument i = midiInstruments.begin(); + i != midiInstruments.end(); ++i) { + if (*i == instr) { + midiInstruments.erase(i); + return; + } + } + } + +//--------------------------------------------------------- +// MidiInstrument +//--------------------------------------------------------- + +void MidiInstrument::init() + { + _initScript = 0; + _midiInit = new EventList(); + _midiReset = new EventList(); + _midiState = new EventList(); + _controller = new MidiControllerList; + + // add some default controller to controller list + // this controllers are always available for all instruments + // + MidiController* prog = new MidiController("Program", CTRL_PROGRAM, 0, 0x7fffff, 0); + _controller->push_back(prog); + _dirty = false; + _readonly = false; + } + +MidiInstrument::MidiInstrument() + { + init(); + } + +//--------------------------------------------------------- +// MidiInstrument +//--------------------------------------------------------- + +MidiInstrument::MidiInstrument(const QString& txt) + { + _name = txt; + init(); + } + +//--------------------------------------------------------- +// MidiInstrument +//--------------------------------------------------------- + +MidiInstrument::~MidiInstrument() + { + delete _midiInit; + delete _midiReset; + delete _midiState; + delete _controller; + if (_initScript) + delete _initScript; + } + +//--------------------------------------------------------- +// readPatchGroup +//--------------------------------------------------------- + +void PatchGroup::read(QDomNode node, MidiInstrument* instrument) + { + for (; !node.isNull(); node = node.nextSibling()) { + QDomElement e = node.toElement(); + QString tag(e.tagName()); + + if (tag == "Patch") { + Patch* patch = new Patch; + patch->read(node, false, instrument); + patches.push_back(patch); + } + else if (tag == "drummap") { + Patch* patch = new Patch; + patch->read(node, true, instrument); + patches.push_back(patch); + } + else if (!tag.isEmpty()) + printf("MusE:PatchGroup(): unknown tag %s in group %s\n", + e.tagName().toLatin1().data(), name.toLatin1().data()); + } + } + +//--------------------------------------------------------- +// read +//--------------------------------------------------------- + +void Patch::read(QDomNode node, bool dr, MidiInstrument* instrument) + { + QDomElement e = node.toElement(); + name = e.attribute("name"); + typ = e.attribute("mode", "-1").toInt(); + hbank = e.attribute("hbank", "-1").toInt(); + lbank = e.attribute("lbank", "-1").toInt(); + prog = e.attribute("prog", "0").toInt(); + QString cat = e.attribute("cat"); + categorie = instrument->categories().indexOf(cat); + drumMap = 0; + if (!dr) + return; + drumMap = new DrumMap(name); + int idx = 0; + for (node = node.firstChild(); !node.isNull(); node = node.nextSibling()) { + e = node.toElement(); + QString tag(e.tagName()); + if (tag == "entry") { + DrumMapEntry* de = drumMap->entry(idx); + de->read(node); + ++idx; + } + else if (!tag.isEmpty()) { + printf("Patch: read drummap: unknown tag %s\n", tag.toLatin1().data()); + } + } + drumMap->init(); + } + +//--------------------------------------------------------- +// write +//--------------------------------------------------------- + +void Patch::write(Xml& xml) + { + if (drumMap == 0) { + QString s = QString("Patch name=\"%1\"").arg(Xml::xmlString(name)); + if (typ != -1) + s += QString(" mode=\"%d\"").arg(typ); + s += QString(" hbank=\"%1\" lbank=\"%2\" prog=\"%3\"").arg(hbank).arg(lbank).arg(prog); + xml.tagE(s); + return; + } + QString s = QString("drummap name=\"%1\"").arg(Xml::xmlString(name)); + s += QString(" hbank=\"%1\" lbank=\"%2\" prog=\"%3\"").arg(hbank).arg(lbank).arg(prog); + xml.stag(s); + for (int i = 0; i < DRUM_MAPSIZE; ++i) { + DrumMapEntry* dm = drumMap->entry(i); + dm->write(xml); + } + xml.etag("drummap"); + } + +//--------------------------------------------------------- +// readMidiState +//--------------------------------------------------------- + +void MidiInstrument::readMidiState(QDomNode node) + { + _midiState->read(node, true); + } + +//--------------------------------------------------------- +// read +//--------------------------------------------------------- + +void MidiInstrument::read(QDomNode node) + { + QDomElement e = node.toElement(); + _name = e.attribute("name"); + + for (node = node.firstChild(); !node.isNull(); node = node.nextSibling()) { + e = node.toElement(); + QString tag(e.tagName()); + if (tag == "Patch") { + Patch* patch = new Patch; + patch->read(node, false, this); + if (pg.empty()) { + PatchGroup p; + p.patches.push_back(patch); + pg.push_back(p); + } + else + pg[0].patches.push_back(patch); + } + else if (tag == "Category") { + QString name = e.attribute(QString("name")); + _categories.append(name); + } + else if (tag == "drummap") { + Patch* patch = new Patch; + patch->read(node, true, this); + if (pg.empty()) { + PatchGroup p; + p.patches.push_back(patch); + pg.push_back(p); + } + else + pg[0].patches.push_back(patch); + } + else if (tag == "PatchGroup") { + PatchGroup p; + p.name = e.attribute("name"); + p.read(node.firstChild(), this); + pg.push_back(p); + } + else if (tag == "Controller") { + MidiController* mc = new MidiController(); + mc->read(node); + // + // HACK: make predefined "Program" controller overloadable + // + if (mc->name() == "Program") { + for (iMidiController i = _controller->begin(); i != _controller->end(); ++i) { + if ((*i)->name() == mc->name()) { + _controller->erase(i); + break; + } + } + } + _controller->push_back(mc); + } + else if (tag == "Init") + _midiInit->read(node.firstChild(), true); + else if (tag == "SysEx") { + 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->dataLen = string2sysex(e.text(), &(se->data)); + } + else + printf("MidiInstrument::read():SysEx: unknown tag %s\n", tag.toLatin1().data()); + } + _sysex.append(se); + } + else if (!tag.isEmpty()) { + printf("MidiInstrument::read(): unknown tag %s\n", tag.toLatin1().data()); + } + } + } + +//--------------------------------------------------------- +// getPatchName +//--------------------------------------------------------- + +QString MidiInstrument::getPatchName(int /*channel*/, int prog) + { + int hbank = (prog >> 16) & 0xff; + int lbank = (prog >> 8) & 0xff; + prog &= 0xff; + if (prog == 0xff) + return "---"; + + int tmask = 1; + bool hb = hbank == 0xff; + bool lb = lbank == 0xff; + + for (std::vector<PatchGroup>::iterator i = pg.begin(); i != pg.end(); ++i) { + PatchList& pl = i->patches; + for (PatchList::const_iterator ipl = pl.begin(); ipl != pl.end(); ++ipl) { + const Patch* mp = *ipl; + if ((mp->typ & tmask) + && (prog == mp->prog) + && (hbank == mp->hbank || hb || mp->hbank == -1) + && (lbank == mp->lbank || lb || mp->lbank == -1)) + return mp->name; + } + } + return QString("---"); + } + +//--------------------------------------------------------- +// getDrumMap +//--------------------------------------------------------- + +DrumMap* MidiInstrument::getDrumMap(int prog) + { + int hbank = (prog >> 16) & 0xff; + int lbank = (prog >> 8) & 0xff; + prog &= 0xff; + if (prog == 0xff) + return 0; + + int tmask = 1; + bool hb = hbank == 0xff; + bool lb = lbank == 0xff; + + for (std::vector<PatchGroup>::iterator i = pg.begin(); i != pg.end(); ++i) { + PatchList& pl = i->patches; + for (PatchList::const_iterator ipl = pl.begin(); ipl != pl.end(); ++ipl) { + const Patch* mp = *ipl; + if ((mp->typ & tmask) + && (prog == mp->prog) + && (hbank == mp->hbank || hb || mp->hbank == -1) + && (lbank == mp->lbank || lb || mp->lbank == -1)) { + return mp->drumMap; + } + } + } + return 0; + } + +//--------------------------------------------------------- +// populatePatchPopup +//--------------------------------------------------------- + +void MidiInstrument::populatePatchPopup(QMenu* menu, int) + { + menu->clear(); + int mask = 7; + + if (pg.size() > 1) { + for (std::vector<PatchGroup>::iterator i = pg.begin(); i != pg.end(); ++i) { + QMenu* pm = menu->addMenu(i->name); +// pm->setFont(config.fonts[0]); + PatchList& pl = i->patches; + for (PatchList::const_iterator ipl = pl.begin(); ipl != pl.end(); ++ipl) { + const Patch* mp = *ipl; + if (mp->typ & mask) { + int id = ((mp->hbank & 0xff) << 16) + + ((mp->lbank & 0xff) << 8) + (mp->prog & 0xff); + QAction* a = pm->addAction(mp->name); + a->setData(id); + } + } + } + } + else if (pg.size() == 1 ){ + // no groups + PatchList& pl = pg.front().patches; + for (PatchList::const_iterator ipl = pl.begin(); ipl != pl.end(); ++ipl) { + const Patch* mp = *ipl; + if (mp->typ & mask) { + int id = ((mp->hbank & 0xff) << 16) + + ((mp->lbank & 0xff) << 8) + (mp->prog & 0xff); + QAction* a = menu->addAction(mp->name); + a->setData(id); + } + } + } + } + +//--------------------------------------------------------- +// getMidiController +//--------------------------------------------------------- + +MidiController* MidiInstrument::midiController(int num) const + { + for (iMidiController i = _controller->begin(); i != _controller->end(); ++i) { + int cn = (*i)->num(); + if (cn == num) + return *i; + // wildcard? + if (((cn & 0xff) == 0xff) && ((cn & ~0xff) == (num & ~0xff))) + return *i; + } + for (iMidiController i = defaultMidiController.begin(); i != defaultMidiController.end(); ++i) { + int cn = (*i)->num(); + if (cn == num) + return *i; + // wildcard? + if (((cn & 0xff) == 0xff) && ((cn & ~0xff) == (num & ~0xff))) + return *i; + } + QString name = midiCtrlName(num); + int min = 0; + int max = 127; + MidiController* c = new MidiController(name, num, min, max, 0); + defaultMidiController.push_back(c); + return c; + } + +//--------------------------------------------------------- +// write +//--------------------------------------------------------- + +void MidiInstrument::write(Xml& xml) + { + xml.header(); + xml.stag("muse version=\"2.1\""); + xml.stag(QString("MidiInstrument name=\"%1\"").arg(Xml::xmlString(iname()))); + + foreach(const QString& s, _categories) + xml.tagE(QString("Category name=\"%1\"").arg(Xml::xmlString(s))); + + std::vector<PatchGroup>* pg = groups(); + for (std::vector<PatchGroup>::iterator g = pg->begin(); g != pg->end(); ++g) { + xml.stag(QString("PatchGroup name=\"%1\"").arg(Xml::xmlString(g->name))); + for (iPatch p = g->patches.begin(); p != g->patches.end(); ++p) + (*p)->write(xml); + xml.etag("PatchGroup"); + } + for (iMidiController ic = _controller->begin(); ic != _controller->end(); ++ic) + (*ic)->write(xml); + xml.etag("MidiInstrument"); + xml.etag("muse"); + } + diff --git a/attic/muse_qt4_evolution/muse/instruments/minstrument.h b/attic/muse_qt4_evolution/muse/instruments/minstrument.h new file mode 100644 index 00000000..5bcf2616 --- /dev/null +++ b/attic/muse_qt4_evolution/muse/instruments/minstrument.h @@ -0,0 +1,160 @@ +//============================================================================= +// MusE +// Linux Music Editor +// $Id:$ +// +// Copyright (C) 2002-2006 by Werner Schweer and others +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +//============================================================================= + +#ifndef __MINSTRUMENT_H__ +#define __MINSTRUMENT_H__ + +#include "globaldefs.h" + +namespace AL { + class Xml; + }; +using AL::Xml; + +class MidiOutPort; +class EventList; +class MidiControllerList; +class MidiController; +class MidiEvent; +class DrumMap; +class MidiInstrument; + +//--------------------------------------------------------- +// Patch +//--------------------------------------------------------- + +struct Patch { + signed char typ; // 1 - GM 2 - GS 4 - XG + signed char hbank, lbank, prog; + QString name; + int categorie; + DrumMap* drumMap; + + void read(QDomNode, bool, MidiInstrument*); + void write(Xml& xml); + + Patch(); + ~Patch(); + }; + +typedef std::list<Patch*> PatchList; +typedef PatchList::iterator iPatch; +typedef PatchList::const_iterator ciPatch; + +//--------------------------------------------------------- +// PatchGroup +//--------------------------------------------------------- + +struct PatchGroup { + QString name; + PatchList patches; + void read(QDomNode, MidiInstrument*); + }; + +struct SysEx { + QString name; + QString comment; + int dataLen; + unsigned char* data; + }; + +//--------------------------------------------------------- +// MidiInstrument +//--------------------------------------------------------- + +class MidiInstrument { + std::vector<PatchGroup> pg; + MidiControllerList* _controller; + QList<SysEx*> _sysex; + bool _dirty; + bool _readonly; + + void init(); + + protected: + QList<QString> _categories; + EventList* _midiInit; + EventList* _midiReset; + EventList* _midiState; + char* _initScript; + QString _name; + QString _filePath; + + public: + MidiInstrument(); + virtual ~MidiInstrument(); + MidiInstrument(const QString& txt); + const QString& iname() const { return _name; } + void setIName(const QString& txt) { _name = txt; } + QString filePath() const { return _filePath; } + void setFilePath(const QString& s) { _filePath = s; } + bool dirty() const { return _dirty; } + void setDirty(bool v) { _dirty = v; } + bool readonly() const { return _readonly; } + void setReadonly(bool v) { _readonly = v; } + + EventList* midiInit() const { return _midiInit; } + EventList* midiReset() const { return _midiReset; } + EventList* midiState() const { return _midiState; } + const char* initScript() const { return _initScript; } + MidiControllerList* controller() const { return _controller; } + + void readMidiState(QDomNode); + virtual bool guiVisible() const { return false; } + virtual void showGui(bool) {} + virtual bool hasGui() const { return false; } + virtual void writeToGui(const MidiEvent&) {} + + virtual QString getPatchName(int,int); + virtual DrumMap* getDrumMap(int); + + virtual void populatePatchPopup(QMenu*, int); + void read(QDomNode); + void write(Xml& xml); + 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; } + const QList<QString>& categories() const { return _categories; } + void addCategory(const QString& s) { _categories.append(s); } + }; + +//--------------------------------------------------------- +// MidiInstrumentList +//--------------------------------------------------------- + +class MidiInstrumentList : public QList<MidiInstrument*> { + }; + +typedef MidiInstrumentList::iterator iMidiInstrument; + +extern MidiInstrumentList midiInstruments; + +extern MidiInstrument* genericMidiInstrument; +extern void initMidiInstruments(); +extern MidiInstrument* registerMidiInstrument(const QString&); +extern void removeMidiInstrument(const QString& name); +extern void removeMidiInstrument(const MidiInstrument* instr); + +#endif + |