void AssKaraoke::SplitLines(std::set<AssDialogue*> const& lines, agi::Context *c) { if (lines.empty()) return; AssKaraoke kara; SubtitleSelection sel = c->selectionController->GetSelectedSet(); bool did_split = false; for (entryIter it = c->ass->Line.begin(); it != c->ass->Line.end(); ++it) { AssDialogue *diag = dynamic_cast<AssDialogue*>(&*it); if (!diag || !lines.count(diag)) continue; kara.SetLine(diag); // If there aren't at least two tags there's nothing to split if (kara.size() < 2) continue; bool in_sel = sel.count(diag) > 0; for (auto const& syl : kara) { AssDialogue *new_line = new AssDialogue(*diag); new_line->Start = syl.start_time; new_line->End = syl.start_time + syl.duration; new_line->Text = syl.GetText(false); c->ass->Line.insert(it, *new_line); if (in_sel) sel.insert(new_line); } --it; // Move `it` to the last of the new lines sel.erase(diag); delete diag; did_split = true; } if (!did_split) return; c->ass->Commit(_("splitting"), AssFile::COMMIT_DIAG_ADDREM | AssFile::COMMIT_DIAG_FULL); AssDialogue *new_active = c->selectionController->GetActiveLine(); if (!sel.count(c->selectionController->GetActiveLine())) new_active = *sel.begin(); c->selectionController->SetSelectionAndActive(sel, new_active); }
void VisualToolDrag::OnSelectedSetChanged(const SubtitleSelection &added, const SubtitleSelection &removed) { c->selectionController->GetSelectedSet(selection); bool any_changed = false; for (feature_iterator it = features.begin(); it != features.end(); ) { if (removed.count(it->line)) { sel_features.erase(it++); any_changed = true; } else { if (added.count(it->line) && it->type == DRAG_START && line_not_present(sel_features, it)) { sel_features.insert(it); any_changed = true; } ++it; } } if (any_changed) parent->Render(); }
void DialogShiftTimes::Process(wxCommandEvent &) { int mode = selection_mode->GetSelection(); int type = time_fields->GetSelection(); bool reverse = shift_backward->GetValue(); bool by_time = shift_by_time->GetValue(); bool start = type != 2; bool end = type != 1; SubtitleSelection sel = context->selectionController->GetSelectedSet(); long shift; if (by_time) { shift = shift_time->GetTime(); if (shift == 0) { Close(); return; } } else shift_frames->GetValue().ToLong(&shift); if (reverse) shift = -shift; // Track which rows were shifted for the log int row_number = 0; int block_start = 0; json::Array shifted_blocks; for (auto line : context->ass->Line | agi::of_type<AssDialogue>()) { ++row_number; if (!sel.count(line)) { if (block_start) { json::Object block; block["start"] = block_start; block["end"] = row_number - 1; shifted_blocks.push_back(block); block_start = 0; } if (mode == 1) continue; if (mode == 2 && shifted_blocks.empty()) continue; } else if (!block_start) block_start = row_number; if (start) line->Start = Shift(line->Start, shift, by_time, agi::vfr::START); if (end) line->End = Shift(line->End, shift, by_time, agi::vfr::END); } context->ass->Commit(_("shifting"), AssFile::COMMIT_DIAG_TIME); if (block_start) { json::Object block; block["start"] = block_start; block["end"] = row_number - 1; shifted_blocks.push_back(block); } SaveHistory(shifted_blocks); Close(); }