From 9a36e5cfe13c0c789154850ffc1c65f20dc1e508 Mon Sep 17 00:00:00 2001 From: Thomas Goyne Date: Fri, 2 Nov 2012 21:06:37 -0700 Subject: [PATCH] Add a unique ID to dialogue lines This is needed to track lines across undo, as the previous method of using the row number was slow and broke on inserts/deletes. --- aegisub/src/ass_dialogue.cpp | 15 +++++++++++---- aegisub/src/ass_dialogue.h | 5 +++++ aegisub/src/command/edit.cpp | 2 +- aegisub/src/subtitle_format.cpp | 8 ++++---- 4 files changed, 21 insertions(+), 9 deletions(-) diff --git a/aegisub/src/ass_dialogue.cpp b/aegisub/src/ass_dialogue.cpp index e2c55b26e..380254223 100644 --- a/aegisub/src/ass_dialogue.cpp +++ b/aegisub/src/ass_dialogue.cpp @@ -49,12 +49,15 @@ using namespace boost::adaptors; +static int next_id = 0; + std::size_t hash_value(wxString const& s) { return wxStringHash()(s); } AssDialogue::AssDialogue() -: Comment(false) +: Id(++next_id) +, Comment(false) , Layer(0) , Start(0) , End(5000) @@ -64,7 +67,8 @@ AssDialogue::AssDialogue() } AssDialogue::AssDialogue(AssDialogue const& that) -: Comment(that.Comment) +: Id(++next_id) +, Comment(that.Comment) , Layer(that.Layer) , Start(that.Start) , End(that.End) @@ -77,7 +81,8 @@ AssDialogue::AssDialogue(AssDialogue const& that) } AssDialogue::AssDialogue(wxString const& data) -: Comment(false) +: Id(++next_id) +, Comment(false) , Layer(0) , Start(0) , End(5000) @@ -325,7 +330,9 @@ wxString AssDialogue::GetStrippedText() const { } AssEntry *AssDialogue::Clone() const { - return new AssDialogue(*this); + AssDialogue *clone = new AssDialogue(*this); + *const_cast(&clone->Id) = Id; + return clone; } void AssDialogueBlockDrawing::TransformCoords(int mx, int my, double x, double y) { diff --git a/aegisub/src/ass_dialogue.h b/aegisub/src/ass_dialogue.h index 33a8f97ca..51b0fcde1 100644 --- a/aegisub/src/ass_dialogue.h +++ b/aegisub/src/ass_dialogue.h @@ -127,6 +127,11 @@ public: class AssDialogue : public AssEntry { wxString GetData(bool ssa) const; public: + /// Unique ID of this line. Copies of the line for Undo/Redo purposes + /// preserve the unique ID, so that the equivalent lines can be found in + /// the different versions of the file. + const int Id; + /// Is this a comment line? bool Comment; /// Layer number diff --git a/aegisub/src/command/edit.cpp b/aegisub/src/command/edit.cpp index 267f6508f..4c9696b1f 100644 --- a/aegisub/src/command/edit.cpp +++ b/aegisub/src/command/edit.cpp @@ -585,7 +585,7 @@ static void duplicate_lines(agi::Context *c, bool shift) { // Duplicate each of the selected lines, inserting them in a block // after the selected block do { - AssDialogue *new_diag = static_cast(start->Clone()); + AssDialogue *new_diag = new AssDialogue(*static_cast(&*start)); c->ass->Line.insert(insert_pos, *new_diag); new_sel.insert(new_diag); diff --git a/aegisub/src/subtitle_format.cpp b/aegisub/src/subtitle_format.cpp index 34f8794c1..64821c48f 100644 --- a/aegisub/src/subtitle_format.cpp +++ b/aegisub/src/subtitle_format.cpp @@ -228,7 +228,7 @@ void SubtitleFormat::RecombineOverlaps(AssFile &file) { //Is there an A part before the overlap? if (curdlg->Start > prevdlg->Start) { // Produce new entry with correct values - AssDialogue *newdlg = static_cast(prevdlg->Clone()); + AssDialogue *newdlg = new AssDialogue(*prevdlg); newdlg->Start = prevdlg->Start; newdlg->End = curdlg->Start; newdlg->Text = prevdlg->Text; @@ -238,7 +238,7 @@ void SubtitleFormat::RecombineOverlaps(AssFile &file) { // Overlapping A+B part { - AssDialogue *newdlg = static_cast(prevdlg->Clone()); + AssDialogue *newdlg = new AssDialogue(*prevdlg); newdlg->Start = curdlg->Start; newdlg->End = (prevdlg->End < curdlg->End) ? prevdlg->End : curdlg->End; // Put an ASS format hard linewrap between lines @@ -250,7 +250,7 @@ void SubtitleFormat::RecombineOverlaps(AssFile &file) { // Is there an A part after the overlap? if (prevdlg->End > curdlg->End) { // Produce new entry with correct values - AssDialogue *newdlg = static_cast(prevdlg->Clone()); + AssDialogue *newdlg = new AssDialogue(*prevdlg); newdlg->Start = curdlg->End; newdlg->End = prevdlg->End; newdlg->Text = prevdlg->Text; @@ -261,7 +261,7 @@ void SubtitleFormat::RecombineOverlaps(AssFile &file) { // Is there a B part after the overlap? if (curdlg->End > prevdlg->End) { // Produce new entry with correct values - AssDialogue *newdlg = static_cast(prevdlg->Clone()); + AssDialogue *newdlg = new AssDialogue(*prevdlg); newdlg->Start = prevdlg->End; newdlg->End = curdlg->End; newdlg->Text = curdlg->Text;