Skip to content

Commit 2c62da6

Browse files
authored
Merge pull request #29569 from Eism/fret_box_hide_elements_fix_4.6
fixed #29264: Crash around undo deleted Fretboard diagram in FDL. 4.6
2 parents c892561 + 5853d98 commit 2c62da6

10 files changed

Lines changed: 72 additions & 90 deletions

File tree

src/engraving/dom/box.cpp

Lines changed: 26 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -710,14 +710,18 @@ FBox::FBox(System* parent)
710710

711711
void FBox::init()
712712
{
713-
std::vector<FretDiagram*> newDiagrams;
714-
StringList newDiagramsNames;
713+
LOGDA() << "============= init";
715714

716715
StringList oldDiagramsNames;
716+
std::vector<FretDiagram*> oldDiagrams;
717717
for (EngravingItem* element : el()) {
718-
oldDiagramsNames.push_back(toFretDiagram(element)->harmonyText().toLower());
718+
FretDiagram* diagram = toFretDiagram(element);
719+
oldDiagrams.push_back(diagram);
720+
oldDiagramsNames.push_back(diagram->harmonyText().toLower());
719721
}
720722

723+
StringList diagramsNamesInScore;
724+
std::vector<EngravingItem*> harmonyOrDiagramsInScore;
721725
for (mu::engraving::Segment* segment = masterScore()->firstSegment(mu::engraving::SegmentType::ChordRest); segment;
722726
segment = segment->next1(mu::engraving::SegmentType::ChordRest)) {
723727
for (EngravingItem* item : segment->annotations()) {
@@ -729,35 +733,36 @@ void FBox::init()
729733
continue;
730734
}
731735

732-
FretDiagram* fretDiagram = FretDiagram::makeFromHarmonyOrFretDiagram(item);
733-
if (!fretDiagram) {
736+
if (!(item->isHarmony() || item->isFretDiagram())) {
734737
continue;
735738
}
736739

737-
String harmonyName = fretDiagram->harmonyText().toLower();
738-
if (muse::contains(newDiagramsNames, harmonyName) || harmonyName.empty()) {
739-
delete fretDiagram;
740+
String harmonyName = item->isHarmony() ? toHarmony(item)->plainText().toLower()
741+
: item->isFretDiagram() ? toFretDiagram(item)->harmonyText().toLower()
742+
: String();
743+
if (harmonyName.empty() || muse::contains(diagramsNamesInScore, harmonyName)) {
740744
continue;
741745
}
742746

743-
newDiagrams.emplace_back(fretDiagram);
744-
newDiagramsNames.push_back(harmonyName);
747+
harmonyOrDiagramsInScore.push_back(item);
748+
diagramsNamesInScore.push_back(harmonyName);
745749
}
746750
}
747751

748-
if (newDiagramsNames == oldDiagramsNames) {
749-
muse::DeleteAll(newDiagrams);
750-
return;
752+
for (size_t i = 0; i < oldDiagramsNames.size(); ++i) {
753+
String oldName = oldDiagramsNames[i];
754+
if (!muse::contains(diagramsNamesInScore, oldName)) {
755+
score()->undoRemoveElement(oldDiagrams[i]);
756+
}
751757
}
752758

753-
DEFER {
754-
triggerLayout();
755-
};
756-
757-
clearElements();
758-
759-
for (FretDiagram* diagram : newDiagrams) {
760-
add(diagram);
759+
for (size_t i = 0; i < diagramsNamesInScore.size(); ++i) {
760+
String newName = diagramsNamesInScore[i];
761+
if (!muse::contains(oldDiagramsNames, newName)) {
762+
FretDiagram* newDiagram = FretDiagram::makeFromHarmonyOrFretDiagram(harmonyOrDiagramsInScore[i]);
763+
newDiagram->setParent(this);
764+
score()->undoAddElement(newDiagram);
765+
}
761766
}
762767

763768
if (m_diagramsOrder.empty()) {

src/engraving/dom/box.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,13 +211,18 @@ class FBox : public VBox
211211

212212
ElementList orderedElements() const;
213213

214+
bool needsRebuild() const { return m_needsRebuild; }
215+
void setNeedsRebuild(bool v) { m_needsRebuild = v; }
216+
214217
private:
215218
double m_textScale = 0.0;
216219
double m_diagramScale = 0.0;
217220
Spatium m_columnGap;
218221
Spatium m_rowGap;
219222
int m_chordsPerRow = 0;
220223

224+
bool m_needsRebuild = false;
225+
221226
AlignH m_contentAlignmentH = AlignH::HCENTER;
222227

223228
StringList /*harmonyNames*/ m_diagramsOrder;

src/engraving/dom/edit.cpp

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7057,10 +7057,6 @@ void Score::undoAddElement(EngravingItem* element, bool addToLinkedStaves, bool
70577057
}
70587058
}
70597059
}
7060-
7061-
if (element->isHarmony() || element->isFretDiagram()) {
7062-
element->score()->rebuildFretBox();
7063-
}
70647060
} else if (element->isSlur()
70657061
|| element->isHairpin()
70667062
|| element->isOttava()
@@ -7449,16 +7445,8 @@ void Score::rebuildFretBox()
74497445
return;
74507446
}
74517447

7452-
fretBox->init();
7453-
7454-
for (EngravingObject* linkedObject : fretBox->linkList()) {
7455-
if (!linkedObject || !linkedObject->isFBox() || linkedObject == fretBox) {
7456-
continue;
7457-
}
7458-
7459-
FBox* box = toFBox(linkedObject);
7460-
box->init();
7461-
}
7448+
fretBox->setNeedsRebuild(true);
7449+
fretBox->triggerLayout();
74627450
}
74637451

74647452
//---------------------------------------------------------
@@ -7573,10 +7561,6 @@ void Score::undoRemoveElement(EngravingItem* element, bool removeLinked)
75737561
if (e->explicitParent() && e->explicitParent()->isSystem()) {
75747562
e->setParent(0); // systems will be regenerated upon redo, so detach
75757563
}
7576-
7577-
if (e->isHarmony() || e->isFretDiagram()) {
7578-
e->score()->rebuildFretBox();
7579-
}
75807564
}
75817565
}
75827566

