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.
This commit is contained in:
Thomas Goyne 2012-11-02 21:06:37 -07:00
parent 0e7df15170
commit 9a36e5cfe1
4 changed files with 21 additions and 9 deletions

View File

@ -49,12 +49,15 @@
using namespace boost::adaptors; using namespace boost::adaptors;
static int next_id = 0;
std::size_t hash_value(wxString const& s) { std::size_t hash_value(wxString const& s) {
return wxStringHash()(s); return wxStringHash()(s);
} }
AssDialogue::AssDialogue() AssDialogue::AssDialogue()
: Comment(false) : Id(++next_id)
, Comment(false)
, Layer(0) , Layer(0)
, Start(0) , Start(0)
, End(5000) , End(5000)
@ -64,7 +67,8 @@ AssDialogue::AssDialogue()
} }
AssDialogue::AssDialogue(AssDialogue const& that) AssDialogue::AssDialogue(AssDialogue const& that)
: Comment(that.Comment) : Id(++next_id)
, Comment(that.Comment)
, Layer(that.Layer) , Layer(that.Layer)
, Start(that.Start) , Start(that.Start)
, End(that.End) , End(that.End)
@ -77,7 +81,8 @@ AssDialogue::AssDialogue(AssDialogue const& that)
} }
AssDialogue::AssDialogue(wxString const& data) AssDialogue::AssDialogue(wxString const& data)
: Comment(false) : Id(++next_id)
, Comment(false)
, Layer(0) , Layer(0)
, Start(0) , Start(0)
, End(5000) , End(5000)
@ -325,7 +330,9 @@ wxString AssDialogue::GetStrippedText() const {
} }
AssEntry *AssDialogue::Clone() const { AssEntry *AssDialogue::Clone() const {
return new AssDialogue(*this); AssDialogue *clone = new AssDialogue(*this);
*const_cast<int *>(&clone->Id) = Id;
return clone;
} }
void AssDialogueBlockDrawing::TransformCoords(int mx, int my, double x, double y) { void AssDialogueBlockDrawing::TransformCoords(int mx, int my, double x, double y) {

View File

@ -127,6 +127,11 @@ public:
class AssDialogue : public AssEntry { class AssDialogue : public AssEntry {
wxString GetData(bool ssa) const; wxString GetData(bool ssa) const;
public: 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? /// Is this a comment line?
bool Comment; bool Comment;
/// Layer number /// Layer number

View File

@ -585,7 +585,7 @@ static void duplicate_lines(agi::Context *c, bool shift) {
// Duplicate each of the selected lines, inserting them in a block // Duplicate each of the selected lines, inserting them in a block
// after the selected block // after the selected block
do { do {
AssDialogue *new_diag = static_cast<AssDialogue*>(start->Clone()); AssDialogue *new_diag = new AssDialogue(*static_cast<AssDialogue*>(&*start));
c->ass->Line.insert(insert_pos, *new_diag); c->ass->Line.insert(insert_pos, *new_diag);
new_sel.insert(new_diag); new_sel.insert(new_diag);

View File

@ -228,7 +228,7 @@ void SubtitleFormat::RecombineOverlaps(AssFile &file) {
//Is there an A part before the overlap? //Is there an A part before the overlap?
if (curdlg->Start > prevdlg->Start) { if (curdlg->Start > prevdlg->Start) {
// Produce new entry with correct values // Produce new entry with correct values
AssDialogue *newdlg = static_cast<AssDialogue*>(prevdlg->Clone()); AssDialogue *newdlg = new AssDialogue(*prevdlg);
newdlg->Start = prevdlg->Start; newdlg->Start = prevdlg->Start;
newdlg->End = curdlg->Start; newdlg->End = curdlg->Start;
newdlg->Text = prevdlg->Text; newdlg->Text = prevdlg->Text;
@ -238,7 +238,7 @@ void SubtitleFormat::RecombineOverlaps(AssFile &file) {
// Overlapping A+B part // Overlapping A+B part
{ {
AssDialogue *newdlg = static_cast<AssDialogue*>(prevdlg->Clone()); AssDialogue *newdlg = new AssDialogue(*prevdlg);
newdlg->Start = curdlg->Start; newdlg->Start = curdlg->Start;
newdlg->End = (prevdlg->End < curdlg->End) ? prevdlg->End : curdlg->End; newdlg->End = (prevdlg->End < curdlg->End) ? prevdlg->End : curdlg->End;
// Put an ASS format hard linewrap between lines // 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? // Is there an A part after the overlap?
if (prevdlg->End > curdlg->End) { if (prevdlg->End > curdlg->End) {
// Produce new entry with correct values // Produce new entry with correct values
AssDialogue *newdlg = static_cast<AssDialogue*>(prevdlg->Clone()); AssDialogue *newdlg = new AssDialogue(*prevdlg);
newdlg->Start = curdlg->End; newdlg->Start = curdlg->End;
newdlg->End = prevdlg->End; newdlg->End = prevdlg->End;
newdlg->Text = prevdlg->Text; newdlg->Text = prevdlg->Text;
@ -261,7 +261,7 @@ void SubtitleFormat::RecombineOverlaps(AssFile &file) {
// Is there a B part after the overlap? // Is there a B part after the overlap?
if (curdlg->End > prevdlg->End) { if (curdlg->End > prevdlg->End) {
// Produce new entry with correct values // Produce new entry with correct values
AssDialogue *newdlg = static_cast<AssDialogue*>(prevdlg->Clone()); AssDialogue *newdlg = new AssDialogue(*prevdlg);
newdlg->Start = prevdlg->End; newdlg->Start = prevdlg->End;
newdlg->End = curdlg->End; newdlg->End = curdlg->End;
newdlg->Text = curdlg->Text; newdlg->Text = curdlg->Text;