From 99a7eece9c719e2cf34703cac180abb9e0bbb96e Mon Sep 17 00:00:00 2001 From: Thomas Goyne Date: Thu, 26 Jan 2012 20:08:54 +0000 Subject: [PATCH] Significantly speed up duplicating multiple lines SubtitlesGrid::DuplicateLines iterated over the entire file multiple times for each line duplicated, making duplicating large numbers of lines extremely slow. Originally committed to SVN as r6366. --- aegisub/src/subs_grid.cpp | 43 ++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/aegisub/src/subs_grid.cpp b/aegisub/src/subs_grid.cpp index 19002ab2c..277b291f6 100644 --- a/aegisub/src/subs_grid.cpp +++ b/aegisub/src/subs_grid.cpp @@ -371,34 +371,35 @@ void SubtitlesGrid::AdjoinLines(int n1,int n2,bool setStart) { context->ass->Commit(_("adjoin"), AssFile::COMMIT_DIAG_TIME); } -void SubtitlesGrid::DuplicateLines(int n1,int n2,bool nextFrame) { - AssDialogue *cur; - bool update = false; - int step=0; - for (int i=n1;i<=n2;i++) { - // Create - if (i == n2) update = true; - cur = new AssDialogue(GetDialogue(i)->GetEntryData()); +void SubtitlesGrid::DuplicateLines(int n1, int n2, bool nextFrame) { + std::list::iterator insert_pos = find(context->ass->Line.begin(), context->ass->Line.end(), GetDialogue(n2)); + if (insert_pos != context->ass->Line.end()) + ++insert_pos; + + Selection newsel; + + AssDialogue *first = 0; + + for (int i = n1; i <= n2; ++i) { + AssDialogue *diag = new AssDialogue(*GetDialogue(i)); + if (!first) + first = diag; + + context->ass->Line.insert(insert_pos, diag); + newsel.insert(diag); // Shift to next frame if (nextFrame) { - int posFrame = context->videoController->FrameAtTime(cur->End,agi::vfr::END) + 1; - cur->Start = context->videoController->TimeAtFrame(posFrame,agi::vfr::START); - cur->End = context->videoController->TimeAtFrame(posFrame,agi::vfr::END); + int posFrame = context->videoController->FrameAtTime(diag->End, agi::vfr::END) + 1; + diag->Start = context->videoController->TimeAtFrame(posFrame, agi::vfr::START); + diag->End = context->videoController->TimeAtFrame(posFrame, agi::vfr::END); } - - // Insert - InsertLine(cur,n2+step,true,update); - step++; } - // Select new lines - Selection newsel; - for (int i=n1;i<=n2;i++) { - newsel.insert(GetDialogue(i+step)); - } + context->ass->Commit(_("duplicate lines"), AssFile::COMMIT_DIAG_ADDREM); + SetSelectedSet(newsel); - SetActiveLine(GetDialogue(n1+step)); + SetActiveLine(first); } /// @brief Retrieve a list of selected lines in the actual ASS file (ie. not as displayed in the grid but as represented in the file)