MuseScore/mscore/instrdialog.cpp
2013-02-07 13:10:46 +01:00

929 lines
32 KiB
C++

//=============================================================================
// MuseScore
// Linux Music Score Editor
// $Id: instrdialog.cpp 5580 2012-04-27 15:36:57Z wschweer $
//
// Copyright (C) 2002-2009 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 "config.h"
#include "musescore.h"
#include "instrdialog.h"
#include "libmscore/instrtemplate.h"
#include "scoreview.h"
#include "libmscore/score.h"
#include "libmscore/system.h"
#include "libmscore/clef.h"
#include "libmscore/undo.h"
#include "libmscore/staff.h"
#include "libmscore/part.h"
#include "libmscore/segment.h"
#include "libmscore/style.h"
#include "editinstrument.h"
#include "libmscore/drumset.h"
#include "libmscore/slur.h"
#include "seq.h"
#include "libmscore/measure.h"
#include "libmscore/line.h"
#include "libmscore/beam.h"
#include "libmscore/excerpt.h"
#include "libmscore/stafftype.h"
void filterInstruments(QTreeWidget *instrumentList, const QString &searchPhrase = QString(""));
//---------------------------------------------------------
// StaffListItem
//---------------------------------------------------------
StaffListItem::StaffListItem(PartListItem* li)
: QTreeWidgetItem(li, STAFF_LIST_ITEM)
{
op = ITEM_KEEP;
staff = 0;
setPartIdx(0);
staffIdx = 0;
setLinked(false);
setClef(CLEF_G);
// setFlags(flags() | Qt::ItemIsUserCheckable);
}
StaffListItem::StaffListItem()
: QTreeWidgetItem(STAFF_LIST_ITEM)
{
op = ITEM_KEEP;
staff = 0;
setPartIdx(0);
staffIdx = 0;
setClef(CLEF_G);
setLinked(false);
}
//---------------------------------------------------------
// setPartIdx
//---------------------------------------------------------
void StaffListItem::setPartIdx(int val)
{
_partIdx = val;
setText(0, InstrumentsDialog::tr("Staff %1").arg(_partIdx + 1));
}
//---------------------------------------------------------
// setClef
//---------------------------------------------------------
void StaffListItem::setClef(ClefType val)
{
_clef = val;
setText(2, qApp->translate("clefTable", clefTable[_clef].name));
}
//---------------------------------------------------------
// setLinked
//---------------------------------------------------------
void StaffListItem::setLinked(bool val)
{
_linked = val;
setText(3, _linked ? InstrumentsDialog::tr("linked") : "");
}
//---------------------------------------------------------
// setVisible
//---------------------------------------------------------
void PartListItem::setVisible(bool val)
{
setCheckState(1, val ? Qt::Checked : Qt::Unchecked);
}
//---------------------------------------------------------
// visible
//---------------------------------------------------------
bool PartListItem::visible() const
{
return checkState(1) == Qt::Checked;
}
//---------------------------------------------------------
// PartListItem
//---------------------------------------------------------
PartListItem::PartListItem(Part* p, QTreeWidget* lv)
: QTreeWidgetItem(lv, PART_LIST_ITEM)
{
part = p;
it = 0;
op = ITEM_KEEP;
setText(0, p->partName());
setFlags(flags() | Qt::ItemIsUserCheckable);
}
PartListItem::PartListItem(const InstrumentTemplate* i, QTreeWidget* lv)
: QTreeWidgetItem(lv, PART_LIST_ITEM)
{
part = 0;
it = i;
op = ITEM_ADD;
setText(0, it->trackName);
}
//---------------------------------------------------------
// InstrumentTemplateListItem
//---------------------------------------------------------
InstrumentTemplateListItem::InstrumentTemplateListItem(QString group, QTreeWidget* parent)
: QTreeWidgetItem(parent) {
_instrumentTemplate = 0;
_group = group;
setText(0, group);
}
InstrumentTemplateListItem::InstrumentTemplateListItem(InstrumentTemplate* i, InstrumentTemplateListItem* item)
: QTreeWidgetItem(item) {
_instrumentTemplate = i;
setText(0, i->trackName);
}
InstrumentTemplateListItem::InstrumentTemplateListItem(InstrumentTemplate* i, QTreeWidget* parent)
: QTreeWidgetItem(parent) {
_instrumentTemplate = i;
setText(0, i->trackName);
}
//---------------------------------------------------------
// text
//---------------------------------------------------------
QString InstrumentTemplateListItem::text(int col) const
{
switch (col) {
case 0:
return _instrumentTemplate ?
_instrumentTemplate->trackName : _group;
default:
return QString("");
}
}
//---------------------------------------------------------
// InstrumentsDialog
//---------------------------------------------------------
InstrumentsDialog::InstrumentsDialog(QWidget* parent)
: QDialog(parent)
{
editInstrument = 0;
setupUi(this);
setWindowFlags(this->windowFlags() & ~Qt::WindowContextHelpButtonHint);
cs = 0;
QAction* a = getAction("instruments");
connect(a, SIGNAL(triggered()), SLOT(reject()));
addAction(a);
instrumentList->setSelectionMode(QAbstractItemView::SingleSelection);
partiturList->setSelectionMode(QAbstractItemView::SingleSelection);
buildTemplateList();
addButton->setEnabled(false);
removeButton->setEnabled(false);
upButton->setEnabled(false);
downButton->setEnabled(false);
belowButton->setEnabled(false);
linkedButton->setEnabled(false);
connect(showMore, SIGNAL(clicked()), SLOT(buildTemplateList()));
}
//---------------------------------------------------------
// populateInstrumentList
//---------------------------------------------------------
void populateInstrumentList(QTreeWidget* instrumentList, bool extended)
{
instrumentList->clear();
// TODO: memory leak
foreach(InstrumentGroup* g, instrumentGroups) {
if (!extended && g->extended)
continue;
InstrumentTemplateListItem* group = new InstrumentTemplateListItem(g->name, instrumentList);
group->setFlags(Qt::ItemIsEnabled);
foreach(InstrumentTemplate* t, g->instrumentTemplates) {
if (!extended && t->extended)
continue;
new InstrumentTemplateListItem(t, group);
}
}
}
//---------------------------------------------------------
// buildTemplateList
//---------------------------------------------------------
void InstrumentsDialog::buildTemplateList()
{
// clear search if instrument list is updated
search->clear();
filterInstruments(instrumentList, search->text());
populateInstrumentList(instrumentList, showMore->isChecked());
}
//---------------------------------------------------------
// genPartList
//---------------------------------------------------------
void InstrumentsDialog::genPartList()
{
partiturList->clear();
foreach(Part* p, cs->parts()) {
PartListItem* pli = new PartListItem(p, partiturList);
pli->setVisible(p->show());
foreach(Staff* s, *p->staves()) {
StaffListItem* sli = new StaffListItem(pli);
sli->staff = s;
sli->setPartIdx(s->rstaff());
sli->staffIdx = s->idx();
if (s->isTabStaff())
sli->setClef(ClefType(cs->styleI(ST_tabClef)));
else
sli->setClef(s->clef(0));
const LinkedStaves* ls = s->linkedStaves();
sli->setLinked(ls && !ls->isEmpty());
}
partiturList->setItemExpanded(pli, true);
}
}
//---------------------------------------------------------
// on_instrumentList_itemSelectionChanged
//---------------------------------------------------------
void InstrumentsDialog::on_instrumentList_itemSelectionChanged()
{
QList<QTreeWidgetItem*> wi = instrumentList->selectedItems();
bool flag = !wi.isEmpty();
addButton->setEnabled(flag);
// editButton->setEnabled(flag);
}
//---------------------------------------------------------
// on_partiturList_itemSelectionChanged
//---------------------------------------------------------
void InstrumentsDialog::on_partiturList_itemSelectionChanged()
{
QList<QTreeWidgetItem*> wi = partiturList->selectedItems();
if (wi.isEmpty()) {
removeButton->setEnabled(false);
upButton->setEnabled(false);
downButton->setEnabled(false);
linkedButton->setEnabled(false);
belowButton->setEnabled(false);
return;
}
QTreeWidgetItem* item = wi.front();
bool flag = item != 0;
int count = 0; // item can be hidden
QTreeWidgetItem* it = 0;
QList<QTreeWidgetItem*> witems;
if(item->type() == PART_LIST_ITEM) {
for (int idx = 0; (it = partiturList->topLevelItem(idx)); ++idx) {
if (!it->isHidden()) {
count++;
witems.append(it);
}
}
}
else {
for (int idx = 0; (it = item->parent()->child(idx)); ++idx) {
if (!it->isHidden()){
count++;
witems.append(it);
}
}
}
bool onlyOne = (count == 1);
bool first = (witems.first() == item);
bool last = (witems.last() == item);
removeButton->setEnabled(flag && !onlyOne);
upButton->setEnabled(flag && !onlyOne && !first);
downButton->setEnabled(flag && !onlyOne && !last);
linkedButton->setEnabled(item && item->type() == STAFF_LIST_ITEM);
belowButton->setEnabled(item && item->type() == STAFF_LIST_ITEM);
}
//---------------------------------------------------------
// on_instrumentList
//---------------------------------------------------------
void InstrumentsDialog::on_instrumentList_itemDoubleClicked(QTreeWidgetItem*, int)
{
on_addButton_clicked();
}
//---------------------------------------------------------
// on_addButton_clicked
// add instrument to partitur
//---------------------------------------------------------
void InstrumentsDialog::on_addButton_clicked()
{
QList<QTreeWidgetItem*> wi = instrumentList->selectedItems();
if (wi.isEmpty())
return;
InstrumentTemplateListItem* item = (InstrumentTemplateListItem*)wi.front();
const InstrumentTemplate* it = item->instrumentTemplate();
if (it == 0)
return;
PartListItem* pli = new PartListItem(it, partiturList);
pli->op = ITEM_ADD;
int n = it->nstaves();
for (int i = 0; i < n; ++i) {
StaffListItem* sli = new StaffListItem(pli);
sli->op = ITEM_ADD;
sli->staff = 0;
sli->setPartIdx(i);
sli->staffIdx = -1;
sli->setClef(it->clefIdx[i]);
}
partiturList->setItemExpanded(pli, true);
partiturList->clearSelection(); // should not be necessary
partiturList->setItemSelected(pli, true);
}
//---------------------------------------------------------
// on_removeButton_clicked
// remove instrument from partitur
//---------------------------------------------------------
void InstrumentsDialog::on_removeButton_clicked()
{
QList<QTreeWidgetItem*> wi = partiturList->selectedItems();
if (wi.isEmpty())
return;
QTreeWidgetItem* item = wi.front();
QTreeWidgetItem* parent = item->parent();
if (parent) {
if (((StaffListItem*)item)->op == ITEM_ADD) {
if (parent->childCount() == 1) {
partiturList->takeTopLevelItem(partiturList->indexOfTopLevelItem(parent));
delete parent;
}
else {
parent->takeChild(parent->indexOfChild(item));
delete item;
}
}
else {
((StaffListItem*)item)->op = ITEM_DELETE;
item->setHidden(true);
}
}
else {
if (((PartListItem*)item)->op == ITEM_ADD)
delete item;
else {
((PartListItem*)item)->op = ITEM_DELETE;
item->setHidden(true);
}
}
partiturList->clearSelection();
}
//---------------------------------------------------------
// on_upButton_clicked
// move instrument up in partitur
//---------------------------------------------------------
void InstrumentsDialog::on_upButton_clicked()
{
QList<QTreeWidgetItem*> wi = partiturList->selectedItems();
if (wi.isEmpty())
return;
QTreeWidgetItem* item = wi.front();
if (item->type() == PART_LIST_ITEM) {
bool isExpanded = partiturList->isItemExpanded(item);
int idx = partiturList->indexOfTopLevelItem(item);
if (idx) {
partiturList->selectionModel()->clear();
QTreeWidgetItem* item = partiturList->takeTopLevelItem(idx);
partiturList->insertTopLevelItem(idx-1, item);
partiturList->setItemExpanded(item, isExpanded);
partiturList->setItemSelected(item, true);
}
}
else {
QTreeWidgetItem* parent = item->parent();
int idx = parent->indexOfChild(item);
if (idx) {
partiturList->selectionModel()->clear();
QTreeWidgetItem* item = parent->takeChild(idx);
parent->insertChild(idx-1, item);
partiturList->setItemSelected(item, true);
}
else {
int parentIdx = partiturList->indexOfTopLevelItem(parent);
if (parentIdx) {
partiturList->selectionModel()->clear();
QTreeWidgetItem* item = parent->takeChild(idx);
QTreeWidgetItem* prevParent = partiturList->topLevelItem(parentIdx - 1);
prevParent->addChild(item);
partiturList->setItemSelected(item, true);
PartListItem* pli = static_cast<PartListItem*>(prevParent);
StaffListItem* sli = static_cast<StaffListItem*>(item);
int idx = pli->part->nstaves();
cs->undo(new MoveStaff(sli->staff, pli->part, idx));
}
}
}
}
//---------------------------------------------------------
// on_downButton_clicked
// move instrument down in partitur
//---------------------------------------------------------
void InstrumentsDialog::on_downButton_clicked()
{
QList<QTreeWidgetItem*> wi = partiturList->selectedItems();
if (wi.isEmpty())
return;
QTreeWidgetItem* item = wi.front();
if (item->type() == PART_LIST_ITEM) {
bool isExpanded = partiturList->isItemExpanded(item);
int idx = partiturList->indexOfTopLevelItem(item);
int n = partiturList->topLevelItemCount();
if (idx < (n-1)) {
partiturList->selectionModel()->clear();
QTreeWidgetItem* item = partiturList->takeTopLevelItem(idx);
partiturList->insertTopLevelItem(idx+1, item);
partiturList->setItemExpanded(item, isExpanded);
partiturList->setItemSelected(item, true);
}
}
else {
QTreeWidgetItem* parent = item->parent();
int idx = parent->indexOfChild(item);
int n = parent->childCount();
if (idx < (n-1)) {
partiturList->selectionModel()->clear();
QTreeWidgetItem* item = parent->takeChild(idx);
parent->insertChild(idx+1, item);
partiturList->setItemSelected(item, true);
}
else {
int parentIdx = partiturList->indexOfTopLevelItem(parent);
int n = partiturList->topLevelItemCount();
if (parentIdx < (n-1)) {
partiturList->selectionModel()->clear();
QTreeWidgetItem* item = parent->takeChild(idx);
QTreeWidgetItem* nextParent = partiturList->topLevelItem(parentIdx - 1);
nextParent->addChild(item);
partiturList->setItemSelected(item, true);
PartListItem* pli = static_cast<PartListItem*>(nextParent);
StaffListItem* sli = static_cast<StaffListItem*>(item);
cs->undo(new MoveStaff(sli->staff, pli->part, 0));
}
}
}
}
//---------------------------------------------------------
// on_editButton_clicked
// start instrument editor for selected instrument
//---------------------------------------------------------
#if 0
void InstrumentsDialog::on_editButton_clicked()
{
QList<QTreeWidgetItem*> wi = instrumentList->selectedItems();
if (wi.isEmpty())
return;
QTreeWidgetItem* item = wi.front();
InstrumentTemplateListItem* ti = (InstrumentTemplateListItem*) item;
InstrumentTemplate* tp = ti->instrumentTemplate();
if (tp == 0)
return;
if (editInstrument == 0)
editInstrument = new EditInstrument(this);
editInstrument->setInstrument(tp);
editInstrument->show();
}
#endif
//---------------------------------------------------------
// on_belowButton_clicked
//---------------------------------------------------------
void InstrumentsDialog::on_belowButton_clicked()
{
QList<QTreeWidgetItem*> wi = partiturList->selectedItems();
if (wi.isEmpty())
return;
QTreeWidgetItem* item = wi.front();
if (item->type() != STAFF_LIST_ITEM)
return;
StaffListItem* sli = (StaffListItem*)item;
Staff* staff = sli->staff;
PartListItem* pli = (PartListItem*)sli->parent();
StaffListItem* nsli = new StaffListItem();
nsli->staff = staff;
nsli->setClef(sli->clef());
if (staff)
nsli->op = ITEM_ADD;
pli->insertChild(pli->indexOfChild(sli)+1, nsli);
partiturList->clearSelection(); // should not be necessary
partiturList->setItemSelected(nsli, true);
}
//---------------------------------------------------------
// on_linkedButton_clicked
//---------------------------------------------------------
void InstrumentsDialog::on_linkedButton_clicked()
{
QList<QTreeWidgetItem*> wi = partiturList->selectedItems();
if (wi.isEmpty())
return;
QTreeWidgetItem* item = wi.front();
if (item->type() != STAFF_LIST_ITEM)
return;
StaffListItem* sli = (StaffListItem*)item;
Staff* staff = sli->staff;
PartListItem* pli = (PartListItem*)sli->parent();
StaffListItem* nsli = new StaffListItem();
nsli->staff = staff;
nsli->setClef(sli->clef());
nsli->setLinked(true);
if (staff)
nsli->op = ITEM_ADD;
pli->insertChild(pli->indexOfChild(sli)+1, nsli);
partiturList->clearSelection(); // should not be necessary
partiturList->setItemSelected(nsli, true);
}
//---------------------------------------------------------
// accept
//---------------------------------------------------------
void InstrumentsDialog::accept()
{
done(1);
}
//---------------------------------------------------------
// editInstrList
//---------------------------------------------------------
void MuseScore::editInstrList()
{
if (cs == 0)
return;
if (!instrList)
instrList = new InstrumentsDialog(this);
else if (instrList->isVisible()) {
instrList->done(0);
return;
}
instrList->setScore(cs);
instrList->genPartList();
cs->startCmd();
cs->deselectAll();
int rv = instrList->exec();
if (rv == 0) {
cs->endCmd();
return;
}
cs->inputState().setTrack(-1);
//
// process modified partitur list
//
QTreeWidget* pl = instrList->partiturList;
Part* part = 0;
int staffIdx = 0;
int rstaff = 0;
QTreeWidgetItem* item = 0;
for (int idx = 0; (item = pl->topLevelItem(idx)); ++idx) {
PartListItem* pli = static_cast<PartListItem*>(item);
// check if the part contains any remaining staves
// mark to remove part if not
QTreeWidgetItem* ci = 0;
int staves = 0;
for (int cidx = 0; (ci = pli->child(cidx)); ++cidx) {
StaffListItem* sli = static_cast<StaffListItem*>(ci);
if (sli->op != ITEM_DELETE)
++staves;
}
if (staves == 0)
pli->op = ITEM_DELETE;
}
item = 0;
for (int idx = 0; (item = pl->topLevelItem(idx)); ++idx) {
rstaff = 0;
PartListItem* pli = static_cast<PartListItem*>(item);
if (pli->op == ITEM_DELETE)
cs->cmdRemovePart(pli->part);
else if (pli->op == ITEM_ADD) {
const InstrumentTemplate* t = ((PartListItem*)item)->it;
part = new Part(cs);
part->initFromInstrTemplate(t);
pli->part = part;
QTreeWidgetItem* ci = 0;
rstaff = 0;
for (int cidx = 0; (ci = pli->child(cidx)); ++cidx) {
StaffListItem* sli = static_cast<StaffListItem*>(ci);
Staff* staff = new Staff(cs, part, rstaff);
sli->staff = staff;
staff->setRstaff(rstaff);
staff->init(t, cidx);
staff->setInitialClef(sli->clef());
cs->undoInsertStaff(staff, staffIdx + rstaff);
if (sli->linked()) {
// TODO: link staff
qDebug("TODO: link staff\n");
}
++rstaff;
}
part->staves()->front()->setBarLineSpan(part->nstaves());
cs->cmdInsertPart(part, staffIdx);
staffIdx += rstaff;
}
else {
part = pli->part;
if (part->show() != pli->visible()) {
part->score()->undo()->push(new ChangePartProperty(part, Part::SHOW, pli->visible()));
}
QTreeWidgetItem* ci = 0;
for (int cidx = 0; (ci = pli->child(cidx)); ++cidx) {
StaffListItem* sli = (StaffListItem*)ci;
if (sli->op == ITEM_DELETE) {
cs->systems()->clear();
Staff* staff = sli->staff;
int sidx = staff->idx();
int eidx = sidx + 1;
for (MeasureBase* mb = cs->measures()->first(); mb; mb = mb->next()) {
if (mb->type() != Element::MEASURE)
continue;
Measure* m = (Measure*)mb;
m->cmdRemoveStaves(sidx, eidx);
}
/* foreach(Beam* e, cs->beams()) {
int staffIdx = e->staffIdx();
if (staffIdx >= sidx && staffIdx < eidx)
cs->undoRemoveElement(e);
}
*/
cs->cmdRemoveStaff(sidx);
}
else if (sli->op == ITEM_ADD) {
Staff* staff = new Staff(cs, part, rstaff);
sli->staff = staff;
staff->setRstaff(rstaff);
++rstaff;
cs->undoInsertStaff(staff, staffIdx);
for (Measure* m = cs->firstMeasure(); m; m = m->nextMeasure()) {
// do not create whole measure rests for linked staves
m->cmdAddStaves(staffIdx, staffIdx+1, !sli->linked());
}
cs->adjustBracketsIns(staffIdx, staffIdx+1);
KeySigEvent nKey = part->staff(0)->key(0);
staff->setKey(0, nKey);
if (sli->linked()) {
int idx = cs->staffIdx(staff);
if (idx > 0) {
Staff* ostaff = cs->staff(idx - 1);
staff->setStaffType(ostaff->staffType());
cloneStaff(ostaff, staff);
}
}
++staffIdx;
}
else {
++staffIdx;
++rstaff;
}
}
}
}
//
// sort staves
//
QList<Staff*> dst;
for (int idx = 0; idx < pl->topLevelItemCount(); ++idx) {
PartListItem* pli = (PartListItem*)pl->topLevelItem(idx);
if (pli->op == ITEM_DELETE)
continue;
QTreeWidgetItem* ci = 0;
for (int cidx = 0; (ci = pli->child(cidx)); ++cidx) {
StaffListItem* sli = (StaffListItem*) ci;
if (sli->op == ITEM_DELETE)
continue;
dst.push_back(sli->staff);
}
}
QList<int> dl;
foreach(Staff* staff, dst) {
int idx = cs->staves().indexOf(staff);
if (idx == -1)
qDebug("staff in dialog(%p) not found in score\n", staff);
else
dl.push_back(idx);
}
// bool sort = false;
// for (int i = 0; i < dl.size(); ++i) {
// if (dl[i] != i) {
// sort = true;
// break;
// }
// }
// if (sort)
cs->undo(new SortStaves(cs, dl));
//
// check for valid barLineSpan and bracketSpan
// in all staves
//
int n = cs->nstaves();
for (int i = 0; i < n; ++i) {
Staff* staff = cs->staff(i);
if (staff->barLineSpan() > (n - i))
cs->undoChangeBarLineSpan(staff, n - i, 0, cs->staff(n-1)->lines()-1);
QList<BracketItem> brackets = staff->brackets();
int nn = brackets.size();
for (int ii = 0; ii < nn; ++ii) {
if ((brackets[ii]._bracket != -1) && (brackets[ii]._bracketSpan > (n - i)))
cs->undoChangeBracketSpan(staff, ii, n - i);
}
}
//
// there should be at least one measure
//
if (cs->measures()->size() == 0)
cs->insertMeasure(Element::MEASURE, 0, false);
cs->setLayoutAll(true);
cs->endCmd();
cs->rebuildMidiMapping();
seq->initInstruments();
}
//---------------------------------------------------------
// on_saveButton_clicked
//---------------------------------------------------------
void InstrumentsDialog::on_saveButton_clicked()
{
QString name = QFileDialog::getSaveFileName(
this,
tr("MuseScore: Save Instrument List"),
".",
tr("MuseScore Instruments (*.xml);;")
);
if (name.isEmpty())
return;
QString ext(".xml");
QFileInfo info(name);
if (info.suffix().isEmpty())
info.setFile(info.filePath() + ext);
QFile f(info.filePath());
if (!f.open(QIODevice::WriteOnly)) {
QString s = tr("Open Instruments File\n") + f.fileName() + tr("\nfailed: ")
+ QString(strerror(errno));
QMessageBox::critical(mscore, tr("MuseScore: Open Instruments file"), s);
return;
}
Xml xml(&f);
xml.header();
xml.stag("museScore version=\"" MSC_VERSION "\"");
foreach(InstrumentGroup* g, instrumentGroups) {
xml.stag(QString("InstrumentGroup name=\"%1\" extended=\"%2\"").arg(g->name).arg(g->extended));
foreach(InstrumentTemplate* t, g->instrumentTemplates)
t->write(xml);
xml.etag();
}
xml.etag();
if (f.error() != QFile::NoError) {
QString s = tr("Write Style failed: ") + f.errorString();
QMessageBox::critical(this, tr("MuseScore: Write Style"), s);
}
}
//---------------------------------------------------------
// on_loadButton_clicked
//---------------------------------------------------------
void InstrumentsDialog::on_loadButton_clicked()
{
QString fn = QFileDialog::getOpenFileName(
this, tr("MuseScore: Load Instrument List"),
mscoreGlobalShare + "/templates",
tr("MuseScore Instruments (*.xml);;"
"All files (*)"
)
);
if (fn.isEmpty())
return;
QFile f(fn);
if (!loadInstrumentTemplates(fn)) {
QMessageBox::warning(0,
QWidget::tr("MuseScore: load Style failed:"),
QString(strerror(errno)),
QString::null, QWidget::tr("Quit"), QString::null, 0, 1);
return;
}
buildTemplateList();
}
//---------------------------------------------------------
// filterInstruments
//---------------------------------------------------------
void filterInstruments(QTreeWidget* instrumentList, const QString &searchPhrase)
{
QTreeWidgetItem* item = 0;
for (int idx = 0; (item = instrumentList->topLevelItem(idx)); ++idx) {
int numMatchedChildren = 0;
QTreeWidgetItem* ci = 0;
for (int cidx = 0; (ci = item->child(cidx)); ++cidx) {
// replace the unicode b (accidential) so a search phrase of "bb" would give Bb Trumpet...
QString text = ci->text(0).replace(QChar(0x266d), QChar('b'));
bool isMatch = text.contains(searchPhrase, Qt::CaseInsensitive);
ci->setHidden(!isMatch);
if (isMatch)
numMatchedChildren++;
}
item->setHidden(numMatchedChildren == 0);
item->setExpanded(numMatchedChildren > 0 && !searchPhrase.isEmpty());
}
}
//---------------------------------------------------------
// on_search_textChanged
//---------------------------------------------------------
void InstrumentsDialog::on_search_textChanged(const QString &searchPhrase)
{
filterInstruments(instrumentList, searchPhrase);
}
//---------------------------------------------------------
// on_clearSearch_clicked
//---------------------------------------------------------
void InstrumentsDialog::on_clearSearch_clicked()
{
search->clear();
filterInstruments (instrumentList);
}