src/engraving/dom/fret.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -831,6 +831,11 @@ void FretDiagram::clear()
831831
m_fretOffset = 0;
832832
}
833833

834+
bool FretDiagram::isClear() const
835+
{
836+
return m_barres.empty() && m_dots.empty() && m_markers.empty();
837+
}
838+
834839
//---------------------------------------------------------
835840
// undoFretClear
836841
//---------------------------------------------------------
@@ -965,8 +970,6 @@ void FretDiagram::unlinkHarmony()
965970

966971
segment()->add(m_harmony);
967972

968-
score()->rebuildFretBox();
969-
970973
m_harmony = nullptr;
971974
}
972975

@@ -1336,6 +1339,7 @@ FretDiagram* FretDiagram::makeFromHarmonyOrFretDiagram(const EngravingItem* harm
13361339
fretDiagram = toFretDiagram(harmonyOrFretDiagram->parentItem())->clone();
13371340
} else if (harmonyOrFretDiagram->isFretDiagram()) {
13381341
fretDiagram = toFretDiagram(harmonyOrFretDiagram)->clone();
1342+
fretDiagram->setOffset(PointF());
13391343
if (!fretDiagram->harmony()) {
13401344
//! generate from diagram and add harmony
13411345
fretDiagram->add(Factory::createHarmony(harmonyOrFretDiagram->score()->dummy()->segment()));

src/engraving/dom/fret.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,10 @@ class FretDiagram final : public EngravingItem
186186
void setBarre(int string, int fret, bool add = false);
187187
void setMarker(int string, FretMarkerType marker);
188188
/*void setFingering(int string, int finger);*/
189+
189190
void clear();
191+
bool isClear() const;
192+
190193
void undoSetFretDot(int _string, int _fret, bool _add = false, FretDotType _dtype = FretDotType::NORMAL);
191194
void undoSetFretMarker(int _string, FretMarkerType _mtype);
192195
void undoSetFretBarre(int _string, int _fret, bool _add = false);

src/engraving/dom/score.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1591,7 +1591,9 @@ void Score::addElement(EngravingItem* element)
15911591
}
15921592
case ElementType::HARMONY:
15931593
case ElementType::FRET_DIAGRAM:
1594-
element->part()->updateHarmonyChannels(true);
1594+
if (element->part()) {
1595+
element->part()->updateHarmonyChannels(true);
1596+
}
15951597
break;
15961598
case ElementType::GUITAR_BEND:
15971599
{
@@ -1790,7 +1792,9 @@ void Score::removeElement(EngravingItem* element)
17901792

17911793
case ElementType::HARMONY:
17921794
case ElementType::FRET_DIAGRAM:
1793-
element->part()->updateHarmonyChannels(true, true);
1795+
if (element->part()) {
1796+
element->part()->updateHarmonyChannels(true, true);
1797+
}
17941798
break;
17951799

17961800
default:

src/engraving/dom/segment.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -733,12 +733,14 @@ void Segment::add(EngravingItem* el)
733733
setEmpty(false);
734734
break;
735735

736+
case ElementType::HARMONY:
737+
case ElementType::FRET_DIAGRAM:
738+
score()->rebuildFretBox();
739+
//fallthrough
736740
case ElementType::TEMPO_TEXT:
737741
case ElementType::DYNAMIC:
738742
case ElementType::EXPRESSION:
739-
case ElementType::HARMONY:
740743
case ElementType::SYMBOL:
741-
case ElementType::FRET_DIAGRAM:
742744
case ElementType::STAFF_TEXT:
743745
case ElementType::SYSTEM_TEXT:
744746
case ElementType::TRIPLET_FEEL:
@@ -925,11 +927,13 @@ void Segment::remove(EngravingItem* el)
925927
m_elist[track] = 0;
926928
break;
927929

930+
case ElementType::HARMONY:
931+
case ElementType::FRET_DIAGRAM:
932+
score()->rebuildFretBox();
933+
//fallthrough
928934
case ElementType::DYNAMIC:
929935
case ElementType::EXPRESSION:
930936
case ElementType::FIGURED_BASS:
931-
case ElementType::FRET_DIAGRAM:
932-
case ElementType::HARMONY:
933937
case ElementType::IMAGE:
934938
case ElementType::MARKER:
935939
case ElementType::REHEARSAL_MARK:

src/engraving/dom/undo.cpp

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -976,14 +976,6 @@ void AddElement::undo(EditData*)
976976
updateStaffTextCache(toStaffTextBase(element), score);
977977
}
978978

979-
if (element->isHarmony() && !toHarmony(element)->isInFretBox()) {
980-
score->rebuildFretBox();
981-
}
982-
983-
if (element->isFretDiagram() && !toFretDiagram(element)->isInFretBox()) {
984-
score->rebuildFretBox();
985-
}
986-
987979
endUndoRedo(true);
988980
}
989981

