Skip to content

Commit

Permalink
Merge pull request #2315 from vgstef/partsOrder
Browse files Browse the repository at this point in the history
Fix #89791 - Reordering parts and undo actions
  • Loading branch information
lasconic committed Jan 13, 2016
2 parents aefa798 + 65be66e commit ac4819d
Show file tree
Hide file tree
Showing 6 changed files with 153 additions and 21 deletions.
15 changes: 15 additions & 0 deletions libmscore/excerpt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,21 @@ bool Excerpt::operator!=(const Excerpt& e) const
return false;
}

//---------------------------------------------------------
// operator==
//---------------------------------------------------------

bool Excerpt::operator==(const Excerpt& e) const
{
if (e._oscore != _oscore)
return false;
if (e._title != _title)
return false;
if (e._parts != _parts)
return false;
return true;
}

//---------------------------------------------------------
// localSetScore
//---------------------------------------------------------
Expand Down
2 changes: 2 additions & 0 deletions libmscore/excerpt.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ class Excerpt : public QObject {
void read(XmlReader&);

bool operator!=(const Excerpt&) const;
bool operator==(const Excerpt&) const;

QString title() const { return _title; }
void setTitle(const QString& s) { _title = s; }

Expand Down
20 changes: 20 additions & 0 deletions libmscore/undo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3136,6 +3136,26 @@ void RemoveExcerpt::redo()
score->parentScore()->setExcerptsChanged(true);
}

//---------------------------------------------------------
// SwapExcerpt::undo()
//---------------------------------------------------------

void SwapExcerpt::undo()
{
score->excerpts().swap(pos2, pos1);
score->setExcerptsChanged(true);
}

//---------------------------------------------------------
// SwapExcerpt::redo()
//---------------------------------------------------------

void SwapExcerpt::redo()
{
score->excerpts().swap(pos1, pos2);
score->setExcerptsChanged(true);
}

//---------------------------------------------------------
// flip
//---------------------------------------------------------
Expand Down
16 changes: 16 additions & 0 deletions libmscore/undo.h
Original file line number Diff line number Diff line change
Expand Up @@ -925,6 +925,22 @@ class RemoveExcerpt : public UndoCommand {
UNDO_NAME("RemoveExcerpt")
};

//---------------------------------------------------------
// SwapExcerpt
//---------------------------------------------------------

class SwapExcerpt : public UndoCommand {
Score* score;
int pos1;
int pos2;

public:
SwapExcerpt(Score* s, int p1, int p2) : score(s), pos1(p1), pos2(p2) {}
virtual void undo();
virtual void redo();
UNDO_NAME("SwapExcerpt")
};

//---------------------------------------------------------
// ChangeBend
//---------------------------------------------------------
Expand Down
120 changes: 99 additions & 21 deletions mscore/excerptsdialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,15 +138,9 @@ void ExcerptsDialog::deleteClicked()
QListWidgetItem* cur = excerptList->currentItem();
if (cur == 0)
return;
Excerpt* ex = static_cast<ExcerptItem*>(cur)->excerpt();

if (ex->partScore()) {
score->startCmd();
score->undo(new RemoveExcerpt(ex->partScore()));
score->endCmd();
}
int row = excerptList->row(cur);
excerptList->takeItem(row);
delete cur;
//excerptList->takeItem(row);
}

//---------------------------------------------------------
Expand Down Expand Up @@ -212,10 +206,6 @@ void ExcerptsDialog::moveUpClicked()
QListWidgetItem* currentItem = excerptList->takeItem(currentRow);
excerptList->insertItem(currentRow - 1, currentItem);
excerptList->setCurrentRow(currentRow - 1);

if (currentRow < score->excerpts().size())
score->excerpts().swap(currentRow, currentRow-1);
score->setExcerptsChanged(true);
}

//---------------------------------------------------------
Expand All @@ -234,10 +224,6 @@ void ExcerptsDialog::moveDownClicked()
QListWidgetItem* currentItem = excerptList->takeItem(currentRow);
excerptList->insertItem(currentRow + 1, currentItem);
excerptList->setCurrentRow(currentRow + 1);

if (currentRow + 1 < score->excerpts().size())
score->excerpts().swap(currentRow, currentRow+1);
score->setExcerptsChanged(true);
}

//---------------------------------------------------------
Expand Down Expand Up @@ -333,20 +319,17 @@ void ExcerptsDialog::createExcerptClicked(QListWidgetItem* cur)

nscore->setName(e->title()); // needed before AddExcerpt

