diff --git a/aegisub/src/command/edit.cpp b/aegisub/src/command/edit.cpp index 4bce705da..87d462a5b 100644 --- a/aegisub/src/command/edit.cpp +++ b/aegisub/src/command/edit.cpp @@ -132,6 +132,46 @@ struct edit_line_duplicate_shift : public Command { } }; +static void combine_lines(agi::Context *c, void (*combiner)(AssDialogue *, AssDialogue *), wxString const& message) { + SelectionController::Selection sel = c->selectionController->GetSelectedSet(); + + AssDialogue *first = 0; + entryIter out = c->ass->Line.begin(); + for (entryIter it = c->ass->Line.begin(); it != c->ass->Line.end(); ++it) { + AssDialogue *diag = dynamic_cast(*it); + if (!diag || !sel.count(diag)) { + *out++ = *it; + continue; + } + if (!first) { + first = diag; + *out++ = *it; + continue; + } + + combiner(first, diag); + + first->End.SetMS(diag->End.GetMS()); + delete diag; + } + + c->ass->Line.erase(out, c->ass->Line.end()); + sel.clear(); + sel.insert(first); + c->selectionController->SetActiveLine(first); + c->selectionController->SetSelectedSet(sel); + c->ass->Commit(message); +} + +static void combine_karaoke(AssDialogue *first, AssDialogue *second) { + first->Text += wxString::Format("{\\k%d}%s", (second->Start.GetMS() - first->End.GetMS()) / 10, second->Text); +} + +static void combine_concat(AssDialogue *first, AssDialogue *second) { + first->Text += L"\\N" + second->Text; +} + +static void combine_drop(AssDialogue *, AssDialogue *) { } /// Joins selected lines in a single one, as karaoke. struct edit_line_join_as_karaoke : public Command { @@ -141,8 +181,7 @@ struct edit_line_join_as_karaoke : public Command { STR_HELP("Joins selected lines in a single one, as karaoke.") void operator()(agi::Context *c) { - wxArrayInt sels = c->subsGrid->GetSelection(); - c->subsGrid->JoinAsKaraoke(sels.front(), sels.back()); + combine_lines(c, combine_karaoke, _("join as karaoke")); } }; @@ -155,8 +194,7 @@ struct edit_line_join_concatenate : public Command { STR_HELP("Joins selected lines in a single one, concatenating text together.") void operator()(agi::Context *c) { - wxArrayInt sels = c->subsGrid->GetSelection(); - c->subsGrid->JoinLines(sels.front(), sels.back(), true); + combine_lines(c, combine_concat, _("join lines")); } }; @@ -169,8 +207,7 @@ struct edit_line_join_keep_first : public Command { STR_HELP("Joins selected lines in a single one, keeping text of first and discarding remaining.") void operator()(agi::Context *c) { - wxArrayInt sels = c->subsGrid->GetSelection(); - c->subsGrid->JoinLines(sels.front(), sels.back(), false); + combine_lines(c, combine_drop, _("join lines")); } }; diff --git a/aegisub/src/subs_grid.cpp b/aegisub/src/subs_grid.cpp index 811ae4af3..f039b1876 100644 --- a/aegisub/src/subs_grid.cpp +++ b/aegisub/src/subs_grid.cpp @@ -517,59 +517,6 @@ void SubtitlesGrid::DeleteLines(wxArrayInt target, bool flagModified) { } } -void SubtitlesGrid::JoinLines(int n1,int n2,bool concat) { - int min_ms = INT_MAX; - int max_ms = INT_MIN; - wxString finalText; - - // Collect data - AssDialogue *cur; - int start,end; - bool gotfirst = false; - bool gottime = false; - for (int i=n1;i<=n2;i++) { - // Get start and end time of current line - cur = GetDialogue(i); - start = cur->Start.GetMS(); - end = cur->End.GetMS(); - - // Don't take the timing of zero lines - if (start != 0 || end != 0) { - if (start < min_ms) min_ms = start; - if (end > max_ms) max_ms = end; - gottime = true; - } - - // Set text - if (concat || !gotfirst) { - if (gotfirst) finalText += _T("\\N"); - gotfirst = true; - finalText += cur->Text; - } - } - - // If it didn't get any times, then it's probably because they were all 0 lines. - if (!gottime) { - min_ms = 0; - max_ms = 0; - } - - // Apply settings to first line - cur = GetDialogue(n1); - cur->Start.SetMS(min_ms); - cur->End.SetMS(max_ms); - cur->Text = finalText; - - // Delete remaining lines (this will auto commit) - DeleteLines(GetRangeArray(n1+1,n2), false); - - context->ass->Commit(_("join lines")); - - // Select new line - SetActiveLine(cur); - SelectRow(n1); -} - void SubtitlesGrid::AdjoinLines(int n1,int n2,bool setStart) { if (n1 == n2) { if (setStart) { @@ -606,52 +553,6 @@ void SubtitlesGrid::AdjoinLines(int n1,int n2,bool setStart) { context->ass->Commit(_("adjoin")); } -void SubtitlesGrid::JoinAsKaraoke(int n1,int n2) { - wxString finalText = _T(""); - - // Collect data - AssDialogue *cur; - int start,end; - int firststart = 0; - int lastend = -1; - int len1,len2; - for (int i=n1;i<=n2;i++) { - cur = GetDialogue(i); - - // Get times - start = cur->Start.GetMS(); - end = cur->End.GetMS(); - - // Get len - if (lastend == -1) { - lastend = start; - firststart = start; - } - len1 = (start - lastend) / 10; - len2 = (end - start) / 10; - - // Create text - if (len1 != 0) finalText += _T("{\\k") + wxString::Format(_T("%i"),len1) + _T("}"); - finalText += _T("{\\k") + wxString::Format(_T("%i"),len2) + _T("}") + cur->Text; - lastend = end; - } - - // Apply settings to first line - cur = GetDialogue(n1); - cur->Start.SetMS(firststart); - cur->End.SetMS(lastend); - cur->Text = finalText; - - // Delete remaining lines (this will auto commit) - DeleteLines(GetRangeArray(n1+1,n2), false); - - context->ass->Commit(_("join as karaoke")); - - // Select new line - SetActiveLine(cur); - SelectRow(n1); -} - void SubtitlesGrid::DuplicateLines(int n1,int n2,bool nextFrame) { AssDialogue *cur; bool update = false; diff --git a/aegisub/src/subs_grid.h b/aegisub/src/subs_grid.h index 96158e356..f37492c67 100644 --- a/aegisub/src/subs_grid.h +++ b/aegisub/src/subs_grid.h @@ -85,15 +85,6 @@ public: /// @param start Start vs. End time void SetSubsToVideo(bool start); - /// @brief Join the selected lines - /// @param n1 First line to join - /// @param n2 Last line to join - /// @param concat Concatenate the lines rather than discarding all past the first - void JoinLines(int first,int last,bool concat=true); - /// @brief Join selected lines as karaoke, with their relative times used for syllable lengths - /// @param n1 First line to join - /// @param n2 Last line to join - void JoinAsKaraoke(int first,int last); /// @brief Adjoins selected lines, setting each line's start time to the previous line's end time /// @param n1 First line to adjoin /// @param n2 Last line to adjoin