Add support for noncontiguous selections to the duplicate lines commands
Originally committed to SVN as r6476.
This commit is contained in:
parent
d4e1c90a04
commit
9b69ce7a27
3 changed files with 56 additions and 41 deletions
|
@ -133,6 +133,60 @@ struct edit_line_delete : public validate_sel_nonempty {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct in_selection : public std::unary_function<AssEntry*, bool> {
|
||||||
|
SubtitleSelectionController::Selection const& sel;
|
||||||
|
in_selection(SubtitleSelectionController::Selection const& sel) : sel(sel) { }
|
||||||
|
bool operator()(AssEntry *e) const {
|
||||||
|
AssDialogue *d = dynamic_cast<AssDialogue*>(e);
|
||||||
|
return d && sel.count(d);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static void duplicate_lines(agi::Context *c, bool shift) {
|
||||||
|
in_selection sel(c->selectionController->GetSelectedSet());
|
||||||
|
SubtitleSelectionController::Selection new_sel;
|
||||||
|
AssDialogue *new_active = 0;
|
||||||
|
|
||||||
|
std::list<AssEntry*>::iterator start = c->ass->Line.begin();
|
||||||
|
std::list<AssEntry*>::iterator end = c->ass->Line.end();
|
||||||
|
while (start != end) {
|
||||||
|
// Find the first line in the selection
|
||||||
|
start = find_if(start, end, sel);
|
||||||
|
if (start == end) break;
|
||||||
|
|
||||||
|
// And the last line in this contiguous selection
|
||||||
|
std::list<AssEntry*>::iterator insert_pos = find_if(start, end, std::not1(sel));
|
||||||
|
std::list<AssEntry*>::iterator last = insert_pos;
|
||||||
|
--last;
|
||||||
|
|
||||||
|
// Duplicate each of the selected lines, inserting them in a block
|
||||||
|
// after the selected block
|
||||||
|
do {
|
||||||
|
AssDialogue *new_diag = static_cast<AssDialogue*>((*start)->Clone());
|
||||||
|
|
||||||
|
c->ass->Line.insert(insert_pos, new_diag);
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
} while (start++ != last);
|
||||||
|
|
||||||
|
// Skip over the lines we just made
|
||||||
|
start = insert_pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (new_sel.empty()) return;
|
||||||
|
|
||||||
|
c->ass->Commit(_("duplicate lines"), AssFile::COMMIT_DIAG_ADDREM);
|
||||||
|
|
||||||
|
c->selectionController->SetSelectedSet(new_sel);
|
||||||
|
c->selectionController->SetActiveLine(new_active);
|
||||||
|
}
|
||||||
|
|
||||||
/// Duplicate the selected lines.
|
/// Duplicate the selected lines.
|
||||||
struct edit_line_duplicate : public validate_sel_nonempty {
|
struct edit_line_duplicate : public validate_sel_nonempty {
|
||||||
|
@ -142,8 +196,7 @@ struct edit_line_duplicate : public validate_sel_nonempty {
|
||||||
STR_HELP("Duplicate the selected lines")
|
STR_HELP("Duplicate the selected lines")
|
||||||
|
|
||||||
void operator()(agi::Context *c) {
|
void operator()(agi::Context *c) {
|
||||||
wxArrayInt sels = c->subsGrid->GetSelection();
|
duplicate_lines(c, false);
|
||||||
c->subsGrid->DuplicateLines(sels.front(), sels.back(), false);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -161,8 +214,7 @@ struct edit_line_duplicate_shift : public Command {
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator()(agi::Context *c) {
|
void operator()(agi::Context *c) {
|
||||||
wxArrayInt sels = c->subsGrid->GetSelection();
|
duplicate_lines(c, true);
|
||||||
c->subsGrid->DuplicateLines(sels.front(), sels.back(), true);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -373,37 +373,6 @@ void SubtitlesGrid::AdjoinLines(int n1,int n2,bool setStart) {
|
||||||
context->ass->Commit(_("adjoin"), AssFile::COMMIT_DIAG_TIME);
|
context->ass->Commit(_("adjoin"), AssFile::COMMIT_DIAG_TIME);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SubtitlesGrid::DuplicateLines(int n1, int n2, bool nextFrame) {
|
|
||||||
std::list<AssEntry*>::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(diag->End, agi::vfr::END) + 1;
|
|
||||||
diag->Start = context->videoController->TimeAtFrame(posFrame, agi::vfr::START);
|
|
||||||
diag->End = context->videoController->TimeAtFrame(posFrame, agi::vfr::END);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
context->ass->Commit(_("duplicate lines"), AssFile::COMMIT_DIAG_ADDREM);
|
|
||||||
|
|
||||||
SetSelectedSet(newsel);
|
|
||||||
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)
|
/// @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)
|
||||||
/// @return
|
/// @return
|
||||||
///
|
///
|
||||||
|
|
|
@ -58,12 +58,6 @@ public:
|
||||||
/// @param setStart Set the start times (rather than end times)
|
/// @param setStart Set the start times (rather than end times)
|
||||||
void AdjoinLines(int first,int last,bool setStart);
|
void AdjoinLines(int first,int last,bool setStart);
|
||||||
|
|
||||||
/// @brief Duplicate lines
|
|
||||||
/// @param n1 First frame to duplicate
|
|
||||||
/// @param n2 Last frame to duplicate
|
|
||||||
/// @param nextFrame Set the new lines to start and end on the next frame
|
|
||||||
void DuplicateLines(int first,int last,bool nextFrame=false);
|
|
||||||
|
|
||||||
void InsertLine(AssDialogue *line,int position,bool insertAfter,bool update=true);
|
void InsertLine(AssDialogue *line,int position,bool insertAfter,bool update=true);
|
||||||
/// @brief Delete selected lines
|
/// @brief Delete selected lines
|
||||||
/// @param target Lines to delete
|
/// @param target Lines to delete
|
||||||
|
|
Loading…
Reference in a new issue