score->startCmd();
qDebug() << " + Add part : " << e->title();
score->undo(new AddExcerpt(nscore));
createExcerpt(e);
score->endCmd();

// a new excerpt is created in AddExcerpt, make sure the parts are filed
for (Excerpt* ee : e->oscore()->excerpts()) {
if (ee->partScore() == nscore) {
ee->parts().clear();
ee->parts().append(e->parts());
}
}
// the excerpt is not useful anymore,
// we created a new one in AddExcerpt
delete e;

partList->setEnabled(false);
title->setEnabled(false);
Expand All @@ -366,20 +349,115 @@ void ExcerptsDialog::titleChanged(const QString& s)
cur->setText(s);
}

//---------------------------------------------------------
// titleChanged
//---------------------------------------------------------

bool ExcerptsDialog::isInPartsList(Excerpt* e)
{
int n = excerptList->count();
for (int i = 0; i < n; ++i) {
excerptList->setCurrentRow(i);
QListWidgetItem* cur = excerptList->currentItem();
if (cur == 0)
continue;
if (((ExcerptItem*)cur)->excerpt() == ExcerptItem(e).excerpt())
return true;
//qDebug() << "#" << i << "¸-> " << (((ExcerptItem*)cur)->excerpt())->title();
}
return false;
}

//---------------------------------------------------------
// accept
//---------------------------------------------------------

void ExcerptsDialog::accept()
{
score->startCmd();

// first pass : see if actual parts needs to be deleted
qDebug() << "\nFirst pass : delete unwanted parts";

int pos = 0;
foreach(Excerpt* e, score->excerpts()) {
if (!isInPartsList(e)) {
// Delete it because not in the list anymore
if (e->partScore()) {
qDebug() << " - Deleting parts : " << ExcerptItem(e).excerpt()->title();

// Swap Excerpts to the end before deleting, so if undoing, the part will be reordered
int lastPos = score->excerpts().size()-1;
if ((lastPos > 0) && (pos != lastPos))
score->undo(new SwapExcerpt(score, pos, lastPos));

score->undo(new RemoveExcerpt(e->partScore()));
}
}
else
pos++;
}

// Second pass : Create new parts
qDebug() << "\nSecond pass : create new parts";
int n = excerptList->count();
for (int i = 0; i < n; ++i) {
excerptList->setCurrentRow(i);
QListWidgetItem* cur = excerptList->currentItem();
if (cur == 0)
continue;

createExcerptClicked(cur);
}

// Third pass : Remove empty parts.
int i = 0;
while (i < excerptList->count()) {
// This new part is empty, so we don't create an excerpt but remove it from the list.
// Necessary to order the parts later on.
excerptList->setCurrentRow(i);
QListWidgetItem* cur = excerptList->currentItem();
Excerpt* e = static_cast<ExcerptItem*>(cur)->excerpt();
if (e->parts().isEmpty() && !e->partScore()) {
qDebug() << " - Deleting empty parts : " << cur->text();
delete cur;
}
else
i++;
}

// Update the score parts order following excerpList widget
qDebug () << "\nFourth pass : Reordering parts";
qDebug () << " Nb parts in score->excerpts().size() = " << score->excerpts().size();
qDebug () << " Nb parts in the parts dialog : excerptList->count() = " << excerptList->count();

// The reference is the excerpt list. So we iterate following it and swap parts in the score accordingly
for (int i = 0; i < excerptList->count(); ++i) {
excerptList->setCurrentRow(i);
QListWidgetItem* cur = excerptList->currentItem();
if (cur == 0)
continue;

int position = 0; // Actual order position in score
bool found = false;

// Looks for the excerpt and its position.
foreach(Excerpt* e, score->excerpts()) {
if (((ExcerptItem*)cur)->excerpt() == ExcerptItem(e).excerpt()) {
found = true;
break;
}
position++;
}
if ((found) && (position != i)) {
qDebug() << " i=" << i << " <-> position=" << position;
score->undo(new SwapExcerpt(score, i, position));
}
}

score->endCmd();
score->setExcerptsChanged(true);

QDialog::accept();
}
}
Expand Down
1 change: 1 addition & 0 deletions mscore/excerptsdialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ class ExcerptsDialog : public QDialog, private Ui::ExcerptsDialog {
void partClicked(QListWidgetItem*);
void createExcerptClicked(QListWidgetItem*);
void titleChanged(const QString&);
bool isInPartsList(Excerpt* e);

public:
ExcerptsDialog(Score*, QWidget* parent = 0);
Expand Down

0 comments on commit ac4819d

Please sign in to comment.