2014-08-16 11:41:36 +02:00
|
|
|
//=============================================================================
|
|
|
|
// 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 "icons.h"
|
|
|
|
#include "instrwidget.h"
|
2018-02-26 09:06:45 +01:00
|
|
|
#include "stringutils.h"
|
2014-08-16 11:41:36 +02:00
|
|
|
|
|
|
|
#include "libmscore/clef.h"
|
|
|
|
#include "libmscore/instrtemplate.h"
|
|
|
|
#include "libmscore/line.h"
|
|
|
|
#include "libmscore/measure.h"
|
|
|
|
#include "libmscore/part.h"
|
|
|
|
#include "libmscore/score.h"
|
|
|
|
#include "libmscore/segment.h"
|
|
|
|
#include "libmscore/staff.h"
|
|
|
|
#include "libmscore/stafftype.h"
|
|
|
|
#include "libmscore/style.h"
|
|
|
|
#include "libmscore/system.h"
|
|
|
|
#include "libmscore/stringdata.h"
|
|
|
|
#include "libmscore/undo.h"
|
|
|
|
#include "libmscore/keysig.h"
|
|
|
|
|
|
|
|
namespace Ms {
|
|
|
|
|
|
|
|
void filterInstruments(QTreeWidget *instrumentList, const QString &searchPhrase = QString());
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// 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) {
|
2018-02-14 20:20:21 +01:00
|
|
|
// replace the unicode b (accidental) so a search phrase of "bb" would give Bb Trumpet...
|
2014-08-16 11:41:36 +02:00
|
|
|
QString text = ci->text(0).replace(QChar(0x266d), QChar('b'));
|
2018-02-26 09:06:45 +01:00
|
|
|
|
|
|
|
// remove ligatures and diacritics
|
|
|
|
QString removedSpecialChar = stringutils::removeLigatures(text);
|
|
|
|
removedSpecialChar = stringutils::removeDiacritics(removedSpecialChar);
|
|
|
|
|
|
|
|
bool isMatch = text.contains(searchPhrase, Qt::CaseInsensitive) || removedSpecialChar.contains(searchPhrase, Qt::CaseInsensitive);
|
2014-08-16 11:41:36 +02:00
|
|
|
ci->setHidden(!isMatch);
|
|
|
|
|
|
|
|
if (isMatch)
|
|
|
|
numMatchedChildren++;
|
|
|
|
}
|
|
|
|
|
|
|
|
item->setHidden(numMatchedChildren == 0);
|
|
|
|
item->setExpanded(numMatchedChildren > 0 && !searchPhrase.isEmpty());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// StaffListItem
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
StaffListItem::StaffListItem(PartListItem* li)
|
|
|
|
: QTreeWidgetItem(li, STAFF_LIST_ITEM)
|
|
|
|
{
|
|
|
|
setPartIdx(0);
|
|
|
|
setLinked(false);
|
|
|
|
setClefType(ClefTypeList(ClefType::G));
|
|
|
|
initStaffTypeCombo();
|
|
|
|
}
|
|
|
|
|
|
|
|
StaffListItem::StaffListItem()
|
|
|
|
: QTreeWidgetItem(STAFF_LIST_ITEM)
|
|
|
|
{
|
|
|
|
setPartIdx(0);
|
|
|
|
setLinked(false);
|
|
|
|
setClefType(ClefTypeList(ClefType::G));
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// initStaffTypeCombo
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void StaffListItem::initStaffTypeCombo(bool forceRecreate)
|
|
|
|
{
|
|
|
|
if (_staffTypeCombo && !forceRecreate) // do not init more than once
|
|
|
|
return;
|
|
|
|
|
|
|
|
// NOTE: DO NOT DELETE the old _staffTypeCombo if already created:
|
|
|
|
// a bug in Qt looses track of (and presumably deletes) the combo set into the item
|
|
|
|
// if the item is repositioned in the tree; in this case, the pointer to the combo
|
|
|
|
// is no longer valid and cannot be used to delete it
|
|
|
|
// Call initStaffTypeCombo(true) ONLY if the item has been repositioned
|
|
|
|
// or a memory leak may result
|
|
|
|
|
|
|
|
bool canUseTabs = false; // assume only normal staves are applicable
|
2018-05-02 19:22:28 +02:00
|
|
|
int numFrettedStrings = 0;
|
2015-02-11 13:12:25 +01:00
|
|
|
bool canUsePerc = false;
|
2014-08-16 11:41:36 +02:00
|
|
|
PartListItem* part = static_cast<PartListItem*>(QTreeWidgetItem::parent());
|
|
|
|
|
|
|
|
// PartListItem has different members filled out if used in New Score Wizard
|
|
|
|
// or in Instruments Wizard
|
|
|
|
if (part) {
|
|
|
|
const StringData* stringData = part->it ? &(part->it->stringData) :
|
2015-03-13 11:16:43 +01:00
|
|
|
( (part->part && part->part->instrument()) ? part->part->instrument()->stringData() : 0);
|
2018-05-02 19:22:28 +02:00
|
|
|
canUseTabs = stringData && stringData->frettedStrings() > 0;
|
|
|
|
if (canUseTabs)
|
|
|
|
numFrettedStrings = stringData->frettedStrings();
|
2014-08-16 11:41:36 +02:00
|
|
|
canUsePerc = part->it ? part->it->useDrumset :
|
2015-03-13 11:16:43 +01:00
|
|
|
( (part->part && part->part->instrument()) ? part->part->instrument()->useDrumset() : false);
|
2014-08-16 11:41:36 +02:00
|
|
|
}
|
|
|
|
_staffTypeCombo = new QComboBox();
|
|
|
|
_staffTypeCombo->setAutoFillBackground(true);
|
|
|
|
int idx = 0;
|
|
|
|
for (const StaffType& st : StaffType::presets()) {
|
2015-02-11 13:12:25 +01:00
|
|
|
if ( (st.group() == StaffGroup::STANDARD && (!canUsePerc)) // percussion excludes standard
|
|
|
|
|| (st.group() == StaffGroup::PERCUSSION && canUsePerc)
|
2018-05-02 19:22:28 +02:00
|
|
|
|| (st.group() == StaffGroup::TAB && canUseTabs && st.lines() <= numFrettedStrings)) {
|
2014-08-16 11:41:36 +02:00
|
|
|
_staffTypeCombo->addItem(st.name(), idx);
|
|
|
|
}
|
|
|
|
++idx;
|
|
|
|
}
|
|
|
|
treeWidget()->setItemWidget(this, 4, _staffTypeCombo);
|
|
|
|
connect(_staffTypeCombo, SIGNAL(currentIndexChanged(int)), SLOT(staffTypeChanged(int)) );
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// setPartIdx
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void StaffListItem::setPartIdx(int val)
|
|
|
|
{
|
|
|
|
_partIdx = val;
|
|
|
|
setText(0, InstrumentsWidget::tr("Staff %1").arg(_partIdx + 1));
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// setClefType
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void StaffListItem::setClefType(const ClefTypeList& val)
|
|
|
|
{
|
|
|
|
_clefType = val;
|
|
|
|
setText(2, qApp->translate("clefTable", ClefInfo::name(_clefType._transposingClef)));
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// setLinked
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void StaffListItem::setLinked(bool val)
|
|
|
|
{
|
|
|
|
_linked = val;
|
|
|
|
setIcon(3, _linked ? *icons[int(Icons::checkmark_ICON)] : QIcon() );
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// setStaffType
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void StaffListItem::setStaffType(const StaffType* st)
|
|
|
|
{
|
|
|
|
if (!st) // if no staff type given, dault to stadard
|
|
|
|
_staffTypeCombo->setCurrentIndex(0); // staff type (at combo box index 0)
|
|
|
|
else {
|
|
|
|
// if staff type given, look into combo box item data for a preset equal to staff type
|
|
|
|
for (int i = 0; i < _staffTypeCombo->count(); ++i) {
|
|
|
|
const StaffType* _st = StaffType::preset(StaffTypes(_staffTypeCombo->itemData(i).toInt()));
|
|
|
|
if (*_st == *st) {
|
|
|
|
_staffTypeCombo->setCurrentIndex(i);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// try harder
|
|
|
|
for (int i = 0; i < _staffTypeCombo->count(); ++i) {
|
|
|
|
const StaffType* _st = StaffType::preset(StaffTypes(_staffTypeCombo->itemData(i).toInt()));
|
|
|
|
if (_st->isSameStructure(*st)) {
|
|
|
|
_staffTypeCombo->setCurrentIndex(i);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
qDebug("StaffListItem::setStaffType: not found\n");
|
|
|
|
_staffTypeCombo->setCurrentIndex(0); // if none found, default to standard staff type
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// setStaffType
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void StaffListItem::setStaffType(int idx)
|
|
|
|
{
|
|
|
|
int i = _staffTypeCombo->findData(idx);
|
|
|
|
if (i != -1)
|
|
|
|
_staffTypeCombo->setCurrentIndex(i);
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// staffType
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
const StaffType* StaffListItem::staffType() const
|
|
|
|
{
|
|
|
|
return StaffType::preset(StaffTypes((staffTypeIdx())));
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// staffTypeIdx
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
int StaffListItem::staffTypeIdx() const
|
|
|
|
{
|
|
|
|
return _staffTypeCombo->itemData(_staffTypeCombo->currentIndex()).toInt();
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// staffTypeChanged
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void StaffListItem::staffTypeChanged(int idx)
|
|
|
|
{
|
|
|
|
// check current clef matches new staff type
|
|
|
|
int staffTypeIdx = _staffTypeCombo->itemData(idx).toInt();
|
|
|
|
const StaffType* stfType = StaffType::preset(StaffTypes(staffTypeIdx));
|
|
|
|
|
|
|
|
PartListItem* pli = static_cast<PartListItem*>(QTreeWidgetItem::parent());
|
|
|
|
pli->updateClefs();
|
|
|
|
|
2016-12-13 13:16:17 +01:00
|
|
|
if (_staff && _staff->staffType(0)->name() != stfType->name()) {
|
2014-08-16 11:41:36 +02:00
|
|
|
if (_op != ListItemOp::I_DELETE && _op != ListItemOp::ADD)
|
|
|
|
_op = ListItemOp::UPDATE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// setVisible
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void PartListItem::setVisible(bool val)
|
|
|
|
{
|
|
|
|
setCheckState(1, val ? Qt::Checked : Qt::Unchecked);
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// visible
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
bool PartListItem::visible() const
|
|
|
|
{
|
|
|
|
return checkState(1) == Qt::Checked;
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// updateClefs
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void PartListItem::updateClefs()
|
|
|
|
{
|
|
|
|
for (int i = 0; i < childCount(); ++i) {
|
|
|
|
StaffListItem* sli = static_cast<StaffListItem*>(child(i));
|
|
|
|
const StaffType* stfType = StaffType::preset(StaffTypes(sli->staffTypeIdx()));
|
|
|
|
|
|
|
|
ClefTypeList clefType;
|
|
|
|
switch (stfType->group()) {
|
|
|
|
case StaffGroup::STANDARD:
|
|
|
|
clefType = sli->defaultClefType();
|
|
|
|
break;
|
|
|
|
case StaffGroup::TAB:
|
|
|
|
clefType = ClefTypeList(ClefType::TAB);
|
|
|
|
break;
|
|
|
|
case StaffGroup::PERCUSSION:
|
|
|
|
clefType = ClefTypeList(ClefType::PERC);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
sli->setClefType(clefType);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// PartListItem
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
PartListItem::PartListItem(Part* p, QTreeWidget* lv)
|
|
|
|
: QTreeWidgetItem(lv, PART_LIST_ITEM)
|
|
|
|
{
|
|
|
|
part = p;
|
|
|
|
it = 0;
|
|
|
|
op = ListItemOp::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 = ListItemOp::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("");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// InstrumentsWidget
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
InstrumentsWidget::InstrumentsWidget(QWidget* parent)
|
|
|
|
: QWidget(parent)
|
|
|
|
{
|
|
|
|
setupUi(this);
|
|
|
|
splitter->setStretchFactor(0, 10);
|
|
|
|
splitter->setStretchFactor(1, 0);
|
|
|
|
splitter->setStretchFactor(2, 15);
|
|
|
|
setWindowFlags(this->windowFlags() & ~Qt::WindowContextHelpButtonHint);
|
|
|
|
|
|
|
|
instrumentList->setSelectionMode(QAbstractItemView::ExtendedSelection);
|
|
|
|
partiturList->setSelectionMode(QAbstractItemView::SingleSelection);
|
2014-10-15 19:48:38 +02:00
|
|
|
QStringList header = (QStringList() << tr("Staves") << tr("Visible") << tr("Clef") << tr("Linked") << tr("Staff type"));
|
2014-08-16 11:41:36 +02:00
|
|
|
partiturList->setHeaderLabels(header);
|
|
|
|
partiturList->resizeColumnToContents(1); // shrink "visible "and "linked" columns as much as possible
|
|
|
|
partiturList->resizeColumnToContents(3);
|
|
|
|
|
|
|
|
buildTemplateList();
|
|
|
|
|
|
|
|
addButton->setEnabled(false);
|
|
|
|
removeButton->setEnabled(false);
|
|
|
|
upButton->setEnabled(false);
|
|
|
|
downButton->setEnabled(false);
|
|
|
|
belowButton->setEnabled(false);
|
|
|
|
linkedButton->setEnabled(false);
|
|
|
|
|
|
|
|
connect(instrumentList, SIGNAL(clicked(const QModelIndex &)), SLOT(expandOrCollapse(const QModelIndex &)));
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// populateGenreCombo
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void populateGenreCombo(QComboBox* combo)
|
|
|
|
{
|
|
|
|
combo->clear();
|
|
|
|
combo->addItem(qApp->translate("InstrumentsDialog", "All instruments"), "all");
|
|
|
|
int i = 1;
|
|
|
|
int defaultIndex = 0;
|
|
|
|
foreach (InstrumentGenre *ig, instrumentGenres) {
|
|
|
|
combo->addItem(ig->name, ig->id);
|
|
|
|
if (ig->id == "common")
|
|
|
|
defaultIndex = i;
|
|
|
|
++i;
|
|
|
|
}
|
|
|
|
combo->setCurrentIndex(defaultIndex);
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// populateInstrumentList
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void populateInstrumentList(QTreeWidget* instrumentList)
|
|
|
|
{
|
|
|
|
instrumentList->clear();
|
2018-06-05 20:17:21 +02:00
|
|
|
// TODO: memory leak?
|
2014-08-16 11:41:36 +02:00
|
|
|
foreach(InstrumentGroup* g, instrumentGroups) {
|
|
|
|
InstrumentTemplateListItem* group = new InstrumentTemplateListItem(g->name, instrumentList);
|
|
|
|
group->setFlags(Qt::ItemIsEnabled);
|
2018-08-14 10:03:49 +02:00
|
|
|
for (InstrumentTemplate* t : g->instrumentTemplates) {
|
2014-08-16 11:41:36 +02:00
|
|
|
new InstrumentTemplateListItem(t, group);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// buildTemplateList
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void InstrumentsWidget::buildTemplateList()
|
|
|
|
{
|
|
|
|
// clear search if instrument list is updated
|
|
|
|
search->clear();
|
|
|
|
|
|
|
|
populateInstrumentList(instrumentList);
|
|
|
|
populateGenreCombo(instrumentGenreFilter);
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// expandOrCollapse
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void InstrumentsWidget::expandOrCollapse(const QModelIndex &model)
|
|
|
|
{
|
|
|
|
if(instrumentList->isExpanded(model))
|
|
|
|
instrumentList->collapse(model);
|
|
|
|
else
|
|
|
|
instrumentList->expand(model);
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// genPartList
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void InstrumentsWidget::genPartList(Score* cs)
|
|
|
|
{
|
|
|
|
partiturList->clear();
|
|
|
|
|
2016-12-13 13:16:17 +01:00
|
|
|
foreach (Part* p, cs->parts()) {
|
2014-08-16 11:41:36 +02:00
|
|
|
PartListItem* pli = new PartListItem(p, partiturList);
|
|
|
|
pli->setVisible(p->show());
|
2018-08-14 10:03:49 +02:00
|
|
|
for (Staff* s : *p->staves()) {
|
2014-08-16 11:41:36 +02:00
|
|
|
StaffListItem* sli = new StaffListItem(pli);
|
|
|
|
sli->setStaff(s);
|
|
|
|
sli->setClefType(s->clefType(0));
|
|
|
|
sli->setDefaultClefType(s->defaultClefType());
|
|
|
|
sli->setPartIdx(s->rstaff());
|
2018-04-27 13:29:20 +02:00
|
|
|
const LinkedElements* ls = s->links();
|
2014-08-16 11:41:36 +02:00
|
|
|
bool bLinked = false;
|
2016-02-06 22:03:43 +01:00
|
|
|
if (ls && !ls->empty()) {
|
2018-04-27 13:29:20 +02:00
|
|
|
for (auto le : *ls) {
|
|
|
|
Staff* ps = toStaff(le);
|
2014-08-16 11:41:36 +02:00
|
|
|
if (ps != s && ps->score() == s->score()) {
|
|
|
|
bLinked = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
sli->setLinked(bLinked);
|
2016-12-13 13:16:17 +01:00
|
|
|
sli->setStaffType(s->staffType(0)); // TODO
|
2014-08-16 11:41:36 +02:00
|
|
|
}
|
|
|
|
pli->updateClefs();
|
|
|
|
partiturList->setItemExpanded(pli, true);
|
|
|
|
}
|
|
|
|
partiturList->resizeColumnToContents(2); // adjust width of "Clef " and "Staff type" columns
|
|
|
|
partiturList->resizeColumnToContents(4);
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// on_instrumentList_itemSelectionChanged
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void InstrumentsWidget::on_instrumentList_itemSelectionChanged()
|
|
|
|
{
|
|
|
|
QList<QTreeWidgetItem*> wi = instrumentList->selectedItems();
|
|
|
|
bool flag = !wi.isEmpty();
|
|
|
|
addButton->setEnabled(flag);
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// on_partiturList_itemSelectionChanged
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void InstrumentsWidget::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 InstrumentsWidget::on_instrumentList_itemDoubleClicked(QTreeWidgetItem*, int)
|
|
|
|
{
|
|
|
|
on_addButton_clicked();
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// on_addButton_clicked
|
|
|
|
// add instrument to partitur
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void InstrumentsWidget::on_addButton_clicked()
|
|
|
|
{
|
|
|
|
foreach(QTreeWidgetItem* i, instrumentList->selectedItems()) {
|
|
|
|
InstrumentTemplateListItem* item = static_cast<InstrumentTemplateListItem*>(i);
|
|
|
|
const InstrumentTemplate* it = item->instrumentTemplate();
|
|
|
|
if (it == 0)
|
|
|
|
continue;
|
|
|
|
PartListItem* pli = new PartListItem(it, partiturList);
|
|
|
|
pli->setFirstColumnSpanned(true);
|
|
|
|
pli->op = ListItemOp::ADD;
|
|
|
|
|
|
|
|
int n = it->nstaves();
|
|
|
|
for (int i = 0; i < n; ++i) {
|
|
|
|
StaffListItem* sli = new StaffListItem(pli);
|
|
|
|
sli->setOp(ListItemOp::ADD);
|
|
|
|
sli->setStaff(0);
|
|
|
|
sli->setPartIdx(i);
|
|
|
|
sli->setDefaultClefType(it->clefType(i));
|
|
|
|
sli->setStaffType(it->staffTypePreset);
|
|
|
|
}
|
|
|
|
pli->updateClefs();
|
|
|
|
partiturList->setItemExpanded(pli, true);
|
|
|
|
partiturList->clearSelection(); // should not be necessary
|
|
|
|
partiturList->setItemSelected(pli, true);
|
|
|
|
}
|
|
|
|
emit completeChanged(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// on_removeButton_clicked
|
|
|
|
// remove instrument from partitur
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void InstrumentsWidget::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() == ListItemOp::ADD) {
|
|
|
|
if (parent->childCount() == 1) {
|
|
|
|
partiturList->takeTopLevelItem(partiturList->indexOfTopLevelItem(parent));
|
|
|
|
delete parent;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
parent->takeChild(parent->indexOfChild(item));
|
|
|
|
delete item;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
((StaffListItem*)item)->setOp(ListItemOp::I_DELETE);
|
|
|
|
item->setHidden(true);
|
2014-12-01 12:29:36 +01:00
|
|
|
|
|
|
|
// check if a staff is linked to this staff
|
|
|
|
|
|
|
|
int idx = parent->indexOfChild(item);
|
|
|
|
StaffListItem* sli = static_cast<StaffListItem*>(parent->child(idx+1));
|
|
|
|
if (sli) {
|
|
|
|
StaffListItem* sli2 = static_cast<StaffListItem*>(parent->child(idx+2));
|
|
|
|
if (sli->linked() && !(sli2 && sli2->linked())) {
|
|
|
|
sli->setLinked(false);
|
|
|
|
partiturList->update();
|
|
|
|
}
|
|
|
|
}
|
2014-08-16 11:41:36 +02:00
|
|
|
}
|
|
|
|
static_cast<PartListItem*>(parent)->updateClefs();
|
2015-02-16 12:05:00 +01:00
|
|
|
partiturList->setItemSelected(parent, true);
|
2014-08-16 11:41:36 +02:00
|
|
|
}
|
|
|
|
else {
|
2015-02-16 12:05:00 +01:00
|
|
|
int idx = partiturList->indexOfTopLevelItem(item);
|
2014-08-16 11:41:36 +02:00
|
|
|
if (((PartListItem*)item)->op == ListItemOp::ADD)
|
|
|
|
delete item;
|
|
|
|
else {
|
|
|
|
((PartListItem*)item)->op = ListItemOp::I_DELETE;
|
|
|
|
item->setHidden(true);
|
|
|
|
}
|
2015-02-16 12:05:00 +01:00
|
|
|
// select an item, do not consider hidden ones
|
|
|
|
int plusIdx = 0;
|
|
|
|
QTreeWidgetItem* nextParent = partiturList->topLevelItem(idx + plusIdx);
|
|
|
|
while (nextParent && nextParent->isHidden()) {
|
|
|
|
plusIdx++;
|
|
|
|
nextParent = partiturList->topLevelItem(idx + plusIdx);
|
|
|
|
}
|
|
|
|
if(!nextParent) { // could find after, check before
|
|
|
|
plusIdx = 1;
|
|
|
|
nextParent = partiturList->topLevelItem(idx - plusIdx);
|
|
|
|
while (nextParent && nextParent->isHidden()) {
|
|
|
|
plusIdx++;
|
|
|
|
nextParent = partiturList->topLevelItem(idx - plusIdx);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
partiturList->setItemSelected(nextParent, true);
|
2014-08-16 11:41:36 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// on_upButton_clicked
|
|
|
|
// move instrument up in partitur
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void InstrumentsWidget::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 part item not first, move one slot up
|
|
|
|
if (idx) {
|
|
|
|
partiturList->selectionModel()->clear();
|
|
|
|
QTreeWidgetItem* item = partiturList->takeTopLevelItem(idx);
|
|
|
|
// Qt looses the QComboBox set into StaffListItem's when they are re-inserted into the tree:
|
|
|
|
// get the currently selected staff type of each combo and re-insert
|
|
|
|
int numOfStaffListItems = item->childCount();
|
Solved all compilation errors on MSVC
This commit contains changes required for MuseScore to compile under MSVC with no errors.
There are several general categories of problems that resulted in errors with the compilation. Main issues:
- Variable Length Arrays (VLA). This is a non-standard extension to C++, supported by clang toolchains, but not by MSVC. The initial workaround is to use std::vector<> instead of VLAs, eventually (if needed) with the original variable pointing to the beginning of the allocated array. More efficient alternatives are possible if profiling shows any code using VLAs to be timing-critical.
- Floating-point constants not suffixed with "f" are doubles by default; in some instances, this leads to narrowing conversion errors (in other instances, just warnings).
- MSVC does not support "or"/"and"/"not" in lieu of "||"/"&&"/"!". Changed unconditionally to use standard C++ symbols.
- MSVC does not support the "__builtin_unreachable()" compiler hint. A similar, albeit not exactly equal, alternative is "__assume(0)", which is MSVC-specific.
- MSVC does not support ranges in case statements. Replaced with list of cases instead of range (non-conditionally)
Detailed changes, with per-file comments:
- all.h: opt-in to deprecated features, include <io.h> and <process.h> instead of POSIX <unistd.h>, undefine "STRING_NONE" and "small", which Microsoft defines as macros, which result in compilation errors.
- effects/compressor/zita.cpp: eliminated narrowing conversion error by appending "f" to float constants.
- fluid/voice.cpp: appended "f" to float constants to eliminate narrowing conversion errors/warnings
- libmscore/beam.cpp: conditionally replaced VLA
- libmscore/edit.cpp: conditionally replaced VLA
- libmscore/element.cpp: appended "f" to float constant
- libmscore/fret.cpp: changed or -> ||
- libmscore/layout.cpp: conditionally replaced VLA
- libmscore/mscore.cpp: conditionally replaced "__builtin_unreachable()" with "__assume(0)" for MSVC
- libmscore/scorefile.coo: use correct char representation conversion for MSVC
- libmscore/stringdata.cpp: conditionally replaced VLA
- libmscore/system.cpp: conditionally replaced VLA
- libmscroe/text.cpp: replaced range in case statement.
- manual/genManual.cpp: use getopt() replacement.
- midi/midifile.cpp: conditionally replaced VLA. This does not use the default replacement.
- mscore/bb.cpp: replaced range in case statement.
- mscore/capella.cpp: conditionally replaced VLA. Changed and -> &&
- mscore/driver:cpp: preclude errors due to macro redefinitions.
- mscore/editstyle.cpp: conditionally replaced "__builtin_unreachable()" with "__assume(0)" for MSVC
- mscore/importgtp-gp6.cpp: conditionally replaced VLA.
- mscore/instrwidget.cpp: conditionally replaced VLA.
- mscore/jackaudio.cpp: conditionally replaced VLA. Preclude errors due to macro redefinitions.
- mscore/jackweakapi.cpp: Preclude errors due to macro redefinitions. Replacement for __atribute__((constructor)) through static object construction for MSVC. Force use of LoadLibraryA instead of LoadLibrary.
- mscore/mididriver.h: Changed not -> !
- mscore/musescore.cpp: Changed not -> !. Conditionally replaced VLA.
- mscore/resourceManager.cpp: conditionally replaced VLA.
- mscore/timeline.cpp: conditionally replaced VLA.
- omr/omrpage.cpp: conditionally replaced VLA.
- synthesizer/msynthesizer.cpp: replaced UNIX sleep(1) method with MSVC Sleep(1000) (equivalent, but in ms instead of seconds)
- synthesizer/msynthsizer.h: appended "f" to float constant
- thirdparty/poppler/config.h: set defines for MSVC to preclude the use of inexistent libraries.
- thirdparty/poppler/poppler/poppler-config.h: set defines for MSVC to preclude the use of inexistent libraries. Eliminated #defines for fmin and fmax which where causing problems.
- thirdparty/poppler/poppler/PSOutputDev.cc: added #include <algorithm> for std::min() and std::max(). Note this is required per-C++ standard.
- thirdparty/portmidi/pm_win/pmwinmm.c: undefined UNICODE to use char-based library functions.
- thirdparty/qzip/qzip.cpp: changed or -> ||
- thirdparty/rtf2html/rtf_keyword.h: file format changed from Apple to UNIX, as MSVC does not supported the former.
(NOT error related, just improvement on previous commit; manual/getopt/README.md: added link to source article)
2018-05-01 19:14:44 +02:00
|
|
|
#if (!defined (_MSCVER) && !defined (_MSC_VER))
|
2014-08-16 11:41:36 +02:00
|
|
|
int staffIdx[numOfStaffListItems];
|
Solved all compilation errors on MSVC
This commit contains changes required for MuseScore to compile under MSVC with no errors.
There are several general categories of problems that resulted in errors with the compilation. Main issues:
- Variable Length Arrays (VLA). This is a non-standard extension to C++, supported by clang toolchains, but not by MSVC. The initial workaround is to use std::vector<> instead of VLAs, eventually (if needed) with the original variable pointing to the beginning of the allocated array. More efficient alternatives are possible if profiling shows any code using VLAs to be timing-critical.
- Floating-point constants not suffixed with "f" are doubles by default; in some instances, this leads to narrowing conversion errors (in other instances, just warnings).
- MSVC does not support "or"/"and"/"not" in lieu of "||"/"&&"/"!". Changed unconditionally to use standard C++ symbols.
- MSVC does not support the "__builtin_unreachable()" compiler hint. A similar, albeit not exactly equal, alternative is "__assume(0)", which is MSVC-specific.
- MSVC does not support ranges in case statements. Replaced with list of cases instead of range (non-conditionally)
Detailed changes, with per-file comments:
- all.h: opt-in to deprecated features, include <io.h> and <process.h> instead of POSIX <unistd.h>, undefine "STRING_NONE" and "small", which Microsoft defines as macros, which result in compilation errors.
- effects/compressor/zita.cpp: eliminated narrowing conversion error by appending "f" to float constants.
- fluid/voice.cpp: appended "f" to float constants to eliminate narrowing conversion errors/warnings
- libmscore/beam.cpp: conditionally replaced VLA
- libmscore/edit.cpp: conditionally replaced VLA
- libmscore/element.cpp: appended "f" to float constant
- libmscore/fret.cpp: changed or -> ||
- libmscore/layout.cpp: conditionally replaced VLA
- libmscore/mscore.cpp: conditionally replaced "__builtin_unreachable()" with "__assume(0)" for MSVC
- libmscore/scorefile.coo: use correct char representation conversion for MSVC
- libmscore/stringdata.cpp: conditionally replaced VLA
- libmscore/system.cpp: conditionally replaced VLA
- libmscroe/text.cpp: replaced range in case statement.
- manual/genManual.cpp: use getopt() replacement.
- midi/midifile.cpp: conditionally replaced VLA. This does not use the default replacement.
- mscore/bb.cpp: replaced range in case statement.
- mscore/capella.cpp: conditionally replaced VLA. Changed and -> &&
- mscore/driver:cpp: preclude errors due to macro redefinitions.
- mscore/editstyle.cpp: conditionally replaced "__builtin_unreachable()" with "__assume(0)" for MSVC
- mscore/importgtp-gp6.cpp: conditionally replaced VLA.
- mscore/instrwidget.cpp: conditionally replaced VLA.
- mscore/jackaudio.cpp: conditionally replaced VLA. Preclude errors due to macro redefinitions.
- mscore/jackweakapi.cpp: Preclude errors due to macro redefinitions. Replacement for __atribute__((constructor)) through static object construction for MSVC. Force use of LoadLibraryA instead of LoadLibrary.
- mscore/mididriver.h: Changed not -> !
- mscore/musescore.cpp: Changed not -> !. Conditionally replaced VLA.
- mscore/resourceManager.cpp: conditionally replaced VLA.
- mscore/timeline.cpp: conditionally replaced VLA.
- omr/omrpage.cpp: conditionally replaced VLA.
- synthesizer/msynthesizer.cpp: replaced UNIX sleep(1) method with MSVC Sleep(1000) (equivalent, but in ms instead of seconds)
- synthesizer/msynthsizer.h: appended "f" to float constant
- thirdparty/poppler/config.h: set defines for MSVC to preclude the use of inexistent libraries.
- thirdparty/poppler/poppler/poppler-config.h: set defines for MSVC to preclude the use of inexistent libraries. Eliminated #defines for fmin and fmax which where causing problems.
- thirdparty/poppler/poppler/PSOutputDev.cc: added #include <algorithm> for std::min() and std::max(). Note this is required per-C++ standard.
- thirdparty/portmidi/pm_win/pmwinmm.c: undefined UNICODE to use char-based library functions.
- thirdparty/qzip/qzip.cpp: changed or -> ||
- thirdparty/rtf2html/rtf_keyword.h: file format changed from Apple to UNIX, as MSVC does not supported the former.
(NOT error related, just improvement on previous commit; manual/getopt/README.md: added link to source article)
2018-05-01 19:14:44 +02:00
|
|
|
#else
|
|
|
|
// MSVC does not support VLA. Replace with std::vector. If profiling determines that the
|
|
|
|
// heap allocation is slow, an optimization might be used.
|
|
|
|
std::vector<int> staffIdx(numOfStaffListItems);
|
|
|
|
#endif
|
2014-08-16 11:41:36 +02:00
|
|
|
for (int itemIdx=0; itemIdx < numOfStaffListItems; ++itemIdx)
|
|
|
|
staffIdx[itemIdx] = (static_cast<StaffListItem*>(item->child(itemIdx)))->staffTypeIdx();
|
2015-02-16 12:05:00 +01:00
|
|
|
// do not consider hidden ones
|
|
|
|
int minusIdx = 1;
|
|
|
|
QTreeWidgetItem* prevParent = partiturList->topLevelItem(idx - minusIdx);
|
|
|
|
while (prevParent && prevParent->isHidden()) {
|
|
|
|
minusIdx++;
|
|
|
|
prevParent = partiturList->topLevelItem(idx - minusIdx);
|
|
|
|
}
|
|
|
|
partiturList->insertTopLevelItem(idx - minusIdx, item);
|
2014-08-16 11:41:36 +02:00
|
|
|
// after-re-insertion, recreate each combo and set its index
|
|
|
|
for (int itemIdx=0; itemIdx < numOfStaffListItems; ++itemIdx) {
|
|
|
|
StaffListItem* staffItem = static_cast<StaffListItem*>(item->child(itemIdx));
|
|
|
|
staffItem->initStaffTypeCombo(true);
|
|
|
|
staffItem->setStaffType(staffIdx[itemIdx]);
|
|
|
|
}
|
|
|
|
partiturList->setItemExpanded(item, isExpanded);
|
|
|
|
partiturList->setItemSelected(item, true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
QTreeWidgetItem* parent = item->parent();
|
|
|
|
int idx = parent->indexOfChild(item);
|
|
|
|
// if staff item not first of its part, move one slot up
|
|
|
|
if (idx) {
|
|
|
|
partiturList->selectionModel()->clear();
|
|
|
|
StaffListItem* item = static_cast<StaffListItem*>(parent->takeChild(idx));
|
|
|
|
// Qt looses the QComboBox set into StaffListItem when it is re-inserted into the tree:
|
|
|
|
// get currently selected staff type and re-insert
|
|
|
|
int staffTypeIdx = item->staffTypeIdx();
|
2015-02-16 12:05:00 +01:00
|
|
|
parent->insertChild(idx - 1, item);
|
2014-08-16 11:41:36 +02:00
|
|
|
// after item has been inserted into the tree, create a new QComboBox and set its index
|
|
|
|
item->initStaffTypeCombo(true);
|
|
|
|
item->setStaffType(staffTypeIdx);
|
|
|
|
partiturList->setItemSelected(item, true);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// if staff item first of its part...
|
|
|
|
int parentIdx = partiturList->indexOfTopLevelItem(parent);
|
|
|
|
// ...and there is a previous part, move staff item to previous part
|
|
|
|
if (parentIdx) {
|
|
|
|
partiturList->selectionModel()->clear();
|
|
|
|
QTreeWidgetItem* prevParent = partiturList->topLevelItem(parentIdx - 1);
|
|
|
|
StaffListItem* sli = static_cast<StaffListItem*>(parent->takeChild(idx));
|
|
|
|
int staffTypeIdx = sli->staffTypeIdx();
|
|
|
|
prevParent->addChild(sli);
|
|
|
|
sli->initStaffTypeCombo(true);
|
|
|
|
sli->setStaffType(staffTypeIdx);
|
|
|
|
partiturList->setItemSelected(sli, true);
|
|
|
|
// PartListItem* pli = static_cast<PartListItem*>(prevParent);
|
|
|
|
// int idx = pli->part->nstaves();
|
|
|
|
//?? cs->undo(new MoveStaff(sli->staff(), pli->part, idx));
|
|
|
|
//
|
|
|
|
// TODO : if staff was linked to a staff of the old parent part, unlink it!
|
|
|
|
//
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// on_downButton_clicked
|
|
|
|
// move instrument down in partitur
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void InstrumentsWidget::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 part not last, move one slot down
|
|
|
|
if (idx < (n-1)) {
|
|
|
|
partiturList->selectionModel()->clear();
|
|
|
|
QTreeWidgetItem* item = partiturList->takeTopLevelItem(idx);
|
|
|
|
// Qt looses the QComboBox set into StaffListItem's when they are re-inserted into the tree:
|
|
|
|
// get the currently selected staff type of each combo and re-insert
|
|
|
|
int numOfStaffListItems = item->childCount();
|
Solved all compilation errors on MSVC
This commit contains changes required for MuseScore to compile under MSVC with no errors.
There are several general categories of problems that resulted in errors with the compilation. Main issues:
- Variable Length Arrays (VLA). This is a non-standard extension to C++, supported by clang toolchains, but not by MSVC. The initial workaround is to use std::vector<> instead of VLAs, eventually (if needed) with the original variable pointing to the beginning of the allocated array. More efficient alternatives are possible if profiling shows any code using VLAs to be timing-critical.
- Floating-point constants not suffixed with "f" are doubles by default; in some instances, this leads to narrowing conversion errors (in other instances, just warnings).
- MSVC does not support "or"/"and"/"not" in lieu of "||"/"&&"/"!". Changed unconditionally to use standard C++ symbols.
- MSVC does not support the "__builtin_unreachable()" compiler hint. A similar, albeit not exactly equal, alternative is "__assume(0)", which is MSVC-specific.
- MSVC does not support ranges in case statements. Replaced with list of cases instead of range (non-conditionally)
Detailed changes, with per-file comments:
- all.h: opt-in to deprecated features, include <io.h> and <process.h> instead of POSIX <unistd.h>, undefine "STRING_NONE" and "small", which Microsoft defines as macros, which result in compilation errors.
- effects/compressor/zita.cpp: eliminated narrowing conversion error by appending "f" to float constants.
- fluid/voice.cpp: appended "f" to float constants to eliminate narrowing conversion errors/warnings
- libmscore/beam.cpp: conditionally replaced VLA
- libmscore/edit.cpp: conditionally replaced VLA
- libmscore/element.cpp: appended "f" to float constant
- libmscore/fret.cpp: changed or -> ||
- libmscore/layout.cpp: conditionally replaced VLA
- libmscore/mscore.cpp: conditionally replaced "__builtin_unreachable()" with "__assume(0)" for MSVC
- libmscore/scorefile.coo: use correct char representation conversion for MSVC
- libmscore/stringdata.cpp: conditionally replaced VLA
- libmscore/system.cpp: conditionally replaced VLA
- libmscroe/text.cpp: replaced range in case statement.
- manual/genManual.cpp: use getopt() replacement.
- midi/midifile.cpp: conditionally replaced VLA. This does not use the default replacement.
- mscore/bb.cpp: replaced range in case statement.
- mscore/capella.cpp: conditionally replaced VLA. Changed and -> &&
- mscore/driver:cpp: preclude errors due to macro redefinitions.
- mscore/editstyle.cpp: conditionally replaced "__builtin_unreachable()" with "__assume(0)" for MSVC
- mscore/importgtp-gp6.cpp: conditionally replaced VLA.
- mscore/instrwidget.cpp: conditionally replaced VLA.
- mscore/jackaudio.cpp: conditionally replaced VLA. Preclude errors due to macro redefinitions.
- mscore/jackweakapi.cpp: Preclude errors due to macro redefinitions. Replacement for __atribute__((constructor)) through static object construction for MSVC. Force use of LoadLibraryA instead of LoadLibrary.
- mscore/mididriver.h: Changed not -> !
- mscore/musescore.cpp: Changed not -> !. Conditionally replaced VLA.
- mscore/resourceManager.cpp: conditionally replaced VLA.
- mscore/timeline.cpp: conditionally replaced VLA.
- omr/omrpage.cpp: conditionally replaced VLA.
- synthesizer/msynthesizer.cpp: replaced UNIX sleep(1) method with MSVC Sleep(1000) (equivalent, but in ms instead of seconds)
- synthesizer/msynthsizer.h: appended "f" to float constant
- thirdparty/poppler/config.h: set defines for MSVC to preclude the use of inexistent libraries.
- thirdparty/poppler/poppler/poppler-config.h: set defines for MSVC to preclude the use of inexistent libraries. Eliminated #defines for fmin and fmax which where causing problems.
- thirdparty/poppler/poppler/PSOutputDev.cc: added #include <algorithm> for std::min() and std::max(). Note this is required per-C++ standard.
- thirdparty/portmidi/pm_win/pmwinmm.c: undefined UNICODE to use char-based library functions.
- thirdparty/qzip/qzip.cpp: changed or -> ||
- thirdparty/rtf2html/rtf_keyword.h: file format changed from Apple to UNIX, as MSVC does not supported the former.
(NOT error related, just improvement on previous commit; manual/getopt/README.md: added link to source article)
2018-05-01 19:14:44 +02:00
|
|
|
#if (!defined (_MSCVER) && !defined (_MSC_VER))
|
2014-08-16 11:41:36 +02:00
|
|
|
int staffIdx[numOfStaffListItems];
|
Solved all compilation errors on MSVC
This commit contains changes required for MuseScore to compile under MSVC with no errors.
There are several general categories of problems that resulted in errors with the compilation. Main issues:
- Variable Length Arrays (VLA). This is a non-standard extension to C++, supported by clang toolchains, but not by MSVC. The initial workaround is to use std::vector<> instead of VLAs, eventually (if needed) with the original variable pointing to the beginning of the allocated array. More efficient alternatives are possible if profiling shows any code using VLAs to be timing-critical.
- Floating-point constants not suffixed with "f" are doubles by default; in some instances, this leads to narrowing conversion errors (in other instances, just warnings).
- MSVC does not support "or"/"and"/"not" in lieu of "||"/"&&"/"!". Changed unconditionally to use standard C++ symbols.
- MSVC does not support the "__builtin_unreachable()" compiler hint. A similar, albeit not exactly equal, alternative is "__assume(0)", which is MSVC-specific.
- MSVC does not support ranges in case statements. Replaced with list of cases instead of range (non-conditionally)
Detailed changes, with per-file comments:
- all.h: opt-in to deprecated features, include <io.h> and <process.h> instead of POSIX <unistd.h>, undefine "STRING_NONE" and "small", which Microsoft defines as macros, which result in compilation errors.
- effects/compressor/zita.cpp: eliminated narrowing conversion error by appending "f" to float constants.
- fluid/voice.cpp: appended "f" to float constants to eliminate narrowing conversion errors/warnings
- libmscore/beam.cpp: conditionally replaced VLA
- libmscore/edit.cpp: conditionally replaced VLA
- libmscore/element.cpp: appended "f" to float constant
- libmscore/fret.cpp: changed or -> ||
- libmscore/layout.cpp: conditionally replaced VLA
- libmscore/mscore.cpp: conditionally replaced "__builtin_unreachable()" with "__assume(0)" for MSVC
- libmscore/scorefile.coo: use correct char representation conversion for MSVC
- libmscore/stringdata.cpp: conditionally replaced VLA
- libmscore/system.cpp: conditionally replaced VLA
- libmscroe/text.cpp: replaced range in case statement.
- manual/genManual.cpp: use getopt() replacement.
- midi/midifile.cpp: conditionally replaced VLA. This does not use the default replacement.
- mscore/bb.cpp: replaced range in case statement.
- mscore/capella.cpp: conditionally replaced VLA. Changed and -> &&
- mscore/driver:cpp: preclude errors due to macro redefinitions.
- mscore/editstyle.cpp: conditionally replaced "__builtin_unreachable()" with "__assume(0)" for MSVC
- mscore/importgtp-gp6.cpp: conditionally replaced VLA.
- mscore/instrwidget.cpp: conditionally replaced VLA.
- mscore/jackaudio.cpp: conditionally replaced VLA. Preclude errors due to macro redefinitions.
- mscore/jackweakapi.cpp: Preclude errors due to macro redefinitions. Replacement for __atribute__((constructor)) through static object construction for MSVC. Force use of LoadLibraryA instead of LoadLibrary.
- mscore/mididriver.h: Changed not -> !
- mscore/musescore.cpp: Changed not -> !. Conditionally replaced VLA.
- mscore/resourceManager.cpp: conditionally replaced VLA.
- mscore/timeline.cpp: conditionally replaced VLA.
- omr/omrpage.cpp: conditionally replaced VLA.
- synthesizer/msynthesizer.cpp: replaced UNIX sleep(1) method with MSVC Sleep(1000) (equivalent, but in ms instead of seconds)
- synthesizer/msynthsizer.h: appended "f" to float constant
- thirdparty/poppler/config.h: set defines for MSVC to preclude the use of inexistent libraries.
- thirdparty/poppler/poppler/poppler-config.h: set defines for MSVC to preclude the use of inexistent libraries. Eliminated #defines for fmin and fmax which where causing problems.
- thirdparty/poppler/poppler/PSOutputDev.cc: added #include <algorithm> for std::min() and std::max(). Note this is required per-C++ standard.
- thirdparty/portmidi/pm_win/pmwinmm.c: undefined UNICODE to use char-based library functions.
- thirdparty/qzip/qzip.cpp: changed or -> ||
- thirdparty/rtf2html/rtf_keyword.h: file format changed from Apple to UNIX, as MSVC does not supported the former.
(NOT error related, just improvement on previous commit; manual/getopt/README.md: added link to source article)
2018-05-01 19:14:44 +02:00
|
|
|
#else
|
|
|
|
// MSVC does not support VLA. Replace with std::vector. If profiling determines that the
|
|
|
|
// heap allocation is slow, an optimization might be used.
|
|
|
|
std::vector<int> staffIdx(numOfStaffListItems);
|
|
|
|
#endif
|
2014-08-16 11:41:36 +02:00
|
|
|
int itemIdx;
|
|
|
|
for (itemIdx=0; itemIdx < numOfStaffListItems; ++itemIdx)
|
|
|
|
staffIdx[itemIdx] = (static_cast<StaffListItem*>(item->child(itemIdx)))->staffTypeIdx();
|
2015-02-16 12:05:00 +01:00
|
|
|
// do not consider hidden ones
|
|
|
|
int plusIdx = 1;
|
|
|
|
QTreeWidgetItem* nextParent = partiturList->topLevelItem(idx + plusIdx);
|
|
|
|
while (nextParent && nextParent->isHidden()) {
|
|
|
|
plusIdx++;
|
|
|
|
nextParent = partiturList->topLevelItem(idx + plusIdx);
|
|
|
|
}
|
|
|
|
partiturList->insertTopLevelItem(idx + plusIdx, item);
|
2014-08-16 11:41:36 +02:00
|
|
|
// after-re-insertion, recreate each combo and set its index
|
|
|
|
for (itemIdx=0; itemIdx < numOfStaffListItems; ++itemIdx) {
|
|
|
|
StaffListItem* staffItem = static_cast<StaffListItem*>(item->child(itemIdx));
|
|
|
|
staffItem->initStaffTypeCombo(true);
|
|
|
|
staffItem->setStaffType(staffIdx[itemIdx]);
|
|
|
|
}
|
|
|
|
partiturList->setItemExpanded(item, isExpanded);
|
|
|
|
partiturList->setItemSelected(item, true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
QTreeWidgetItem* parent = item->parent();
|
|
|
|
int idx = parent->indexOfChild(item);
|
|
|
|
int n = parent->childCount();
|
|
|
|
// if staff item is not last of its part, move one slot down in part
|
|
|
|
if (idx < (n-1)) {
|
|
|
|
partiturList->selectionModel()->clear();
|
|
|
|
StaffListItem* item = static_cast<StaffListItem*>(parent->takeChild(idx));
|
|
|
|
// Qt looses the QComboBox set into StaffListItem when it is re-inserted into the tree:
|
|
|
|
// get currently selected staff type and re-insert
|
|
|
|
int staffTypeIdx = item->staffTypeIdx();
|
|
|
|
parent->insertChild(idx+1, item);
|
|
|
|
// after item has been inserted into the tree, create a new QComboBox and set its index
|
|
|
|
item->initStaffTypeCombo(true);
|
|
|
|
item->setStaffType(staffTypeIdx);
|
|
|
|
partiturList->setItemSelected(item, true);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
// if staff item is last of its part...
|
|
|
|
int parentIdx = partiturList->indexOfTopLevelItem(parent);
|
|
|
|
int n = partiturList->topLevelItemCount();
|
|
|
|
//..and there is a next part, move to next part
|
|
|
|
if (parentIdx < (n-1)) {
|
|
|
|
partiturList->selectionModel()->clear();
|
|
|
|
StaffListItem* sli = static_cast<StaffListItem*>(parent->takeChild(idx));
|
|
|
|
QTreeWidgetItem* nextParent = partiturList->topLevelItem(parentIdx - 1);
|
|
|
|
int staffTypeIdx = sli->staffTypeIdx();
|
|
|
|
nextParent->addChild(sli);
|
|
|
|
sli->initStaffTypeCombo(true);
|
|
|
|
sli->setStaffType(staffTypeIdx);
|
|
|
|
partiturList->setItemSelected(sli, true);
|
|
|
|
// PartListItem* pli = static_cast<PartListItem*>(nextParent);
|
|
|
|
// cs->undo(new MoveStaff(sli->staff(), pli->part, 0));
|
|
|
|
//
|
|
|
|
// TODO : if staff was linked to a staff of the old parent part, unlink it!
|
|
|
|
//
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// on_belowButton_clicked
|
|
|
|
// (actually "Add Staff" button)
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
StaffListItem* InstrumentsWidget::on_belowButton_clicked()
|
|
|
|
{
|
|
|
|
QList<QTreeWidgetItem*> wi = partiturList->selectedItems();
|
|
|
|
if (wi.isEmpty())
|
|
|
|
return 0;
|
|
|
|
QTreeWidgetItem* item = wi.front();
|
|
|
|
if (item->type() != STAFF_LIST_ITEM)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
StaffListItem* sli = static_cast<StaffListItem*>(item);
|
2014-08-17 12:27:31 +02:00
|
|
|
// Staff* staff = sli->staff();
|
2014-08-16 11:41:36 +02:00
|
|
|
PartListItem* pli = static_cast<PartListItem*>(sli->QTreeWidgetItem::parent());
|
|
|
|
StaffListItem* nsli = new StaffListItem();
|
2014-08-16 18:52:16 +02:00
|
|
|
// nsli->setStaff(staff);
|
|
|
|
nsli->setStaff(0);
|
|
|
|
// if (staff)
|
2014-08-16 11:41:36 +02:00
|
|
|
nsli->setOp(ListItemOp::ADD);
|
2014-08-16 18:52:16 +02:00
|
|
|
int ridx = pli->indexOfChild(sli) + 1;
|
|
|
|
pli->insertChild(ridx, nsli);
|
2014-08-16 11:41:36 +02:00
|
|
|
nsli->initStaffTypeCombo(); // StaffListItem needs to be inserted in the tree hierarchy
|
|
|
|
nsli->setStaffType(sli->staffType()); // before a widget can be set into it
|
2014-08-16 18:52:16 +02:00
|
|
|
|
|
|
|
ClefTypeList clefType;
|
|
|
|
if (pli->it)
|
|
|
|
clefType = pli->it->clefType(ridx);
|
|
|
|
else
|
2015-03-13 11:16:43 +01:00
|
|
|
clefType = pli->part->instrument()->clefType(ridx);
|
2014-08-16 18:52:16 +02:00
|
|
|
nsli->setDefaultClefType(clefType);
|
|
|
|
pli->updateClefs();
|
|
|
|
|
2014-08-16 11:41:36 +02:00
|
|
|
partiturList->clearSelection(); // should not be necessary
|
|
|
|
partiturList->setItemSelected(nsli, true);
|
|
|
|
pli->updateClefs();
|
|
|
|
return nsli;
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// on_linkedButton_clicked
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void InstrumentsWidget::on_linkedButton_clicked()
|
|
|
|
{
|
|
|
|
StaffListItem* nsli = on_belowButton_clicked();
|
|
|
|
if (nsli)
|
|
|
|
nsli->setLinked(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// on_search_textChanged
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void InstrumentsWidget::on_search_textChanged(const QString &searchPhrase)
|
|
|
|
{
|
|
|
|
instrumentGenreFilter->blockSignals(true);
|
|
|
|
instrumentGenreFilter->setCurrentIndex(0);
|
|
|
|
instrumentGenreFilter->blockSignals(false);
|
2017-11-10 20:42:09 +01:00
|
|
|
filterInstruments(instrumentList, searchPhrase);
|
2014-08-16 11:41:36 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// on_instrumentGenreFilter_currentTextChanged
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void InstrumentsWidget::on_instrumentGenreFilter_currentIndexChanged(int index)
|
|
|
|
{
|
|
|
|
QString id = instrumentGenreFilter->itemData(index).toString();
|
|
|
|
// Redisplay tree, only showing items from the selected genre
|
|
|
|
filterInstrumentsByGenre(instrumentList, id);
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// filterInstrumentsByGenre
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void InstrumentsWidget::filterInstrumentsByGenre(QTreeWidget *instrumentList, QString genre)
|
|
|
|
{
|
|
|
|
QTreeWidgetItemIterator iList(instrumentList);
|
|
|
|
while (*iList) {
|
|
|
|
(*iList)->setHidden(true);
|
|
|
|
InstrumentTemplateListItem* itli = static_cast<InstrumentTemplateListItem*>(*iList);
|
|
|
|
InstrumentTemplate *it=itli->instrumentTemplate();
|
|
|
|
|
|
|
|
if(it) {
|
|
|
|
if (genre == "all" || it->genreMember(genre)) {
|
|
|
|
(*iList)->setHidden(false);
|
|
|
|
|
|
|
|
QTreeWidgetItem *iParent = (*iList)->parent();
|
|
|
|
while(iParent) {
|
|
|
|
if(!iParent->isHidden())
|
|
|
|
break;
|
|
|
|
|
|
|
|
iParent->setHidden(false);
|
|
|
|
iParent = iParent->parent();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
++iList;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// createInstruments
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void InstrumentsWidget::createInstruments(Score* cs)
|
|
|
|
{
|
|
|
|
//
|
|
|
|
// process modified partitur list
|
|
|
|
//
|
|
|
|
QTreeWidget* pl = partiturList;
|
|
|
|
Part* part = 0;
|
|
|
|
int staffIdx = 0;
|
|
|
|
|
|
|
|
QTreeWidgetItem* item = 0;
|
|
|
|
for (int idx = 0; (item = pl->topLevelItem(idx)); ++idx) {
|
|
|
|
PartListItem* pli = (PartListItem*)item;
|
|
|
|
if (pli->op != ListItemOp::ADD) {
|
|
|
|
qDebug("bad op");
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
const InstrumentTemplate* t = ((PartListItem*)item)->it;
|
|
|
|
part = new Part(cs);
|
|
|
|
part->initFromInstrTemplate(t);
|
|
|
|
|
|
|
|
pli->part = part;
|
|
|
|
QTreeWidgetItem* ci = 0;
|
|
|
|
int rstaff = 0;
|
|
|
|
for (int cidx = 0; (ci = pli->child(cidx)); ++cidx) {
|
|
|
|
if (ci->isHidden())
|
|
|
|
continue;
|
|
|
|
StaffListItem* sli = (StaffListItem*)ci;
|
2014-08-16 13:32:08 +02:00
|
|
|
Staff* staff = new Staff(cs);
|
|
|
|
staff->setPart(part);
|
2014-08-16 11:41:36 +02:00
|
|
|
sli->setStaff(staff);
|
|
|
|
++rstaff;
|
|
|
|
|
|
|
|
staff->init(t, sli->staffType(), cidx);
|
|
|
|
staff->setDefaultClefType(sli->defaultClefType());
|
|
|
|
|
|
|
|
if (sli->linked() && !part->staves()->isEmpty()) {
|
|
|
|
Staff* linkedStaff = part->staves()->back();
|
|
|
|
staff->linkTo(linkedStaff);
|
|
|
|
}
|
|
|
|
part->staves()->push_back(staff);
|
|
|
|
cs->staves().insert(staffIdx + rstaff, staff);
|
|
|
|
}
|
|
|
|
// if a staff was removed from instrument:
|
|
|
|
if (part->staff(0)->barLineSpan() > rstaff) {
|
2017-08-04 15:45:23 +02:00
|
|
|
//TODO part->staff(0)->setBarLineSpan(rstaff);
|
2017-03-31 13:03:15 +02:00
|
|
|
part->staff(0)->setBracketType(0, BracketType::NO_BRACKET);
|
2014-08-16 11:41:36 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// insert part
|
|
|
|
cs->insertPart(part, staffIdx);
|
|
|
|
int sidx = cs->staffIdx(part);
|
|
|
|
int eidx = sidx + part->nstaves();
|
|
|
|
for (Measure* m = cs->firstMeasure(); m; m = m->nextMeasure())
|
|
|
|
m->cmdAddStaves(sidx, eidx, true);
|
|
|
|
staffIdx += rstaff;
|
|
|
|
}
|
2017-08-04 15:45:23 +02:00
|
|
|
#if 0 // TODO
|
2014-08-16 11:41:36 +02:00
|
|
|
//
|
|
|
|
// check for bar lines
|
|
|
|
//
|
|
|
|
for (int staffIdx = 0; staffIdx < cs->nstaves();) {
|
|
|
|
Staff* staff = cs->staff(staffIdx);
|
|
|
|
int barLineSpan = staff->barLineSpan();
|
|
|
|
if (barLineSpan == 0)
|
|
|
|
staff->setBarLineSpan(1);
|
|
|
|
int nstaffIdx = staffIdx + barLineSpan;
|
|
|
|
|
|
|
|
for (int idx = staffIdx+1; idx < nstaffIdx; ++idx) {
|
|
|
|
Staff* tStaff = cs->staff(idx);
|
|
|
|
if (tStaff)
|
|
|
|
tStaff->setBarLineSpan(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
staffIdx = nstaffIdx;
|
|
|
|
}
|
2017-08-04 15:45:23 +02:00
|
|
|
#endif
|
2016-03-02 13:20:19 +01:00
|
|
|
cs->setLayoutAll();
|
2014-08-16 11:41:36 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// init
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void InstrumentsWidget::init()
|
|
|
|
{
|
|
|
|
partiturList->clear();
|
|
|
|
instrumentList->clearSelection();
|
|
|
|
addButton->setEnabled(false);
|
|
|
|
removeButton->setEnabled(false);
|
|
|
|
upButton->setEnabled(false);
|
|
|
|
downButton->setEnabled(false);
|
|
|
|
linkedButton->setEnabled(false);
|
|
|
|
belowButton->setEnabled(false);
|
|
|
|
emit completeChanged(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// getPartiturList
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
QTreeWidget* InstrumentsWidget::getPartiturList()
|
|
|
|
{
|
|
|
|
return partiturList;
|
|
|
|
}
|
|
|
|
}
|