@@ -1003,14 +995,6 @@ void AddElement::redo(EditData*)
1003995
updateStaffTextCache(toStaffTextBase(element), score);
1004996
}
1005997

1006-
if (element->isHarmony() && !toHarmony(element)->isInFretBox()) {
1007-
score->rebuildFretBox();
1008-
}
1009-
1010-
if (element->isFretDiagram() && !toFretDiagram(element)->isInFretBox()) {
1011-
score->rebuildFretBox();
1012-
}
1013-
1014998
endUndoRedo(false);
1015999
}
10161000

@@ -1165,14 +1149,6 @@ void RemoveElement::undo(EditData*)
11651149
} else if (element->isKeySig()) {
11661150
score->setLayout(element->staff()->nextKeyTick(element->tick()), element->staffIdx());
11671151
}
1168-
1169-
if (element->isHarmony() && !toHarmony(element)->isInFretBox()) {
1170-
score->rebuildFretBox();
1171-
}
1172-
1173-
if (element->isFretDiagram() && !toFretDiagram(element)->isInFretBox()) {
1174-
score->rebuildFretBox();
1175-
}
11761152
}
11771153

11781154
//---------------------------------------------------------
@@ -1202,14 +1178,6 @@ void RemoveElement::redo(EditData*)
12021178
} else if (element->isKeySig()) {
12031179
score->setLayout(element->staff()->nextKeyTick(element->tick()), element->staffIdx());
12041180
}
1205-
1206-
if (element->isHarmony() && !toHarmony(element)->isInFretBox()) {
1207-
score->rebuildFretBox();
1208-
}
1209-
1210-
if (element->isFretDiagram() && !toFretDiagram(element)->isInFretBox()) {
1211-
score->rebuildFretBox();
1212-
}
12131181
}
12141182

12151183
//---------------------------------------------------------

src/engraving/rendering/score/tlayout.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1486,6 +1486,11 @@ void TLayout::layoutFBox(const FBox* item, FBox::LayoutData* ldata, const Layout
14861486
{
14871487
LAYOUT_CALL_ITEM(item);
14881488

1489+
if (item->needsRebuild()) {
1490+
const_cast<FBox*>(item)->init();
1491+
const_cast<FBox*>(item)->setNeedsRebuild(false);
1492+
}
1493+
14891494
const System* parentSystem = item->system();
14901495
LD_CONDITION(parentSystem->ldata()->isSetBbox());
14911496

0 commit comments

Comments
 (0)