1 //============================================================================= 2 // MuseScore 3 // Music Composition & Notation 4 // 5 // Copyright (C) 2018 Werner Schweer 6 // 7 // This program is free software; you can redistribute it and/or modify 8 // it under the terms of the GNU General Public License version 2 9 // as published by the Free Software Foundation and appearing in 10 // the file LICENCE.GPL 11 //============================================================================= 12 13 #ifndef __SCOREDIFF_H__ 14 #define __SCOREDIFF_H__ 15 16 #include "score.h" 17 18 #include <vector> 19 20 namespace Ms { 21 22 enum class Pid; 23 class ScoreElement; 24 25 //--------------------------------------------------------- 26 // ItemType 27 //--------------------------------------------------------- 28 29 enum class ItemType { 30 ELEMENT, 31 PROPERTY, 32 MARKUP, 33 CONTEXTCHANGE 34 }; 35 36 //--------------------------------------------------------- 37 // DiffType 38 //--------------------------------------------------------- 39 #undef DELETE 40 enum class DiffType { 41 EQUAL, 42 INSERT, 43 DELETE, 44 REPLACE 45 }; 46 47 //--------------------------------------------------------- 48 // TextDiff 49 // A structure similar to Diff from diff_match_patch 50 // but contains info on line numbers of the diff 51 //--------------------------------------------------------- 52 53 struct TextDiff { 54 DiffType type; 55 QString text[2]; 56 int start[2]; // starting line numbers in both texts 57 int end[2]; // ending line numbers in both texts 58 59 bool merge(const TextDiff& other); // merge other diff into this one 60 QString toString(DiffType type, bool prefixLines = false) const; 61 QString toString(bool prefixLines = false) const { return toString(type, prefixLines); } 62 }; 63 64 //--------------------------------------------------------- 65 // BaseDiff 66 //--------------------------------------------------------- 67 68 struct BaseDiff { 69 DiffType type; 70 const TextDiff* textDiff; 71 const ScoreElement* ctx[2]; 72 const ScoreElement* before[2]; 73 74 virtual ~BaseDiff() = default; 75 76 virtual ItemType itemType() const = 0; 77 virtual bool sameItem(const BaseDiff&) const; 78 virtual Fraction afrac(int score) const; 79 virtual QString toString() const = 0; 80 }; 81 82 //--------------------------------------------------------- 83 // ContextChange 84 // Dummy Diff for temporary storing information on 85 // context changes. 86 //--------------------------------------------------------- 87 88 struct ContextChange : public BaseDiff { itemTypeContextChange89 ItemType itemType() const override { return ItemType::CONTEXTCHANGE; } 90 QString toString() const override; 91 }; 92 93 //--------------------------------------------------------- 94 // ElementDiff 95 //--------------------------------------------------------- 96 97 struct ElementDiff : public BaseDiff { 98 const ScoreElement* el[2]; 99 itemTypeElementDiff100 ItemType itemType() const override { return ItemType::ELEMENT; } 101 bool sameItem(const BaseDiff&) const override; 102 Fraction afrac(int score) const override; 103 QString toString() const override; 104 }; 105 106 //--------------------------------------------------------- 107 // PropertyDiff 108 //--------------------------------------------------------- 109 110 struct PropertyDiff : public BaseDiff { 111 Pid pid; 112 itemTypePropertyDiff113 ItemType itemType() const override { return ItemType::PROPERTY; } 114 bool sameItem(const BaseDiff&) const override; 115 QString toString() const override; 116 }; 117 118 //--------------------------------------------------------- 119 // MarkupDiff 120 //--------------------------------------------------------- 121 122 struct MarkupDiff : public BaseDiff { 123 QString name; 124 QVariant info; 125 itemTypeMarkupDiff126 ItemType itemType() const override { return ItemType::MARKUP; } 127 bool sameItem(const BaseDiff&) const override; 128 QString toString() const override; 129 }; 130 131 //--------------------------------------------------------- 132 // ScoreDiff 133 //--------------------------------------------------------- 134 135 class ScoreDiff { 136 std::vector<TextDiff> _textDiffs; // raw diff between MSCX code for scores 137 std::vector<const TextDiff*> _mergedTextDiffs; // extra diff items created after merging score diff items 138 std::vector<BaseDiff*> _diffs; 139 Score* _s1; 140 Score* _s2; 141 ScoreContentState _scoreState1; 142 ScoreContentState _scoreState2; 143 144 bool _textDiffOnly; 145 146 void processMarkupDiffs(); 147 void mergeInsertDeleteDiffs(); 148 void mergeElementDiffs(); 149 void editPropertyDiffs(); 150 151 public: 152 ScoreDiff(Score* s1, Score* s2, bool textDiffOnly = false); 153 ScoreDiff(const ScoreDiff&) = delete; 154 ~ScoreDiff(); 155 156 void update(); updated()157 bool updated() const { return _scoreState1 == _s1->state() && _scoreState2 == _s2->state(); } 158 diffs()159 std::vector<BaseDiff*>& diffs() { return _diffs; } textDiffs()160 const std::vector<TextDiff>& textDiffs() const { return _textDiffs; } 161 score1()162 const Score* score1() const { return _s1; } score2()163 const Score* score2() const { return _s2; } 164 165 bool equal() const; 166 167 QString rawDiff(bool skipEqual = true) const; 168 QString userDiff() const; 169 }; 170 171 } // namespace Ms 172 #endif 173