示例#1
0
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);
}
示例#2
0
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();
}