From 5c4279a654a4b75dd9f8f3dbca3fb799506174fc Mon Sep 17 00:00:00 2001 From: Thomas Goyne Date: Thu, 6 Jun 2013 18:57:14 -0700 Subject: [PATCH] Add command "edit/line/duplicate/shift_back" --- aegisub/src/command/edit.cpp | 42 ++++++++++++++++++++++++++---------- 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/aegisub/src/command/edit.cpp b/aegisub/src/command/edit.cpp index 41d28e713..74037372e 100644 --- a/aegisub/src/command/edit.cpp +++ b/aegisub/src/command/edit.cpp @@ -571,7 +571,8 @@ struct in_selection : public std::unary_function { } }; -static void duplicate_lines(agi::Context *c, bool shift) { +template +static void duplicate_lines(agi::Context *c, Func&& shift) { in_selection sel(c->selectionController->GetSelectedSet()); SubtitleSelectionController::Selection new_sel; AssDialogue *new_active = 0; @@ -596,12 +597,7 @@ static void duplicate_lines(agi::Context *c, bool shift) { new_sel.insert(new_diag); if (!new_active) new_active = new_diag; - - if (shift) { - int pos = c->videoController->FrameAtTime(new_diag->End, agi::vfr::END) + 1; - new_diag->Start = c->videoController->TimeAtFrame(pos, agi::vfr::START); - new_diag->End = c->videoController->TimeAtFrame(pos, agi::vfr::END); - } + shift(new_diag); } while (start++ != last); // Skip over the lines we just made @@ -623,17 +619,16 @@ struct edit_line_duplicate : public validate_sel_nonempty { STR_HELP("Duplicate the selected lines") void operator()(agi::Context *c) { - duplicate_lines(c, false); + duplicate_lines(c, [](AssDialogue *){}); } }; - /// Duplicate lines and shift by one frame. struct edit_line_duplicate_shift : public Command { CMD_NAME("edit/line/duplicate/shift") STR_MENU("D&uplicate and Shift by 1 Frame") STR_DISP("Duplicate and Shift by 1 Frame") - STR_HELP("Duplicate lines and shift by one frame") + STR_HELP("Duplicate lines and shift them to the frame after the original end frame") CMD_TYPE(COMMAND_VALIDATE) bool Validate(const agi::Context *c) { @@ -641,7 +636,31 @@ struct edit_line_duplicate_shift : public Command { } void operator()(agi::Context *c) { - duplicate_lines(c, true); + duplicate_lines(c, [=](AssDialogue *new_diag) { + int pos = c->videoController->FrameAtTime(new_diag->End, agi::vfr::END) + 1; + new_diag->Start = c->videoController->TimeAtFrame(pos, agi::vfr::START); + new_diag->End = c->videoController->TimeAtFrame(pos, agi::vfr::END); + }); + } +}; + +struct edit_line_duplicate_shift_back : public Command { + CMD_NAME("edit/line/duplicate/shift_back") + STR_MENU("Du&plicate and Shift by 1 Frame Backwards") + STR_DISP("Duplicate and Shift by 1 Frame Backwards") + STR_HELP("Duplicate selected lines and shift them to the frame before the original start frame") + CMD_TYPE(COMMAND_VALIDATE) + + bool Validate(const agi::Context *c) { + return !c->selectionController->GetSelectedSet().empty() && c->videoController->IsLoaded(); + } + + void operator()(agi::Context *c) { + duplicate_lines(c, [=](AssDialogue *new_diag) { + int pos = c->videoController->FrameAtTime(new_diag->Start, agi::vfr::START) - 1; + new_diag->Start = c->videoController->TimeAtFrame(pos, agi::vfr::START); + new_diag->End = c->videoController->TimeAtFrame(pos, agi::vfr::END); + }); } }; @@ -1000,6 +1019,7 @@ namespace cmd { reg(new edit_line_delete); reg(new edit_line_duplicate); reg(new edit_line_duplicate_shift); + reg(new edit_line_duplicate_shift_back); reg(new edit_line_join_as_karaoke); reg(new edit_line_join_concatenate); reg(new edit_line_join_keep_first);