Skip to content

Commit

Permalink
Fix #20615:
Browse files Browse the repository at this point in the history
In the New Score wizard and in the Instruments dlg box, the "Staff Type" combo is lost when staves or parts are moved up or down.
  • Loading branch information
Maurizio M. Gavioli committed Mar 30, 2013
1 parent 15c1263 commit 6d0634e
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 16 deletions.
2 changes: 1 addition & 1 deletion libmscore/staff.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -755,7 +755,7 @@ void Staff::init(const InstrumentTemplate* t, const StaffType* staffType, int ci

// use selected staff type
setStaffType(st);
if (t->staffGroup != TAB_STAFF) // if not TAB (where num of staff lines is determined by TAB style)
if (st->group() != TAB_STAFF) // if not TAB (where num of staff lines is determined by TAB style)
setLines(t->staffLines[cidx]); // use number of lines from instr. template
}

Expand Down
82 changes: 70 additions & 12 deletions mscore/instrdialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,18 @@ StaffListItem::StaffListItem()
// initStaffTypeCombo(); // no! can't set widgets into this, until this is inserted in the tree hierarchy
}

void StaffListItem::initStaffTypeCombo()
void StaffListItem::initStaffTypeCombo(bool forceRecreate)
{
if (_staffTypeCombo) // do not init more than once
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

_staffTypeCombo = new QComboBox();
_staffTypeCombo->setAutoFillBackground(true);
foreach (STAFF_LIST_STAFF_TYPE staffTypeData, staffTypeList)
Expand Down Expand Up @@ -563,33 +571,58 @@ void InstrumentsDialog::on_upButton_clicked()
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();
int staffIdx[numOfStaffListItems];
int itemIdx;
for (itemIdx=0; itemIdx < numOfStaffListItems; ++itemIdx)
staffIdx[itemIdx] = (static_cast<StaffListItem*>(item->child(itemIdx)))->staffTypeIdx();
partiturList->insertTopLevelItem(idx-1, item);
// 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);
// if staff item not first of its part, move one slot up
if (idx) {
partiturList->selectionModel()->clear();
QTreeWidgetItem* item = parent->takeChild(idx);
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 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* item = parent->takeChild(idx);
QTreeWidgetItem* prevParent = partiturList->topLevelItem(parentIdx - 1);
prevParent->addChild(item);
partiturList->setItemSelected(item, true);
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);
StaffListItem* sli = static_cast<StaffListItem*>(item);
int idx = pli->part->nstaves();
cs->undo(new MoveStaff(sli->staff, pli->part, idx));
}
Expand All @@ -612,10 +645,24 @@ void InstrumentsDialog::on_downButton_clicked()
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();
int staffIdx[numOfStaffListItems];
int itemIdx;
for (itemIdx=0; itemIdx < numOfStaffListItems; ++itemIdx)
staffIdx[itemIdx] = (static_cast<StaffListItem*>(item->child(itemIdx)))->staffTypeIdx();
partiturList->insertTopLevelItem(idx+1, item);
// 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);
}
Expand All @@ -624,23 +671,34 @@ void InstrumentsDialog::on_downButton_clicked()
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();
QTreeWidgetItem* item = parent->takeChild(idx);
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();
QTreeWidgetItem* item = parent->takeChild(idx);
StaffListItem* sli = static_cast<StaffListItem*>(parent->takeChild(idx));
QTreeWidgetItem* nextParent = partiturList->topLevelItem(parentIdx - 1);
nextParent->addChild(item);
partiturList->setItemSelected(item, true);
int staffTypeIdx = sli->staffTypeIdx();
nextParent->addChild(sli);
sli->initStaffTypeCombo(true);
sli->setStaffType(staffTypeIdx);
partiturList->setItemSelected(sli, true);
PartListItem* pli = static_cast<PartListItem*>(nextParent);
StaffListItem* sli = static_cast<StaffListItem*>(item);
cs->undo(new MoveStaff(sli->staff, pli->part, 0));
}
}
Expand Down
2 changes: 1 addition & 1 deletion mscore/instrdialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ class StaffListItem : public QObject, public QTreeWidgetItem {
void setStaffType(int staffTypeIdx);
const StaffType* staffType() const;
int staffTypeIdx() const;
void initStaffTypeCombo();
void initStaffTypeCombo(bool forceRecreate = false);

static void populateStaffTypes(Score * score);

Expand Down
42 changes: 40 additions & 2 deletions mscore/newwizard.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,20 @@ void InstrumentWizard::on_upButton_clicked()
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();
int staffIdx[numOfStaffListItems];
int itemIdx;
for (itemIdx=0; itemIdx < numOfStaffListItems; ++itemIdx)
staffIdx[itemIdx] = (static_cast<StaffListItem*>(item->child(itemIdx)))->staffTypeIdx();
partiturList->insertTopLevelItem(idx-1, item);
// 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);
}
Expand All @@ -279,8 +292,14 @@ void InstrumentWizard::on_upButton_clicked()
int idx = parent->indexOfChild(item);
if (idx) {
partiturList->selectionModel()->clear();
QTreeWidgetItem* item = parent->takeChild(idx);
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);
}
}
Expand All @@ -304,7 +323,20 @@ void InstrumentWizard::on_downButton_clicked()
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();
int staffIdx[numOfStaffListItems];
int itemIdx;
for (itemIdx=0; itemIdx < numOfStaffListItems; ++itemIdx)
staffIdx[itemIdx] = (static_cast<StaffListItem*>(item->child(itemIdx)))->staffTypeIdx();
partiturList->insertTopLevelItem(idx+1, item);
// 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);
}
Expand All @@ -315,8 +347,14 @@ void InstrumentWizard::on_downButton_clicked()
int n = parent->childCount();
if (idx < (n-1)) {
partiturList->selectionModel()->clear();
QTreeWidgetItem* item = parent->takeChild(idx);
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);
}
}
Expand Down

0 comments on commit 6d0634e

Please sign in to comment.