コード例 #1
0
///////////////////
// split current line
void FrameMain::OnVideoTrackSplitLine(wxCommandEvent &event) {
	videoBox->videoDisplay->Stop();

	// Get line
	AssDialogue *curline = SubsBox->GetDialogue(EditBox->linen);
	if (!curline) return;
	if( !curline->Movement ) return;

	// Create split lines
	int StartFrame = VFR_Output.GetFrameAtTime(curline->Start.GetMS(),true);
	int EndFrame = VFR_Output.GetFrameAtTime(curline->End.GetMS(),false);

	AssFile *subs = AssFile::top;
	int ResXValue,ResYValue;
	swscanf( subs->GetScriptInfo(_T("PlayResX")), _T("%d"), &ResXValue );
	swscanf( subs->GetScriptInfo(_T("PlayResY")), _T("%d"), &ResYValue );
	int SrcXValue = videoBox->videoDisplay->provider->GetSourceWidth();
	int SrcYValue = videoBox->videoDisplay->provider->GetSourceHeight();

	float sx = float(ResXValue)/float(SrcXValue);
	float sy = float(ResYValue)/float(SrcYValue);

	for( int Frame = StartFrame; Frame < EndFrame; Frame ++ )
	{
		int localframe = Frame - StartFrame;

		while( curline->Movement->Frames.size() <= localframe ) localframe--;
		FexMovementFrame f = curline->Movement->Frames[localframe];
//		f.Pos.x /= videoBox->videoDisplay->GetW

		AssDialogue *cur = new AssDialogue( curline->GetEntryData() );
		cur->Start.SetMS(VFR_Output.GetTimeAtFrame(Frame,true));
		cur->End.SetMS(VFR_Output.GetTimeAtFrame(Frame,false));
		cur->Text = wxString::Format( _T("{\\pos(%.0f,%.0f)\\fscx%.2f\\fscy%.2f}"), f.Pos.x*sx, f.Pos.y*sy, f.Scale.x*100, f.Scale.y*100 ) + cur->Text;
		cur->UpdateData();

		SubsBox->InsertLine(cur,EditBox->linen + Frame - StartFrame,true,false);
	}

	// Remove Movement
	DeleteMovement( curline->Movement );
	curline->Movement = 0;

	// Remove Tracker
	delete curline->Tracker;
	curline->Tracker = 0;

	// Remove this line
	SubsBox->DeleteLines(SubsBox->GetRangeArray(EditBox->linen, EditBox->linen));

	videoBox->videoDisplay->RefreshVideo();
}
コード例 #2
0
///////////////////
// link line to move file
void FrameMain::OnVideoTrackLinkFile(wxCommandEvent &event) {
	videoBox->videoDisplay->Stop();

	// Get line
	AssDialogue *curline = SubsBox->GetDialogue(EditBox->linen);
	if (!curline) return;

	wxString link = wxGetTextFromUser(_("Link name:"), _("Link line to movement file"), curline->Movement?curline->Movement->FileName:_T(""), this);
	if( link.empty() ) curline->Effect = _T("");
	else curline->Effect = _T("FexMovement:")+link;
	
	curline->UpdateData();

	if( !curline->Effect.empty() && curline->Movement )
		SaveMovement( curline->Movement, curline->Effect.AfterFirst(':').c_str() );
}
コード例 #3
0
ファイル: subs_grid.cpp プロジェクト: Azpidatziak/Aegisub
void SubtitlesGrid::CopyLines(wxArrayInt target) {
	// Prepare text
	wxString data;
	AssDialogue *cur;
	int nrows = target.Count();
	bool first = true;
	for (int i=0;i<nrows;i++) {
		if (!first) data += "\r\n";
		first = false;
		cur = GetDialogue(target[i]);
		data += cur->GetEntryData();
	}

	// Send to clipboard
	if (wxTheClipboard->Open()) {
		wxTheClipboard->SetData(new wxTextDataObject(data));
		wxTheClipboard->Close();
	}
}
コード例 #4
0
/////////////////////////////
// Set style of current line
void DialogStyling::SetStyle (wxString curName, bool jump) {
	// Get line
	AssDialogue *line = grid->GetDialogue(linen);

	// Update line
	line->Style = curName;
	line->UpdateData();

	// Update grid/subs
	grid->Refresh(false);
	if (PreviewCheck->IsChecked()) {
		grid->ass->FlagAsModified(_("Change Style (Assistant)"));
		grid->CommitChanges();
	}
	else needCommit = true;

	// Next line
	if (jump) JumpToLine(linen+1);
}
コード例 #5
0
///////////////////////
// Transform framerate
void AssTransformFramerateFilter::TransformFrameRate(AssFile *subs) {
	int n=0;

	// Run through
	using std::list;
	AssEntry *curEntry;
	AssDialogue *curDialogue;
	for (entryIter cur=subs->Line.begin();cur!=subs->Line.end();cur++) {
		curEntry = *cur;
		curEntry->StartMS = Input->GetTimeAtFrame(Output->GetFrameAtTime(curEntry->StartMS,true),true);
		curDialogue = AssEntry::GetAsDialogue(curEntry);

		// Update dialogue entries
		if (curDialogue) {
			// Line data
			LineData data;
			data.line = curDialogue;
			data.k = 0;
			data.kf = 0;
			data.ko = 0;

			// Process stuff
			curDialogue->ParseASSTags();
			curDialogue->ProcessParameters(TransformTimeTags,&data);
			curDialogue->Start.SetMS(Input->GetTimeAtFrame(Output->GetFrameAtTime(curDialogue->Start.GetMS(),true),true));
			curDialogue->End.SetMS(Input->GetTimeAtFrame(Output->GetFrameAtTime(curDialogue->End.GetMS(),false),false));
			curDialogue->UpdateText();
			curDialogue->UpdateData();
			curDialogue->ClearBlocks();
			n++;
		}
	}
}
コード例 #6
0
void AssTransformFramerateFilter::TransformFrameRate(AssFile *subs) {
	if (!Input->IsLoaded() || !Output->IsLoaded()) return;
	for (entryIter cur=subs->Line.begin();cur!=subs->Line.end();cur++) {
		AssDialogue *curDialogue = dynamic_cast<AssDialogue*>(*cur);

		if (curDialogue) {
			line = curDialogue;
			newK = 0;
			oldK = 0;
			newStart = trunc_cs(ConvertTime(curDialogue->Start));
			newEnd = trunc_cs(ConvertTime(curDialogue->End) + 9);

			// Process stuff
			curDialogue->ParseASSTags();
			curDialogue->ProcessParameters(TransformTimeTags, this);
			curDialogue->Start = newStart;
			curDialogue->End = newEnd;
			curDialogue->UpdateText();
			curDialogue->ClearBlocks();
		}
	}
}
コード例 #7
0
///////////
// Collect
void FontsCollectorThread::Collect() {
	// Make sure there is a separator at the end
	destination += _T("\\");

	// Reset log box
	wxTextCtrl *LogBox = collector->LogBox;
	wxMutexGuiEnter();
	LogBox->SetValue(_T(""));
	LogBox->SetDefaultStyle(wxTextAttr(wxColour(0,0,180)));
	LogBox->AppendText(_("Searching for fonts in file...\n"));
	LogBox->SetDefaultStyle(wxTextAttr(wxColour(0,0,0)));
	LogBox->Refresh();
	LogBox->Update();
	wxSafeYield();
	wxMutexGuiLeave();

	// Scans file
	bool fileModified = false;
	AssStyle *curStyle;
	AssDialogue *curDiag;
	curLine = 0;
	for (std::list<AssEntry*>::iterator cur=subs->Line.begin();cur!=subs->Line.end();cur++) {
		// Collect from style
		curStyle = AssEntry::GetAsStyle(*cur);
		if (curStyle) {
			AddFont(curStyle->font,true);
			wxMutexGuiEnter();
			LogBox->AppendText(wxString(_T("\"")) + curStyle->font + _("\" found on style \"") + curStyle->name + _T("\".\n"));
			LogBox->Refresh();
			LogBox->Update();
			wxSafeYield();
			wxMutexGuiLeave();
		}

		// Collect from dialogue
		else {
			curDiag = AssEntry::GetAsDialogue(*cur);
			if (curDiag) {
				curLine++;
				curDiag->ParseASSTags();
				curDiag->ProcessParameters(GetFonts);
				curDiag->ClearBlocks();
			}
		}
	}

#ifdef __WINDOWS__
	// Collect font data
	wxMutexGuiEnter();
	LogBox->SetDefaultStyle(wxTextAttr(wxColour(0,0,180)));
	LogBox->AppendText(_("\nReading fonts from registry...\n"));
	LogBox->SetDefaultStyle(wxTextAttr(wxColour(0,0,0)));
	wxSafeYield();
	wxMutexGuiLeave();
	CollectFontData();

	// Get fonts folder
	wxString source;
	TCHAR szPath[MAX_PATH];
	if (SUCCEEDED(SHGetFolderPath(NULL, CSIDL_FONTS,NULL,0,szPath))) {
		source = wxString(szPath);
	}
	else source = wxGetOSDirectory() + _T("\\fonts");
	source += _T("\\");

	// Get font file names
	wxArrayString work;
	wxArrayString copied;
	bool attaching = collector->AttachmentCheck->IsChecked();
	for (size_t i=0;i<fonts.GetCount();i++) {
		try {
			work = GetFontFiles(fonts[i]);
			for (size_t j=0;j<work.GetCount();j++) {
				// Get path to font file
				wxString srcFile,dstFile;
				wxFileName srcFileName(work[j]);
				if (srcFileName.FileExists() && srcFileName.IsAbsolute()) {
					srcFile = work[j];
					dstFile = destination + srcFileName.GetFullName();
				}
				else {
					srcFile = source + work[j];
					dstFile = destination + work[j];
				}

				if (copied.Index(work[j]) == wxNOT_FOUND) {
					copied.Add(work[j]);

					// Check if it exists
					if (!attaching && wxFileName::FileExists(dstFile)) {
						wxMutexGuiEnter();
						LogBox->SetDefaultStyle(wxTextAttr(wxColour(255,128,0)));
						LogBox->AppendText(wxString(_T("\"")) + work[j] + _("\" already exists on destination.\n"));
						LogBox->Refresh();
						LogBox->Update();
						wxSafeYield();
						wxMutexGuiLeave();
					}

					// Copy
					else {
						// Copy font
						bool success;
						if (attaching) {
							try {
								subs->InsertAttachment(srcFile);
								fileModified = true;
								success = true;
							}
							catch (...) { success = false; }
						}
						else success = Copy(srcFile,dstFile);

						// Report
						wxMutexGuiEnter();
						if (success) {
							LogBox->SetDefaultStyle(wxTextAttr(wxColour(0,180,0)));
							LogBox->AppendText(wxString(_T("\"")) + work[j] + _("\" copied.\n"));

						}
						else {
							LogBox->SetDefaultStyle(wxTextAttr(wxColour(220,0,0)));
							LogBox->AppendText(wxString(_("Failed copying \"")) + srcFile + _T("\".\n"));
						}
						LogBox->Refresh();
						LogBox->Update();
						wxSafeYield();
						wxMutexGuiLeave();
					}
				}
			}
		}

		catch (...) {
			wxMutexGuiEnter();
			LogBox->SetDefaultStyle(wxTextAttr(wxColour(220,0,0)));
			LogBox->AppendText(wxString(_("Could not find font ")) + fonts[i] + _T("\n"));
			wxMutexGuiLeave();
		}
	}
#endif

	// Flag file as modified
	if (fileModified) {
		subs->FlagAsModified();
		collector->main->SubsBox->CommitChanges();
	}
}
コード例 #8
0
void TXTSubtitleFormat::WriteFile(const AssFile *src, wxString const& filename, wxString const& encoding) const {
	size_t num_actor_names = 0, num_dialogue_lines = 0;

	// Detect number of lines with Actor field filled out
	for (LineList::const_iterator l = src->Line.begin(); l != src->Line.end(); ++l) {
		AssDialogue *dia = dynamic_cast<AssDialogue*>(*l);
		if (dia && !dia->Comment) {
			num_dialogue_lines++;
			if (!dia->Actor.empty())
				num_actor_names++;
		}
	}

	// If too few lines have Actor filled out, don't write it
	bool write_actors = num_actor_names > num_dialogue_lines/2;
	bool strip_formatting = true;

	TextFileWriter file(filename, encoding);
	file.WriteLineToFile(wxString("# Exported by Aegisub ") + GetAegisubShortVersionString());

	// Write the file
	for (LineList::const_iterator l = src->Line.begin(); l != src->Line.end(); ++l) {
		AssDialogue *dia = dynamic_cast<AssDialogue*>(*l);

		if (dia) {
			wxString out_line;

			if (dia->Comment) {
				out_line = "# ";
			}

			if (write_actors) {
				out_line += dia->Actor + ": ";
			}

			wxString out_text;
			if (strip_formatting) {
				dia->ParseASSTags();
				for (std::vector<AssDialogueBlock*>::iterator block = dia->Blocks.begin(); block != dia->Blocks.end(); ++block) {
					if ((*block)->GetType() == BLOCK_PLAIN) {
						out_text += (*block)->GetText();
					}
				}
				dia->ClearBlocks();
			}
			else {
				out_text = dia->Text;
			}
			out_line += out_text;

			if (!out_text.empty()) {
				file.WriteLineToFile(out_line);
			}
		}
		else {
			// Not a dialogue line
			// TODO: should any non-dia lines cause blank lines in output?
			//file.WriteLineToFile("");
		}
	}
}
コード例 #9
0
////////////
// Resample
void DialogResample::OnResample (wxCommandEvent &event) {
	// Resolutions
	AssFile *subs = AssFile::top;
	int x1,y1;
	subs->GetResolution(x1,y1);
	long x2 = 0;
	long y2 = 0;
	ResX->GetValue().ToLong(&x2);
	ResY->GetValue().ToLong(&y2);

	// Check for validity
	if (x1 == 0 || x2 == 0 || y1 == 0 || y2 == 0) {
		EndModal(0);
		return;
	}

	// Calculate resamples
	rx = double(x2)/double(x1);
	ry = double(y2)/double(y1);
	r = ry;
	if (Anamorphic->IsChecked()) ar = rx/ry;
	else ar = 1.0;

	// Iterate through subs
	AssStyle *curStyle;
	AssDialogue *curDiag;
	for (entryIter cur=subs->Line.begin();cur!=subs->Line.end();cur++) {
		// Apply to dialogues
		curDiag = AssEntry::GetAsDialogue(*cur);
		if (curDiag) {
			try {
				// Override tags
				curDiag->ParseASSTags();
				curDiag->ProcessParameters(ResampleTags,curDiag);

				// Drawing tags
				size_t nblocks = curDiag->Blocks.size();
				AssDialogueBlockDrawing *curBlock;
				for (size_t i=0;i<nblocks;i++) {
					curBlock = AssDialogueBlock::GetAsDrawing(curDiag->Blocks.at(i));
					if (curBlock) {
						curBlock->MultiplyCoords(rx,ry);
					}
				}

				// Margins
				curDiag->MarginL = int(curDiag->MarginL * rx + 0.5);
				curDiag->MarginR = int(curDiag->MarginR * rx + 0.5);
				curDiag->MarginV = int(curDiag->MarginV * ry + 0.5);

				// Update
				curDiag->UpdateText();
				curDiag->UpdateData();
				curDiag->ClearBlocks();
				continue;
			}
			catch (const wchar_t *err) {
				wxLogMessage(err);
			}
			catch (wxString err) {
				wxLogMessage(err);
			}
		}

		// Apply to styles
		curStyle = AssEntry::GetAsStyle(*cur);
		if (curStyle) {
			curStyle->fontsize = int(curStyle->fontsize * r + 0.5);
			//curStyle->outline_w *= r;
			//curStyle->shadow_w *= r;
			curStyle->spacing *= rx;
			curStyle->scalex *= ar;
			curStyle->MarginL = int(curStyle->MarginL * rx + 0.5);
			curStyle->MarginR = int(curStyle->MarginR * rx + 0.5);
			curStyle->MarginV = int(curStyle->MarginV * ry + 0.5);
			curStyle->UpdateData();
		}
	}

	// Change script resolution
	subs->SetScriptInfo(_T("PlayResX"),wxString::Format(_T("%i"),x2));
	subs->SetScriptInfo(_T("PlayResY"),wxString::Format(_T("%i"),y2));

	// Flag as modified
	subs->FlagAsModified();
	grid->CommitChanges();;
	EndModal(0);
}
コード例 #10
0
//////////////
// Draw image
void BaseGrid::DrawImage(wxDC &dc) {
	dc.BeginDrawing();

	// Get size and pos
	int w = 0;
	int h = 0;
	GetClientSize(&w,&h);

	// Set font
	dc.SetFont(font);

	// Clear background
	dc.SetBackground(wxBrush(Options.AsColour(_T("Grid Background"))));
	dc.Clear();

	// Draw labels
	dc.SetPen(*wxTRANSPARENT_PEN);
	dc.SetBrush(wxBrush(Options.AsColour(_T("Grid left column"))));
	dc.DrawRectangle(0,lineHeight,colWidth[0],h-lineHeight);

	// Visible lines
	int drawPerScreen = h/lineHeight + 1;
	int nDraw = MID(0,drawPerScreen,GetRows()-yPos);
	int maxH = (nDraw+1) * lineHeight;

	// Row colors
	std::vector<wxBrush> rowColors;
	std::vector<wxColor> foreColors;
	rowColors.push_back(wxBrush(Options.AsColour(_T("Grid Background"))));					// 0 = Standard
	foreColors.push_back(Options.AsColour(_T("Grid standard foreground")));
	rowColors.push_back(wxBrush(Options.AsColour(_T("Grid Header"))));						// 1 = Header
	foreColors.push_back(Options.AsColour(_T("Grid standard foreground")));
	rowColors.push_back(wxBrush(Options.AsColour(_T("Grid selection background"))));		// 2 = Selected
	foreColors.push_back(Options.AsColour(_T("Grid selection foreground")));
	rowColors.push_back(wxBrush(Options.AsColour(_T("Grid comment background"))));			// 3 = Commented
	foreColors.push_back(Options.AsColour(_T("Grid selection foreground")));
	rowColors.push_back(wxBrush(Options.AsColour(_T("Grid inframe background"))));			// 4 = Video Highlighted
	foreColors.push_back(Options.AsColour(_T("Grid selection foreground")));
	rowColors.push_back(wxBrush(Options.AsColour(_T("Grid selected comment background"))));	// 5 = Commented & selected
	foreColors.push_back(Options.AsColour(_T("Grid selection foreground")));

	// First grid row
	bool drawGrid = true;
	if (drawGrid) {
		dc.SetPen(wxPen(Options.AsColour(_T("Grid lines"))));
		dc.DrawLine(0,0,w,0);
		dc.SetPen(*wxTRANSPARENT_PEN);
	}

	// Draw rows
	int dx = 0;
	int dy = 0;
	int curColor = 0;
	AssDialogue *curDiag;
	for (int i=0;i<nDraw+1;i++) {
		// Prepare
		int curRow = i+yPos-1;
		curDiag = GetDialogue(curRow);
		dx = 0;
		dy = i*lineHeight;

		// Check for collisions
		bool collides = false;
		if (curDiag) {
			AssDialogue *sel = GetDialogue(editBox->linen);
			if (sel && sel != curDiag) {
				if (curDiag->CollidesWith(sel)) collides = true;
			}
		}

		// Text array
		wxArrayString strings;

		// Header
		if (i == 0) {
			strings.Add(_("#"));
			strings.Add(_("L"));
			strings.Add(_("Start"));
			strings.Add(_("End"));
			strings.Add(_("Style"));
			strings.Add(_("Actor"));
			strings.Add(_("Effect"));
			strings.Add(_("Left"));
			strings.Add(_("Right"));
			strings.Add(_("Vert"));
			strings.Add(_("Text"));
			curColor = 1;
		}

		// Lines
		else if (curDiag) {
			// Set fields
			strings.Add(wxString::Format(_T("%i"),curRow+1));
			strings.Add(wxString::Format(_T("%i"),curDiag->Layer));
			if (byFrame) {
				strings.Add(wxString::Format(_T("%i"),VFR_Output.GetFrameAtTime(curDiag->Start.GetMS(),true)));
				strings.Add(wxString::Format(_T("%i"),VFR_Output.GetFrameAtTime(curDiag->End.GetMS(),true)));
			}
			else {
				strings.Add(curDiag->Start.GetASSFormated());
				strings.Add(curDiag->End.GetASSFormated());
			}
			strings.Add(curDiag->Style);
			strings.Add(curDiag->Actor);
			strings.Add(curDiag->Effect);
			strings.Add(curDiag->GetMarginString(1));
			strings.Add(curDiag->GetMarginString(2));
			strings.Add(curDiag->GetMarginString(3));

			// Set text
			int mode = Options.AsInt(_T("Grid Hide Overrides"));
			wxString value = _T("");

			// Hidden overrides
			if (mode == 1 || mode == 2) {
				wxString replaceWith = Options.AsText(_T("Grid hide overrides char"));
				curDiag->ParseASSTags();
				size_t n = curDiag->Blocks.size();
				for (size_t i=0;i<n;i++) {
					AssDialogueBlock *block = curDiag->Blocks.at(i);
					AssDialogueBlockPlain *plain = AssDialogueBlock::GetAsPlain(block);
					if (plain) {
						value += plain->GetText();
					}
					else {
						if (mode == 1) {
							value += replaceWith;
						}
					}
				}
				curDiag->ClearBlocks();
			}

			// Show overrides
			else value = curDiag->Text;

			// Cap length and set text
			if (value.Length() > 512) value = value.Left(512) + _T("...");
			strings.Add(value);

			// Set color
			curColor = 0;
			bool inSel = IsInSelection(curRow,0);
			if (inSel && curDiag->Comment) curColor = 5;
			else if (inSel) curColor = 2;
			else if (curDiag->Comment) curColor = 3;
			else if (Options.AsBool(_T("Highlight subs in frame")) && IsDisplayed(curDiag)) curColor = 4;
		}

		else {
			for (int j=0;j<11;j++) strings.Add(_T("?"));
		}

		// Draw row background color
		if (curColor) {
			dc.SetBrush(rowColors[curColor]);
			dc.DrawRectangle((curColor == 1) ? 0 : colWidth[0],i*lineHeight+1,w,lineHeight);
		}

		// Set text color
		if (collides) dc.SetTextForeground(Options.AsColour(_T("Grid collision foreground")));
		else {
			dc.SetTextForeground(foreColors[curColor]);
		}

		// Draw text
		wxRect cur;
		bool isCenter;
		for (int j=0;j<11;j++) {
			// Is center?
			isCenter = !(j == 4 || j == 5 || j == 6 || j == 10);

			// Calculate clipping
			cur = wxRect(dx+4,dy,colWidth[j]-6,lineHeight);

			// Set clipping
			dc.DestroyClippingRegion();
			dc.SetClippingRegion(cur);

			// Draw
			dc.DrawLabel(strings[j],cur,isCenter ? wxALIGN_CENTER : (wxALIGN_CENTER_VERTICAL | wxALIGN_LEFT));
			dx += colWidth[j];
		}
		//if (collides) dc.SetPen(wxPen(wxColour(255,0,0)));

		// Draw grid
		dc.DestroyClippingRegion();
		if (drawGrid) {
			dc.SetPen(wxPen(Options.AsColour(_T("Grid lines"))));
			dc.DrawLine(0,dy+lineHeight,w,dy+lineHeight);
			dc.SetPen(*wxTRANSPARENT_PEN);
		}
	}

	// Draw grid columns
	dx = 0;
	if (drawGrid) {
		dc.SetPen(wxPen(Options.AsColour(_T("Grid lines"))));
		for (int i=0;i<10;i++) {
			dx += colWidth[i];
			dc.DrawLine(dx,0,dx,maxH);
		}
		dc.DrawLine(0,0,0,maxH);
		dc.DrawLine(w-1,0,w-1,h);
	}

	// Draw currently active line border
	dc.SetPen(wxPen(Options.AsColour(_T("Grid Active border"))));
	dc.SetBrush(*wxTRANSPARENT_BRUSH);
	dy = (editBox->linen+1-yPos) * lineHeight;
	dc.DrawRectangle(0,dy,w,lineHeight+1);

	// Done
	dc.EndDrawing();
}
コード例 #11
0
////////////////////////////////
// Find & Replace next instance
void SearchReplaceEngine::ReplaceNext(bool DoReplace) {
	// Check if it's OK to go on
	if (!CanContinue) {
		OpenDialog(DoReplace);
		return;
	}
	
	wxArrayInt sels = grid->GetSelection();
	// if selection has changed reset values
	if (sels[0] < curLine) {
		curLine = sels[0];
		Modified = false;
		LastWasFind = true;
		pos = 0;
		matchLen = 0;
		replaceLen = 0;
	}

	// Setup
	int start = curLine;
	int nrows = grid->GetRows();
	bool found = false;
	wxString *Text;
	size_t tempPos;
	int regFlags = wxRE_ADVANCED;
	if (!matchCase) {
		if (isReg) regFlags |= wxRE_ICASE;
		else LookFor.MakeLower();
	}

	// Search for it
	while (!found) {
		Text = GetText(curLine,field);
		if (DoReplace && LastWasFind) tempPos = pos;
		else tempPos = pos+replaceLen;

		// RegExp
		if (isReg) {
			wxRegEx regex (LookFor,regFlags);
			if (regex.IsValid()) {
				if (regex.Matches(Text->Mid(tempPos))) {
					size_t match_start;
					regex.GetMatch(&match_start,&matchLen,0);
					pos = match_start + tempPos;
					//matchLen++;
					found = true;
				}
			}
		}

		// Normal
		else {
			wxString src = Text->Mid(tempPos);
			if (!matchCase) src.MakeLower();
			pos = src.Find(LookFor);
			if (pos != -1) {
				pos += tempPos;
				found = true;
				matchLen = LookFor.Length();
			}
		}

		// Didn't find, go to next line
		if (!found) {
			curLine++;
			pos = 0;
			matchLen = 0;
			replaceLen = 0;
			if (curLine == nrows) curLine = 0;
			if (curLine == start) break;
		}
	}

	// Found
	if (found) {
		grid->BeginBatch();

		// If replacing
		if (DoReplace) {
			// Replace with regular expressions
			if (isReg) {
				wxString toReplace = Text->Mid(pos,matchLen);
				wxRegEx regex(LookFor,regFlags);
				regex.ReplaceFirst(&toReplace,ReplaceWith);
				*Text = Text->Left(pos) + toReplace + Text->Mid(pos+matchLen);
				replaceLen = toReplace.Length();
			}

			// Normal replace
			else {
				*Text = Text->Left(pos) + ReplaceWith + Text->Mid(pos+matchLen);
				replaceLen = ReplaceWith.Length();
			}

			// Update
			AssDialogue *cur = grid->GetDialogue(curLine);
			//cur->ParseASSTags();
			cur->UpdateData();

			// Commit
			grid->ass->FlagAsModified();
		}

		else {
			replaceLen = matchLen;
		}

		// Select
		grid->SelectRow(curLine,false);
		grid->MakeCellVisible(curLine,0);
		if (field == 0) {
			grid->editBox->SetToLine(curLine);
			grid->editBox->TextEdit->SetSelectionU(pos,pos+replaceLen);
		}
		grid->EndBatch();

		// Update video
		if (updateVideo) {
			grid->CommitChanges();
			grid->SetVideoToSubs(true);
		}
		else if (DoReplace) Modified = true;

		// hAx to prevent double match on style/actor
		if (field != 0) replaceLen = 99999;
	}
	LastWasFind = !DoReplace;
}
コード例 #12
0
/// @brief Actually process subtitles
///
void DialogTimingProcessor::Process() {
    SortDialogues();
    int rows = Sorted.size();

    // Options
    long inVal = 0;
    long outVal = 0;
    leadIn->GetValue().ToLong(&inVal);
    leadOut->GetValue().ToLong(&outVal);
    bool addIn = hasLeadIn->IsChecked() && inVal;
    bool addOut = hasLeadOut->IsChecked() && outVal;

    // Add lead-in/out
    if (addIn || addOut) {
        for (int i=0; i<rows; i++) {
            AssDialogue *cur = Sorted[i];

            // Compare to every previous line (yay for O(n^2)!) to see if it's OK to add lead-in
            if (inVal) {
                int startLead = cur->Start.GetMS() - inVal;
                for (int j=0; j<i; j++) {
                    AssDialogue *comp = Sorted[j];

                    // Check if they don't already collide (ignore it in that case)
                    if (cur->CollidesWith(comp)) continue;

                    // Get comparison times
                    startLead = std::max(startLead, comp->End.GetMS());
                }
                cur->Start.SetMS(startLead);
            }

            // Compare to every line to see how far can lead-out be extended
            if (outVal) {
                int endLead = cur->End.GetMS() + outVal;
                for (int j=i+1; j<rows; j++) {
                    AssDialogue *comp = Sorted[j];

                    // Check if they don't already collide (ignore it in that case)
                    if (cur->CollidesWith(comp)) continue;

                    // Get comparison times
                    endLead = std::min(endLead, comp->Start.GetMS());
                }
                cur->End.SetMS(endLead);
            }
        }
    }

    // Make adjacent
    if (adjsEnable->IsChecked()) {
        AssDialogue *prev = Sorted.front();

        long adjsThres = 0;
        adjacentThres->GetValue().ToLong(&adjsThres);

        float bias = adjacentBias->GetValue() / 100.0;

        for (int i=1; i < rows; i++) {
            AssDialogue *cur = Sorted[i];

            // Check if they don't collide
            if (cur->CollidesWith(prev)) continue;

            // Compare distance
            int curStart = cur->Start.GetMS();
            int prevEnd = prev->End.GetMS();
            int dist = curStart-prevEnd;
            if (dist > 0 && dist < adjsThres) {
                int setPos = prevEnd+int(dist*bias);
                cur->Start.SetMS(setPos);
                prev->End.SetMS(setPos);
            }

            prev = cur;
        }
    }

    // Keyframe snapping
    if (keysEnable->IsChecked()) {
        KeyFrames = c->videoController->GetKeyFrames();
        KeyFrames.push_back(c->videoController->GetLength() - 1);

        long beforeStart = 0;
        long afterStart = 0;
        long beforeEnd = 0;
        long afterEnd = 0;
        keysStartBefore->GetValue().ToLong(&beforeStart);
        keysStartAfter->GetValue().ToLong(&afterStart);
        keysEndBefore->GetValue().ToLong(&beforeEnd);
        keysEndAfter->GetValue().ToLong(&afterEnd);

        for (int i=0; i<rows; i++) {
            AssDialogue *cur = Sorted[i];

            // Get start/end frames
            int startF = c->videoController->FrameAtTime(cur->Start.GetMS(),agi::vfr::START);
            int endF = c->videoController->FrameAtTime(cur->End.GetMS(),agi::vfr::END);

            // Get closest for start
            int closest = GetClosestKeyFrame(startF);
            if ((closest > startF && closest-startF <= beforeStart) || (closest < startF && startF-closest <= afterStart)) {
                cur->Start.SetMS(c->videoController->TimeAtFrame(closest,agi::vfr::START));
            }

            // Get closest for end
            closest = GetClosestKeyFrame(endF)-1;
            if ((closest > endF && closest-endF <= beforeEnd) || (closest < endF && endF-closest <= afterEnd)) {
                cur->End.SetMS(c->videoController->TimeAtFrame(closest,agi::vfr::END));
            }
        }
    }

    // Update grid
    c->ass->Commit(_("timing processor"), AssFile::COMMIT_TIMES);
}
コード例 #13
0
/////////////
// Read file
void TXTSubtitleFormat::ReadFile(wxString filename,wxString encoding) {	using namespace std;

	// Reader
	TextFileReader file(filename,encoding,false);

	// Default
	LoadDefault(false);

	// Data
	wxString actor;
	wxString separator = Options.AsText(_T("Text actor separator"));
	wxString comment = Options.AsText(_T("Text comment starter"));
	bool isComment = false;
	int lines = 0;

	// Parse file
	AssDialogue *line = NULL;
	while (file.HasMoreLines()) {
		// Reads line
		wxString value = file.ReadLineFromFile();

		// Check if this isn't a timecodes file
		if (value.Left(10) == _T("# timecode")) {
			throw _T("File is a timecode file, cannot load as subtitles.");
		}

		// Read comment data
		isComment = false;
		if (comment != _T("") && value.Left(comment.Length()) == comment) {
			isComment = true;
			value = value.Mid(comment.Length());
		}

		// Read actor data
		if (!isComment && separator != _T("")) {
			if (value[0] != _T(' ') && value[0] != _T('\t')) {
				int pos = value.Find(separator);
				if (pos != wxNOT_FOUND) {
					actor = value.Left(pos);
					actor.Trim(false);
					actor.Trim(true);
					value = value.Mid(pos+1);
					value.Trim(false);
				}
			}
		}

		// Trim spaces at start
		value.Trim(false);

		// Sets line up
		line = new AssDialogue();
		line->group = _T("[Events]");
		line->Style = _T("Default");
		if (isComment) line->Actor = _T("");
		else line->Actor = actor;
		if (value.IsEmpty()) {
			line->Actor = _T("");
			isComment = true;
		}
		line->Comment = isComment;
		line->Text = value;
		line->StartMS = 0;
		line->Start.SetMS(0);
		line->End.SetMS(0);
		line->UpdateData();
		//line->ParseASSTags();

		// Adds line
		Line->push_back(line);
		lines++;
	}

	// No lines?
	if (lines == 0) {
		AssDialogue *line = new AssDialogue();
		line->group = _T("[Events]");
		line->Style = _T("Default");
		line->StartMS = 0;
		line->Start.SetMS(0);
		line->End.SetMS(5000);
		Line->push_back(line);
	}
}
コード例 #14
0
/////////////
// Write file
void TXTSubtitleFormat::WriteFile(wxString filename,wxString encoding) {	using namespace std;
	size_t num_actor_names = 0, num_dialogue_lines = 0;

	// Detect number of lines with Actor field filled out
	for (list<AssEntry*>::iterator l = Line->begin(); l != Line->end(); ++l) {
		AssDialogue *dia = AssEntry::GetAsDialogue(*l);
		if (dia && !dia->Comment) {
			num_dialogue_lines++;
			if (!dia->Actor.IsEmpty())
				num_actor_names++;
		}
	}

	// If too few lines have Actor filled out, don't write it
	bool write_actors = num_actor_names > num_dialogue_lines/2;
	bool strip_formatting = true;

	TextFileWriter file(filename, encoding);
	file.WriteLineToFile(_T("# Exported by Aegisub ") + GetAegisubShortVersionString());

	// Write the file
	for (list<AssEntry*>::iterator l = Line->begin(); l != Line->end(); ++l) {
		AssDialogue *dia = AssEntry::GetAsDialogue(*l);

		if (dia) {
			wxString out_line;

			if (dia->Comment) {
				out_line = _T("# ");
			}

			if (write_actors) {
				out_line += dia->Actor + _T(": ");
			}

			wxString out_text;
			if (strip_formatting) {
				dia->ParseASSTags();
				for (std::vector<AssDialogueBlock*>::iterator block = dia->Blocks.begin(); block != dia->Blocks.end(); ++block) {
					if ((*block)->type == BLOCK_PLAIN) {
						out_text += (*block)->GetText();
					}
				}
				dia->ClearBlocks();
			}
			else {
				out_text = dia->Text;
			}
			out_line += out_text;

			if (!out_text.IsEmpty()) {
				file.WriteLineToFile(out_line);
			}
		}
		else {
			// Not a dialogue line
			// TODO: should any non-dia lines cause blank lines in output?
			//file.WriteLineToFile(_T(""));
		}
	}
}
コード例 #15
0
/////////////////////////
// Replace all instances
void SearchReplaceEngine::ReplaceAll() {
	// Setup
	wxString *Text;
	int nrows = grid->GetRows();
	size_t count = 0;
	int regFlags = wxRE_ADVANCED;
	if (!matchCase) {
		if (isReg) regFlags |= wxRE_ICASE;
		//else LookFor.MakeLower();
	}
	bool replaced;
	grid->BeginBatch();

	// Selection
	bool hasSelection = false;
	wxArrayInt sels = grid->GetSelection();
	if (sels.Count() > 0) hasSelection = true;
	bool inSel = false;
	if (affect == 1) inSel = true;

	// Scan
	for (int i=0;i<nrows;i++) {
		// Check if row is selected
		if (inSel && hasSelection && sels.Index(i) == wxNOT_FOUND) {
			continue;
		}

		// Prepare
		replaced = false;
		Text = GetText(i,field);

		// Regular expressions
		if (isReg) {
			wxRegEx reg(LookFor,regFlags);
			if (reg.IsValid()) {
				size_t reps = reg.ReplaceAll(Text,ReplaceWith);
				if (reps > 0) replaced = true;
				count += reps;
			}
		}

		// Normal replace
		else {
			if (Text->Contains(LookFor)) {
				count += Text->Replace(LookFor,ReplaceWith);
				replaced = true;
			}
		}

		// Replaced?
		if (replaced) {
			AssDialogue *cur = grid->GetDialogue(i);
			cur->UpdateData();
			//cur->ParseASSTags();
		}
	}

	// Commit
	if (count > 0) {
		grid->ass->FlagAsModified();
		grid->CommitChanges();
		wxMessageBox(wxString::Format(_("%i matches were replaced."),count));
	}

	// None found
	else {
		wxMessageBox(_("No matches found."));
	}
	grid->EndBatch();
	LastWasFind = false;
}
コード例 #16
0
/////////////
// Read file
void SRTSubtitleFormat::ReadFile(wxString filename,wxString encoding) {
    using namespace std;

    // Reader
    TextFileReader file(filename,encoding);

    // Default
    LoadDefault(false);

    // Parse file
    int linen = 1;
    int fileLine = 0;
    int mode = 0;
    int lines = 0;
    long templ;
    AssDialogue *line = NULL;
    while (file.HasMoreLines()) {
        // Reads line
        wxString curLine = file.ReadLineFromFile();
        fileLine++;

        switch (mode) {
        case 0:
            // Checks if there is anything to read
            if (curLine.IsEmpty()) continue;

            // Check if it's a line number
            if (!curLine.IsNumber()) {
                Clear();
                throw wxString::Format(_T("Parse error on entry %i at line %i (expecting line number). Possible malformed file."),linen,fileLine);
            }

            // Read line number
            curLine.ToLong(&templ);
            if (templ != linen) {
                linen = templ;
            }
            line = new AssDialogue();
            mode = 1;
            break;

        case 1:
            // Read timestamps
            if (curLine.substr(13,3) != _T("-->")) {
                Clear();
                throw wxString::Format(_T("Parse error on entry %i at line %i (expecting timestamps). Possible malformed file."),linen,fileLine);
            }
            line->Start.ParseSRT(curLine.substr(0,12));
            line->End.ParseSRT(curLine.substr(17,12));
            mode = 2;
            break;

        case 2:
            // Checks if it's done
            if (curLine.IsEmpty() || !file.HasMoreLines()) {
                mode = 0;
                linen++;
                line->group = _T("[Events]");
                line->Style = _T("Default");
                line->Comment = false;
                line->UpdateData();
                line->ParseSRTTags();
                line->StartMS = line->Start.GetMS();
                Line->push_back(line);
                lines++;
                break;
            }
            // Append text
            if (line->Text != _T("")) line->Text += _T("\\N");
            line->Text += curLine;
            break;
        }
    }

    // No lines?
    if (lines == 0) {
        AssDialogue *line = new AssDialogue();
        line->group = _T("[Events]");
        line->Style = _T("Default");
        line->StartMS = 0;
        line->Start.SetMS(0);
        line->End.SetMS(5000);
        Line->push_back(line);
    }
}
コード例 #17
0
//////////////////////////////
// Actually process subtitles
void DialogTimingProcessor::Process() {
	// Sort rows
	SortDialogues();
	int rows = Sorted.size();

	// Options
	long inVal = 0;
	long outVal = 0;
	leadIn->GetValue().ToLong(&inVal);
	leadOut->GetValue().ToLong(&outVal);
	bool addIn = hasLeadIn->IsChecked() && inVal;
	bool addOut = hasLeadOut->IsChecked() && outVal;

	// Add lead-in/out
	if (addIn || addOut) {
		// Variables
		AssDialogue *cur;
		AssDialogue *comp;
		int start,end;
		int startLead,endLead;
		int compStart,compEnd;

		// For each row
		for (int i=0;i<rows;i++) {
			// Get line and check if it's OK
			cur = GetSortedDialogue(i);

			// Set variables
			start = cur->Start.GetMS();
			end = cur->End.GetMS();
			if (addIn) startLead = start - inVal;
			else startLead = start;
			if (addOut) endLead = end + outVal;
			else endLead = end;

			// Compare to every previous line (yay for O(n^2)!) to see if it's OK to add lead-in
			if (addIn) {
				for (int j=0;j<i;j++) {
					comp = GetSortedDialogue(j);

					// Check if they don't already collide (ignore it in that case)
					if (cur->CollidesWith(comp)) continue;

					// Get comparison times
					compEnd = comp->End.GetMS();

					// Limit lead-in if needed
					if (compEnd > startLead) startLead = compEnd;
				}
			}

			// Compare to every line to see how far can lead-out be extended
			if (addOut) {
				for (int j=i+1;j<rows;j++) {
					comp = GetSortedDialogue(j);

					// Check if they don't already collide (ignore it in that case)
					if (cur->CollidesWith(comp)) continue;

					// Get comparison times
					compStart = comp->Start.GetMS();

					// Limit lead-in if needed
					if (compStart < endLead) endLead = compStart;
				}
			}

			// Set times
			cur->Start.SetMS(startLead);
			cur->End.SetMS(endLead);
			cur->UpdateData();
		}
	}

	// Make adjascent
	if (adjsEnable->IsChecked()) {
		// Variables
		AssDialogue *cur;
		AssDialogue *prev = NULL;
		int curStart,prevEnd;
		long adjsThres = 0;
		int dist;

		// Get threshold
		adjascentThres->GetValue().ToLong(&adjsThres);

		// Get bias
		float bias = adjascentBias->GetValue() / 100.0;

		// For each row
		for (int i=0;i<rows;i++) {
			// Get line and check if it's OK
			cur = GetSortedDialogue(i);

			// Check if previous is OK
			if (!prev) {
				prev = cur;
				continue;
			}

			// Check if they don't collide
			if (cur->CollidesWith(prev)) continue;

			// Compare distance
			curStart = cur->Start.GetMS();
			prevEnd = prev->End.GetMS();
			dist = curStart-prevEnd;
			if (dist > 0 && dist < adjsThres) {
				int setPos = prevEnd+int(dist*bias);
				cur->Start.SetMS(setPos);
				cur->UpdateData();
				prev->End.SetMS(setPos);
				prev->UpdateData();
			}

			// Set previous
			prev = cur;
		}
	}

	// Keyframe snapping
	if (keysEnable->IsChecked()) {
		// Get keyframes
		KeyFrames = grid->video->KeyFrames;
		KeyFrames.Add(grid->video->length-1);

		// Variables
		int startF,endF;
		int closest;
		bool changed;
		AssDialogue *cur;

		// Get variables
		long beforeStart = 0;
		long afterStart = 0;
		long beforeEnd = 0;
		long afterEnd = 0;
		keysStartBefore->GetValue().ToLong(&beforeStart);
		keysStartAfter->GetValue().ToLong(&afterStart);
		keysEndBefore->GetValue().ToLong(&beforeEnd);
		keysEndAfter->GetValue().ToLong(&afterEnd);
		
		// For each row
		for (int i=0;i<rows;i++) {
			// Get line and check if it's OK
			cur = GetSortedDialogue(i);

			// Get start/end frames
			startF = VFR_Output.GetFrameAtTime(cur->Start.GetMS(),true);
			endF = VFR_Output.GetFrameAtTime(cur->End.GetMS(),false);
			changed = false;

			// Get closest for start
			closest = GetClosestKeyFrame(startF);
			if ((closest > startF && closest-startF <= beforeStart) || (closest < startF && startF-closest <= afterStart)) {
				cur->Start.SetMS(VFR_Output.GetTimeAtFrame(closest,true));
				changed = true;
			}

			// Get closest for end
			closest = GetClosestKeyFrame(endF)-1;
			if ((closest > endF && closest-endF <= beforeEnd) || (closest < endF && endF-closest <= afterEnd)) {
				cur->End.SetMS(VFR_Output.GetTimeAtFrame(closest,false));
				changed = true;
			}

			// Apply changes
			if (changed) {
				cur->UpdateData();
			}
		}
	}

	// Update grid
	grid->ass->FlagAsModified();
	grid->CommitChanges();
}