예제 #1
0
void DialogAttachments::OnExtract(wxCommandEvent &) {
	int i = listView->GetFirstSelected();
	if (i == -1) return;

	wxString path;
	bool fullPath = false;

	// Multiple or single?
	if (listView->GetNextSelected(i) != -1)
		path = wxDirSelector(_("Select the path to save the files to:"),lagi_wxString(OPT_GET("Path/Fonts Collector Destination")->GetString())) + "/";
	else {
		// Default path
		wxString defPath = ((AssAttachment*)wxUIntToPtr(listView->GetItemData(i)))->GetFileName();
		path = wxFileSelector(
			_("Select the path to save the file to:"),
			lagi_wxString(OPT_GET("Path/Fonts Collector Destination")->GetString()),
			defPath,
			".ttf",
			"Font Files (*.ttf)|*.ttf",
			wxFD_SAVE | wxFD_OVERWRITE_PROMPT,
			this);
		fullPath = true;
	}
	if (!path) return;

	// Loop through items in list
	while (i != -1) {
		AssAttachment *attach = (AssAttachment*)wxUIntToPtr(listView->GetItemData(i));
		attach->Extract(fullPath ? path : path + attach->GetFileName());
		i = listView->GetNextSelected(i);
	}
}
예제 #2
0
void DialogShiftTimes::OnHistoryClick(wxCommandEvent &evt) {
	size_t entry = evt.GetInt();
	if (entry >= history->size()) return;

	json::Object& obj = (*history)[entry];
	if (obj["is by time"]) {
		shift_time->SetTime(AssTime(lagi_wxString(obj["amount"])));
		shift_by_time->SetValue(true);
		OnByTime(evt);
	}
	else {
		shift_frames->SetValue(lagi_wxString(obj["amount"]));
		if (shift_by_frames->IsEnabled()) {
			shift_by_frames->SetValue(true);
			OnByFrames(evt);
		}
	}

	if (obj["is backward"])
		shift_backward->SetValue(true);
	else
		shift_forward->SetValue(true);

	selection_mode->SetSelection((int64_t)obj["mode"]);
	time_fields->SetSelection((int64_t)obj["fields"]);
}
예제 #3
0
void FrameMain::LoadSubtitles(wxString const& filename, wxString const& charset) {
	if (context->ass->loaded) {
		if (TryToCloseSubs() == wxCANCEL) return;
	}

	try {
		// Make sure that file isn't actually a timecode file
		try {
			TextFileReader testSubs(filename, charset);
			wxString cur = testSubs.ReadLineFromFile();
			if (cur.Left(10) == "# timecode") {
				context->videoController->LoadTimecodes(filename);
				return;
			}
		}
		catch (...) {
			// if trying to load the file as timecodes fails it's fairly
			// safe to assume that it is in fact not a timecode file
		}

		context->ass->Load(filename, charset);

		wxFileName file(filename);
		StandardPaths::SetPathValue("?script", file.GetPath());
		config::mru->Add("Subtitle", STD_STR(filename));
		OPT_SET("Path/Last/Subtitles")->SetString(STD_STR(file.GetPath()));

		// Save backup of file
		if (context->ass->CanSave() && OPT_GET("App/Auto/Backup")->GetBool()) {
			if (file.FileExists()) {
				wxString path = lagi_wxString(OPT_GET("Path/Auto/Backup")->GetString());
				if (path.empty()) path = file.GetPath();
				wxFileName dstpath(StandardPaths::DecodePath(path + "/"));
				if (!dstpath.DirExists())
					wxMkdir(dstpath.GetPath());

				dstpath.SetFullName(file.GetName() + ".ORIGINAL." + file.GetExt());

				wxCopyFile(file.GetFullPath(), dstpath.GetFullPath(), true);
			}
		}
	}
	catch (agi::FileNotFoundError const&) {
		wxMessageBox(filename + " not found.", "Error", wxOK | wxICON_ERROR | wxCENTER, this);
		config::mru->Remove("Subtitle", STD_STR(filename));
		return;
	}
	catch (agi::Exception const& err) {
		wxMessageBox(lagi_wxString(err.GetChainedMessage()), "Error", wxOK | wxICON_ERROR | wxCENTER, this);
	}
	catch (...) {
		wxMessageBox("Unknown error", "Error", wxOK | wxICON_ERROR | wxCENTER, this);
		return;
	}
}
예제 #4
0
void Thesaurus::OnLanguageChanged() {
	impl.reset();

	std::string language = OPT_GET("Tool/Thesaurus/Language")->GetString();
	if (language.empty()) return;

	wxString path = StandardPaths::DecodePath(lagi_wxString(OPT_GET("Path/Dictionary")->GetString()) + "/");

	// Get index and data paths
	wxString idxpath = wxString::Format("%s/th_%s.idx", path, language);
	wxString datpath = wxString::Format("%s/th_%s.dat", path, language);

	// If they aren't in the user dictionary path, check the application directory
	if (!wxFileExists(idxpath) || !wxFileExists(datpath)) {
		path = StandardPaths::DecodePath("?data/dictionaries/");
		idxpath = wxString::Format("%s/th_%s.idx", path, language);
		datpath = wxString::Format("%s/th_%s.dat", path, language);

		if (!wxFileExists(idxpath) || !wxFileExists(datpath)) return;
	}

	LOG_I("thesaurus/file") << "Using thesaurus: " << datpath.c_str();

	impl.reset(new agi::Thesaurus(STD_STR(datpath), STD_STR(idxpath)));
}
예제 #5
0
void DialogAttachments::OnAttachFont(wxCommandEvent &) {
	wxFileDialog diag(this,
		_("Choose file to be attached"),
		lagi_wxString(OPT_GET("Path/Fonts Collector Destination")->GetString()), "", "Font Files (*.ttf)|*.ttf",
		wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_MULTIPLE);

	AttachFile(diag, ENTRY_FONT, _("attach font file"));
}
예제 #6
0
static wxString get_history_string(json::Object &obj) {
	wxString filename = lagi_wxString(obj["filename"]);
	if (filename.empty())
		filename = _("unsaved");

	wxString shift_amount(lagi_wxString(obj["amount"]));
	if (!obj["is by time"])
		shift_amount = wxString::Format(_("%s frames"), shift_amount);

	wxString shift_direction = obj["is backward"] ? _("backward") : _("forward");

	int64_t time_field = obj["fields"];
	wxString fields =
		time_field == 0 ? _("s+e") :
		time_field == 1 ? _("s")   :
		                  _("e")   ;

	json::Array const& sel = obj["selection"];
	wxString lines;

	int64_t sel_mode = obj["mode"];
	if (sel_mode == 0)
		lines = _("all");
	else if (sel_mode == 2)
		lines = wxString::Format(_("from %d onward"), (int)(int64_t)sel.front()["start"]);
	else {
		lines += _("sel ");
		for (json::Array::const_iterator it = sel.begin(); it != sel.end(); ++it) {
			int beg = (int64_t)(*it)["start"];
			int end = (int64_t)(*it)["end"];
			if (beg == end)
				lines += wxString::Format("%d", beg);
			else
				lines += wxString::Format("%d-%d", beg, end);
			if (it + 1 != sel.end())
				lines += ";";
		}
	}

	return wxString::Format("%s, %s %s, %s, %s", filename, shift_amount, shift_direction, fields, lines);
}
예제 #7
0
DialogTextImport::DialogTextImport()
: wxDialog(nullptr , -1, _("Text import options"))
{
	// Main controls
	wxFlexGridSizer *fg = new wxFlexGridSizer(2, 5, 5);
	wxBoxSizer *main_sizer = new wxBoxSizer(wxVERTICAL);
	edit_separator = new wxTextCtrl(this, -1, lagi_wxString(OPT_GET("Tool/Import/Text/Actor Separator")->GetString()));
	edit_comment = new wxTextCtrl(this, -1, lagi_wxString(OPT_GET("Tool/Import/Text/Comment Starter")->GetString()));

	// Dialog layout
	fg->Add(new wxStaticText(this, -1, _("Actor separator:")), 0, wxALIGN_CENTRE_VERTICAL);
	fg->Add(edit_separator, 0, wxEXPAND);
	fg->Add(new wxStaticText(this, -1, _("Comment starter:")), 0, wxALIGN_CENTRE_VERTICAL);
	fg->Add(edit_comment, 0, wxEXPAND);

	main_sizer->Add(fg, 1, wxALL|wxEXPAND, 5);
	main_sizer->Add(CreateSeparatedButtonSizer(wxOK|wxCANCEL), 0, wxALL|wxEXPAND, 5);
	SetSizerAndFit(main_sizer);

	Bind(wxEVT_COMMAND_BUTTON_CLICKED, &DialogTextImport::OnOK, this, wxID_OK);
}
예제 #8
0
	void GetMenuBar(std::string const& name, wxFrame *window, agi::Context *c) {
		menu_items const& items = get_menu(name);

		std::auto_ptr<CommandMenuBar> menu(new CommandMenuBar(c));
		for (menu_items::const_iterator it = items.begin(); it != items.end(); ++it) {
			std::string submenu, disp;
			read_entry(*it, "submenu", &submenu);
			read_entry(*it, "text", &disp);
			if (!submenu.empty()) {
				menu->Append(build_menu(submenu, c, &menu->cm), _(lagi_wxString(disp)));
			}
			else {
				read_entry(*it, "special", &submenu);
				if (submenu == "automation")
					menu->Append(new AutomationMenu(c, &menu->cm), _(lagi_wxString(disp)));
			}
		}

		window->Bind(wxEVT_MENU_OPEN, &CommandManager::OnMenuOpen, &menu->cm);
		window->Bind(wxEVT_COMMAND_MENU_SELECTED, &CommandManager::OnMenuClick, &menu->cm);
		window->SetMenuBar(menu.get());

#ifdef __WXGTK__
		// GTK silently swallows keypresses for accelerators whose associated
		// menu items are disabled. As we don't update the menu until it's
		// opened, this means that conditional hotkeys don't work if the menu
		// hasn't been opened since they became valid.
		//
		// To work around this, we completely disable accelerators from menu
		// item. wxGTK doesn't expose any way to do this other that at wx
		// compile time (SetAcceleratorTable is a no-op), so have some fun with
		// the implementation details of undocumented methods. Detaching via
		// wxMenuBar::Detach removes the accelerator table, and then
		// wxMenuBarBase::Attch is used to avoid readding it.
		menu->Detach();
		menu->wxMenuBarBase::Attach(window);
#endif

		menu.release();
	}
예제 #9
0
/// @brief DOCME
/// @param evt 
///
void DialogAutomation::OnAdd(wxCommandEvent &evt)
{
	// build filename filter list
	wxString fnfilter, catchall;
	const std::vector<Automation4::ScriptFactory*> &factories = Automation4::ScriptFactory::GetFactories();
	for (int i = 0; i < (int)factories.size(); i++) {
		const Automation4::ScriptFactory *fact = factories[i];
		if (fact->GetEngineName().IsEmpty() || fact->GetFilenamePattern().IsEmpty())
			continue;
		fnfilter = wxString::Format(_T("%s%s scripts (%s)|%s|"), fnfilter.c_str(), fact->GetEngineName().c_str(), fact->GetFilenamePattern().c_str(), fact->GetFilenamePattern().c_str());
		catchall << fact->GetFilenamePattern() << _T(";");
	}
#ifdef __WINDOWS__
	fnfilter += _T("All files|*.*");
#else
	fnfilter += _T("All files|*");
#endif
	if (!catchall.IsEmpty()) {
		catchall.RemoveLast();
	}
	if (factories.size() > 1) {
		fnfilter = _T("All supported scripts|") + catchall + _T("|") + fnfilter;
	}

	wxString fname = wxFileSelector(_("Add Automation script"), lagi_wxString(OPT_GET("Path/Last/Automation")->GetString()), wxEmptyString, wxEmptyString, fnfilter, wxFD_OPEN|wxFD_FILE_MUST_EXIST, this);

	if (!fname.IsEmpty()) {

		wxFileName fnpath(fname);
		OPT_SET("Path/Last/Automation")->SetString(STD_STR(fnpath.GetPath()));

		// TODO: make sure each script is only loaded once. check in both local and global managers!!
		// it doesn't break for macros, but will for export filters, and maybe for file formats,
		// and makes for confusion in the UI anyhow

		try {
			ExtraScriptInfo ei;
			ei.script = Automation4::ScriptFactory::CreateFromFile(fname, false);
			local_manager->Add(ei.script);
			ei.is_global = false;
			AddScript(ei);
		}
		catch (const wchar_t *e) {
			wxLogError(e);
		}
		catch (...) {
			wxLogError(_T("Unknown error loading script"));
		}
	}
}
예제 #10
0
void FrameMain::OnAutoSave(wxTimerEvent &) try {
	wxString fn = context->ass->AutoSave();
	if (!fn.empty())
		StatusTimeout(wxString::Format(_("File backup saved as \"%s\"."), fn));
}
catch (const agi::Exception& err) {
	StatusTimeout(lagi_wxString("Exception when attempting to autosave file: " + err.GetMessage()));
}
catch (wxString err) {
	StatusTimeout("Exception when attempting to autosave file: " + err);
}
catch (const char *err) {
	StatusTimeout("Exception when attempting to autosave file: " + wxString(err));
}
catch (...) {
	StatusTimeout("Unhandled exception when attempting to autosave file.");
}
예제 #11
0
void RestartAegisub() {
	config::opt->Flush();

#if defined(__WXMSW__)
	wxStandardPaths stand;
	wxExecute("\"" + stand.GetExecutablePath() + "\"");
#elif defined(__WXMAC__)
	std::string bundle_path = agi::util::OSX_GetBundlePath();
	std::string helper_path = agi::util::OSX_GetBundleAuxillaryExecutablePath("restart-helper");
	if (bundle_path.empty() || helper_path.empty()) return;

	wxString exec = wxString::Format("\"%s\" /usr/bin/open -n \"%s\"'", lagi_wxString(helper_path), lagi_wxString(bundle_path));
	LOG_I("util/restart/exec") << exec;
	wxExecute(exec);
#else
	wxStandardPaths stand;
	wxExecute(stand.GetExecutablePath());
#endif
}
예제 #12
0
wxArrayString Thesaurus::GetLanguageList() const {
	if (!languages.empty()) return languages;

	wxArrayString idx, dat;

	// Get list of dictionaries
	wxString path = StandardPaths::DecodePath("?data/dictionaries/");
	if (wxFileName::DirExists(path)) {
		wxDir::GetAllFiles(path, &idx, "th_*.idx", wxDIR_FILES);
		wxDir::GetAllFiles(path, &dat, "th_*.dat", wxDIR_FILES);
	}
	path = StandardPaths::DecodePath(lagi_wxString(OPT_GET("Path/Dictionary")->GetString()) + "/");
	if (wxFileName::DirExists(path)) {
		wxDir::GetAllFiles(path, &idx, "th_*.idx", wxDIR_FILES);
		wxDir::GetAllFiles(path, &dat, "th_*.dat", wxDIR_FILES);
	}
	if (idx.empty() || dat.empty()) return languages;

	idx.Sort();
	dat.Sort();

	// Drop extensions and the th_ prefix
	for (size_t i = 0; i < idx.size(); ++i) idx[i] = idx[i].Mid(3, idx[i].size() - 7);
	for (size_t i = 0; i < dat.size(); ++i) dat[i] = dat[i].Mid(3, dat[i].size() - 7);

	// Verify that each idx has a dat
	for (size_t i = 0, j = 0; i < idx.size() && j < dat.size(); ) {
		int cmp = idx[i].Cmp(dat[j]);
		if (cmp < 0) ++i;
		else if (cmp > 0) ++j;
		else {
			// Don't insert a language twice if it's in both the user dir and
			// the app's dir
			wxString name = wxFileName(dat[j]).GetName().Mid(3);
			if (languages.empty() || name != languages.back())
				languages.push_back(name);
			++i;
			++j;
		}
	}
	return languages;
}
예제 #13
0
void FrameMain::OnVideoOpen() {
	if (!context->videoController->IsLoaded()) {
		SetDisplayMode(0, -1);
		return;
	}

	Freeze();
	int vidx = context->videoController->GetWidth(),
		vidy = context->videoController->GetHeight();

	// Set zoom level based on video resolution and window size
	double zoom = context->videoDisplay->GetZoom();
	wxSize windowSize = GetSize();
	if (vidx*3*zoom > windowSize.GetX()*4 || vidy*4*zoom > windowSize.GetY()*6)
		context->videoDisplay->SetZoom(zoom * .25);
	else if (vidx*3*zoom > windowSize.GetX()*2 || vidy*4*zoom > windowSize.GetY()*3)
		context->videoDisplay->SetZoom(zoom * .5);

	SetDisplayMode(1,-1);

	if (OPT_GET("Video/Detached/Enabled")->GetBool() && !context->dialog->Get<DialogDetachedVideo>())
		cmd::call("video/detach", context.get());
	Thaw();

	if (!blockAudioLoad && OPT_GET("Video/Open Audio")->GetBool() && context->audioController->GetAudioURL() != context->videoController->GetVideoName()) {
		try {
			context->audioController->OpenAudio(context->videoController->GetVideoName());
		}
		catch (agi::UserCancelException const&) { }
		// Opening a video with no audio data isn't an error, so just log
		// and move on
		catch (agi::FileNotAccessibleError const&) {
			LOG_D("video/open/audio") << "File " << context->videoController->GetVideoName() << " found by video provider but not audio provider";
		}
		catch (agi::AudioDataNotFoundError const& e) {
			LOG_D("video/open/audio") << "File " << context->videoController->GetVideoName() << " has no audio data: " << e.GetChainedMessage();
		}
		catch (agi::AudioOpenError const& err) {
			wxMessageBox(lagi_wxString(err.GetMessage()), "Error loading audio", wxOK | wxICON_ERROR | wxCENTER);
		}
	}
}
예제 #14
0
/// @brief Read from environment
/// @param _clip
///
void AvisynthAudioProvider::LoadFromClip(AVSValue _clip) {
	AVSValue script;

	// Check if it has audio
	VideoInfo vi = _clip.AsClip()->GetVideoInfo();
	if (!vi.HasAudio()) throw agi::AudioDataNotFoundError("No audio found.", 0);

	IScriptEnvironment *env = avs_wrapper.GetEnv();

	// Convert to one channel
	char buffer[1024];
	strcpy(buffer,lagi_wxString(OPT_GET("Audio/Downmixer")->GetString()).mb_str(csConvLocal));
	script = env->Invoke(buffer, _clip);

	// Convert to 16 bits per sample
	script = env->Invoke("ConvertAudioTo16bit", script);
	vi = script.AsClip()->GetVideoInfo();

	// Convert sample rate
	int setsample = OPT_GET("Provider/Audio/AVS/Sample Rate")->GetInt();
	if (vi.SamplesPerSecond() < 32000) setsample = 44100;
	if (setsample != 0) {
		AVSValue args[2] = { script, setsample };
		script = env->Invoke("ResampleAudio", AVSValue(args,2));
	}

	// Set clip
	PClip tempclip = script.AsClip();
	vi = tempclip->GetVideoInfo();

	// Read properties
	channels = vi.AudioChannels();
	num_samples = vi.num_audio_samples;
	sample_rate = vi.SamplesPerSecond();
	bytes_per_sample = vi.BytesPerAudioSample();
	float_samples = false;

	clip = tempclip;
}
예제 #15
0
void BaseGrid::UpdateStyle() {
	wxString fontname = lagi_wxString(OPT_GET("Subtitle/Grid/Font Face")->GetString());
	if (fontname.empty()) fontname = "Tahoma";
	font.SetFaceName(fontname);
	font.SetPointSize(OPT_GET("Subtitle/Grid/Font Size")->GetInt());
	font.SetWeight(wxFONTWEIGHT_NORMAL);

	// Set line height
	{
		wxClientDC dc(this);
		dc.SetFont(font);
		int fw,fh;
		dc.GetTextExtent("#TWFfgGhH", &fw, &fh, nullptr, nullptr, &font);
		lineHeight = fh + 4;
	}

	// Set row brushes
	assert(sizeof(rowColors) / sizeof(rowColors[0]) >= COLOR_LEFT_COL);
	rowColors[COLOR_DEFAULT].SetColour(to_wx(OPT_GET("Colour/Subtitle Grid/Background/Background")->GetColor()));
	rowColors[COLOR_HEADER].SetColour(to_wx(OPT_GET("Colour/Subtitle Grid/Header")->GetColor()));
	rowColors[COLOR_SELECTION].SetColour(to_wx(OPT_GET("Colour/Subtitle Grid/Background/Selection")->GetColor()));
	rowColors[COLOR_COMMENT].SetColour(to_wx(OPT_GET("Colour/Subtitle Grid/Background/Comment")->GetColor()));
	rowColors[COLOR_VISIBLE].SetColour(to_wx(OPT_GET("Colour/Subtitle Grid/Background/Inframe")->GetColor()));
	rowColors[COLOR_SELECTED_COMMENT].SetColour(to_wx(OPT_GET("Colour/Subtitle Grid/Background/Selected Comment")->GetColor()));
	rowColors[COLOR_LEFT_COL].SetColour(to_wx(OPT_GET("Colour/Subtitle Grid/Left Column")->GetColor()));

	// Set column widths
	std::vector<bool> column_array(OPT_GET("Subtitle/Grid/Column")->GetListBool());
	assert(column_array.size() == (size_t)columns);
	for (int i = 0; i < columns; ++i) showCol[i] = column_array[i];
	SetColumnWidths();

	// Update
	AdjustScrollbar();
	Refresh();
}
예제 #16
0
void FrameMain::OnSubtitlesOpen() {
	UpdateTitle();

	/// @todo figure out how to move this to the relevant controllers without
	///       prompting for each file loaded/unloaded

	// Load stuff from the new script
	wxString curSubsVideo = DecodeRelativePath(context->ass->GetScriptInfo("Video File"), context->ass->filename);
	wxString curSubsVFR = DecodeRelativePath(context->ass->GetScriptInfo("VFR File"), context->ass->filename);
	wxString curSubsKeyframes = DecodeRelativePath(context->ass->GetScriptInfo("Keyframes File"), context->ass->filename);
	wxString curSubsAudio = DecodeRelativePath(context->ass->GetScriptInfo("Audio URI"), context->ass->filename);

	bool videoChanged = !blockVideoLoad && curSubsVideo != context->videoController->GetVideoName();
	bool timecodesChanged = curSubsVFR != context->videoController->GetTimecodesName();
	bool keyframesChanged = curSubsKeyframes != context->videoController->GetKeyFramesName();
	bool audioChanged = !blockAudioLoad && curSubsAudio != context->audioController->GetAudioURL();

	// Check if there is anything to change
	int autoLoadMode = OPT_GET("App/Auto/Load Linked Files")->GetInt();
	if (autoLoadMode == 0 || (!videoChanged && !timecodesChanged && !keyframesChanged && !audioChanged)) {
		SetDisplayMode(1, 1);
		return;
	}

	if (autoLoadMode == 2) {
		if (wxMessageBox(_("Do you want to load/unload the associated files?"), _("(Un)Load files?"), wxYES_NO | wxCENTRE, this) != wxYES) {
			SetDisplayMode(1, 1);
			return;
		}
	}

	if (audioChanged)
		blockAudioLoad = true;

	// Video
	if (videoChanged) {
		wxString arString = context->ass->GetScriptInfo("Video Aspect Ratio");
		context->videoController->SetVideo(curSubsVideo);
		if (context->videoController->IsLoaded()) {
			context->videoController->JumpToFrame(context->ass->GetScriptInfoAsInt("Video Position"));

			long videoAr = 0;
			double videoArValue = 0.;
			if (arString.StartsWith("c")) {
				videoAr = 4;
				arString.Mid(1).ToDouble(&videoArValue);
			}
			else
				arString.ToLong(&videoAr);

			context->videoController->SetAspectRatio(videoAr, videoArValue);

			double videoZoom = 0.;
			if (context->ass->GetScriptInfo("Video Zoom Percent").ToDouble(&videoZoom))
				context->videoDisplay->SetZoom(videoZoom);
		}
	}

	context->videoController->LoadTimecodes(curSubsVFR);
	context->videoController->LoadKeyframes(curSubsKeyframes);

	// Audio
	if (audioChanged) {
		blockAudioLoad = false;
		try {
			if (!curSubsAudio)
				context->audioController->CloseAudio();
			else
				context->audioController->OpenAudio(curSubsAudio);
		}
		catch (agi::UserCancelException const&) { }
		catch (agi::FileNotAccessibleError const& err) {
			config::mru->Remove("Audio", STD_STR(curSubsAudio));
			wxMessageBox(lagi_wxString(err.GetMessage()), "Error opening audio", wxOK | wxICON_ERROR | wxCENTER, this);
		}
	}

	SetDisplayMode(1, 1);
}
예제 #17
0
void VideoContext::SetVideo(const wxString &filename) {
	Reset();
	if (filename.empty()) {
		VideoOpen();
		return;
	}

	bool commit_subs = false;
	try {
		provider.reset(new ThreadedFrameSource(filename, this));
		videoProvider = provider->GetVideoProvider();
		videoFile = filename;

		// Check that the script resolution matches the video resolution
		int sx = context->ass->GetScriptInfoAsInt("PlayResX");
		int sy = context->ass->GetScriptInfoAsInt("PlayResY");
		int vx = GetWidth();
		int vy = GetHeight();

		// If the script resolution hasn't been set at all just force it to the
		// video resolution
		if (sx == 0 && sy == 0) {
			context->ass->SetScriptInfo("PlayResX", wxString::Format("%d", vx));
			context->ass->SetScriptInfo("PlayResY", wxString::Format("%d", vy));
			commit_subs = true;
		}
		// If it has been set to something other than a multiple of the video
		// resolution, ask the user if they want it to be fixed
		else if (sx % vx != 0 || sy % vy != 0) {
			switch (OPT_GET("Video/Check Script Res")->GetInt()) {
			case 1: // Ask to change on mismatch
				if (wxYES != wxMessageBox(
					wxString::Format(_("The resolution of the loaded video and the resolution specified for the subtitles don't match.\n\nVideo resolution:\t%d x %d\nScript resolution:\t%d x %d\n\nChange subtitles resolution to match video?"), vx, vy, sx, sy),
					_("Resolution mismatch"),
					wxYES_NO | wxCENTER,
					context->parent))

					break;
				// Fallthrough to case 2
			case 2: // Always change script res
				context->ass->SetScriptInfo("PlayResX", wxString::Format("%d", vx));
				context->ass->SetScriptInfo("PlayResY", wxString::Format("%d", vy));
				commit_subs = true;
				break;
			default: // Never change
				break;
			}
		}

		keyFrames = videoProvider->GetKeyFrames();

		// Set frame rate
		videoFPS = videoProvider->GetFPS();
		if (ovrFPS.IsLoaded()) {
			int ovr = wxMessageBox(_("You already have timecodes loaded. Would you like to replace them with timecodes from the video file?"), _("Replace timecodes?"), wxYES_NO | wxICON_QUESTION);
			if (ovr == wxYES) {
				ovrFPS = agi::vfr::Framerate();
				ovrTimecodeFile.clear();
			}
		}

		// Set aspect ratio
		double dar = videoProvider->GetDAR();
		if (dar > 0)
			SetAspectRatio(4, dar);

		// Set filename
		config::mru->Add("Video", STD_STR(filename));
		StandardPaths::SetPathValue("?video", wxFileName(filename).GetPath());

		// Show warning
		wxString warning = videoProvider->GetWarning();
		if (!warning.empty()) wxMessageBox(warning, "Warning", wxICON_WARNING | wxOK);

		hasSubtitles = false;
		if (filename.Right(4).Lower() == ".mkv") {
			hasSubtitles = MatroskaWrapper::HasSubtitles(filename);
		}

		provider->LoadSubtitles(context->ass);
		VideoOpen();
		KeyframesOpen(keyFrames);
		TimecodesOpen(FPS());
	}
	catch (agi::UserCancelException const&) { }
	catch (agi::FileNotAccessibleError const& err) {
		config::mru->Remove("Video", STD_STR(filename));
		wxMessageBox(lagi_wxString(err.GetMessage()), "Error setting video", wxOK | wxICON_ERROR | wxCENTER);
	}
	catch (VideoProviderError const& err) {
		wxMessageBox(lagi_wxString(err.GetMessage()), "Error setting video", wxOK | wxICON_ERROR | wxCENTER);
	}

	if (commit_subs)
		context->ass->Commit(_("change script resolution"), AssFile::COMMIT_SCRIPTINFO);
	else
		JumpToFrame(0);
}
예제 #18
0
DialogStyleEditor::DialogStyleEditor(wxWindow *parent, AssStyle *style, agi::Context *c, AssStyleStorage *store, wxString const& new_name)
: wxDialog (parent, -1, _("Style Editor"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER)
, c(c)
, is_new(false)
, style(style)
, store(store)
{
	if (new_name.size()) {
		is_new = true;
		style = this->style = new AssStyle(*style);
		style->name = new_name;
	}
	else if (!style) {
		is_new = true;
		style = this->style = new AssStyle;
	}

	work.reset(new AssStyle(*style));

	SetIcon(GETICON(style_toolbutton_16));

	// Prepare control values
	wxString EncodingValue = AegiIntegerToString(style->encoding);
	wxString alignValues[9] = { "7", "8", "9", "4", "5", "6", "1", "2", "3" };
	wxArrayString fontList = wxFontEnumerator::GetFacenames();
	fontList.Sort();

	// Encoding options
	wxArrayString encodingStrings;
	AssStyle::GetEncodings(encodingStrings);

	// Create sizers
	wxSizer *NameSizer = new wxStaticBoxSizer(wxHORIZONTAL, this, _("Style Name"));
	wxSizer *FontSizer = new wxStaticBoxSizer(wxVERTICAL, this, _("Font"));
	wxSizer *ColorsSizer = new wxStaticBoxSizer(wxHORIZONTAL, this, _("Colors"));
	wxSizer *MarginSizer = new wxStaticBoxSizer(wxHORIZONTAL, this, _("Margins"));
	wxSizer *OutlineBox = new wxStaticBoxSizer(wxHORIZONTAL, this, _("Outline"));
	wxSizer *MiscBox = new wxStaticBoxSizer(wxVERTICAL, this, _("Miscellaneous"));
	wxSizer *PreviewBox = new wxStaticBoxSizer(wxVERTICAL, this, _("Preview"));

	// Create controls
	StyleName = new wxTextCtrl(this, -1, style->name);
	FontName = new wxComboBox(this, -1, style->font, wxDefaultPosition, wxSize(150, -1), 0, 0, wxCB_DROPDOWN);
	FontSize =  num_text_ctrl(this, style->fontsize, wxSize(50, -1));
	BoxBold = new wxCheckBox(this, -1, _("&Bold"));
	BoxItalic = new wxCheckBox(this, -1, _("&Italic"));
	BoxUnderline = new wxCheckBox(this, -1, _("&Underline"));
	BoxStrikeout = new wxCheckBox(this, -1, _("&Strikeout"));
	colorButton[0] = new ColourButton(this, -1, wxSize(55, 16), style->primary);
	colorButton[1] = new ColourButton(this, -1, wxSize(55, 16), style->secondary);
	colorButton[2] = new ColourButton(this, -1, wxSize(55, 16), style->outline);
	colorButton[3] = new ColourButton(this, -1, wxSize(55, 16), style->shadow);
	colorAlpha[0] = spin_ctrl(this, style->primary.a, 255);
	colorAlpha[1] = spin_ctrl(this, style->secondary.a, 255);
	colorAlpha[2] = spin_ctrl(this, style->outline.a, 255);
	colorAlpha[3] = spin_ctrl(this, style->shadow.a, 255);
	for (int i = 0; i < 3; i++)
		margin[i] = spin_ctrl(this, style->Margin[i], 9999);
	Alignment = new wxRadioBox(this, -1, _("Alignment"), wxDefaultPosition, wxDefaultSize, 9, alignValues, 3, wxRA_SPECIFY_COLS);
	Outline = num_text_ctrl(this, style->outline_w, wxSize(50, -1));
	Shadow = num_text_ctrl(this, style->shadow_w, wxSize(50, -1));
	OutlineType = new wxCheckBox(this, -1, _("&Opaque box"));
	ScaleX = num_text_ctrl(this, style->scalex);
	ScaleY = num_text_ctrl(this, style->scaley);
	Angle = num_text_ctrl(this, style->angle);
	Spacing = num_text_ctrl(this, style->spacing);
	Encoding = new wxComboBox(this, -1, "", wxDefaultPosition, wxDefaultSize, encodingStrings, wxCB_READONLY);

	// Set control tooltips
	StyleName->SetToolTip(_("Style name"));
	FontName->SetToolTip(_("Font face"));
	FontSize->SetToolTip(_("Font size"));
	colorButton[0]->SetToolTip(_("Choose primary color"));
	colorButton[1]->SetToolTip(_("Choose secondary color"));
	colorButton[2]->SetToolTip(_("Choose outline color"));
	colorButton[3]->SetToolTip(_("Choose shadow color"));
	for (int i=0;i<4;i++) colorAlpha[i]->SetToolTip(_("Set opacity, from 0 (opaque) to 255 (transparent)"));
	margin[0]->SetToolTip(_("Distance from left edge, in pixels"));
	margin[1]->SetToolTip(_("Distance from right edge, in pixels"));
	margin[2]->SetToolTip(_("Distance from top/bottom edge, in pixels"));
	OutlineType->SetToolTip(_("When selected, display an opaque box behind the subtitles instead of an outline around the text"));
	Outline->SetToolTip(_("Outline width, in pixels"));
	Shadow->SetToolTip(_("Shadow distance, in pixels"));
	ScaleX->SetToolTip(_("Scale X, in percentage"));
	ScaleY->SetToolTip(_("Scale Y, in percentage"));
	Angle->SetToolTip(_("Angle to rotate in Z axis, in degrees"));
	Encoding->SetToolTip(_("Encoding, only useful in unicode if the font doesn't have the proper unicode mapping"));
	Spacing->SetToolTip(_("Character spacing, in pixels"));
	Alignment->SetToolTip(_("Alignment in screen, in numpad style"));

	// Set up controls
	BoxBold->SetValue(style->bold);
	BoxItalic->SetValue(style->italic);
	BoxUnderline->SetValue(style->underline);
	BoxStrikeout->SetValue(style->strikeout);
	OutlineType->SetValue(style->borderstyle == 3);
	Alignment->SetSelection(AlignToControl(style->alignment));
	// Fill font face list box
	FontName->Freeze();
	FontName->Append(fontList);
	FontName->SetValue(style->font);
	FontName->Thaw();

	// Set encoding value
	bool found = false;
	for (size_t i=0;i<encodingStrings.Count();i++) {
		if (encodingStrings[i].StartsWith(EncodingValue)) {
			Encoding->Select(i);
			found = true;
			break;
		}
	}
	if (!found) Encoding->Select(0);

	// Style name sizer
	NameSizer->Add(StyleName, 1, wxALL, 0);

	// Font sizer
	wxSizer *FontSizerTop = new wxBoxSizer(wxHORIZONTAL);
	wxSizer *FontSizerBottom = new wxBoxSizer(wxHORIZONTAL);
	FontSizerTop->Add(FontName, 1, wxALL, 0);
	FontSizerTop->Add(FontSize, 0, wxLEFT, 5);
	FontSizerBottom->AddStretchSpacer(1);
	FontSizerBottom->Add(BoxBold, 0, 0, 0);
	FontSizerBottom->Add(BoxItalic, 0, wxLEFT, 5);
	FontSizerBottom->Add(BoxUnderline, 0, wxLEFT, 5);
	FontSizerBottom->Add(BoxStrikeout, 0, wxLEFT, 5);
	FontSizerBottom->AddStretchSpacer(1);
	FontSizer->Add(FontSizerTop, 1, wxALL | wxEXPAND, 0);
	FontSizer->Add(FontSizerBottom, 1, wxTOP | wxEXPAND, 5);

	// Colors sizer
	wxSizer *ColorSizer[4];
	wxString colorLabels[] = { _("Primary"), _("Secondary"), _("Outline"), _("Shadow") };
	ColorsSizer->AddStretchSpacer(1);
	for (int i=0;i<4;i++) {
		ColorSizer[i] = new wxBoxSizer(wxVERTICAL);
		ColorSizer[i]->Add(new wxStaticText(this, -1, colorLabels[i]), 0, wxBOTTOM | wxALIGN_CENTER, 5);
		ColorSizer[i]->Add(colorButton[i], 0, wxBOTTOM | wxALIGN_CENTER, 5);
		ColorSizer[i]->Add(colorAlpha[i], 0, wxALIGN_CENTER, 0);
		ColorsSizer->Add(ColorSizer[i], 0, wxLEFT, i?5:0);
	}
	ColorsSizer->AddStretchSpacer(1);

	// Margins
	wxString marginLabels[] = { _("Left"), _("Right"), _("Vert") };
	MarginSizer->AddStretchSpacer(1);
	wxSizer *marginSubSizer[3];
	for (int i=0;i<3;i++) {
		marginSubSizer[i] = new wxBoxSizer(wxVERTICAL);
		marginSubSizer[i]->AddStretchSpacer(1);
		marginSubSizer[i]->Add(new wxStaticText(this, -1, marginLabels[i]), 0, wxCENTER, 0);
		marginSubSizer[i]->Add(margin[i], 0, wxTOP | wxCENTER, 5);
		marginSubSizer[i]->AddStretchSpacer(1);
		MarginSizer->Add(marginSubSizer[i], 0, wxEXPAND | wxLEFT, i?5:0);
	}
	MarginSizer->AddStretchSpacer(1);

	// Margins+Alignment
	wxSizer *MarginAlign = new wxBoxSizer(wxHORIZONTAL);
	MarginAlign->Add(MarginSizer, 1, wxLEFT | wxEXPAND, 0);
	MarginAlign->Add(Alignment, 0, wxLEFT | wxEXPAND, 5);

	// Outline
	add_with_label(OutlineBox, this, _("Outline:"), Outline);
	add_with_label(OutlineBox, this, _("Shadow:"), Shadow);
	OutlineBox->Add(OutlineType, 0, wxLEFT | wxALIGN_CENTER, 5);

	// Misc
	wxFlexGridSizer *MiscBoxTop = new wxFlexGridSizer(2, 4, 5, 5);
	add_with_label(MiscBoxTop, this, _("Scale X%:"), ScaleX);
	add_with_label(MiscBoxTop, this, _("Scale Y%:"), ScaleY);
	add_with_label(MiscBoxTop, this, _("Rotation:"), Angle);
	add_with_label(MiscBoxTop, this, _("Spacing:"), Spacing);

	wxSizer *MiscBoxBottom = new wxBoxSizer(wxHORIZONTAL);
	add_with_label(MiscBoxBottom, this, _("Encoding:"), Encoding);

	MiscBox->Add(MiscBoxTop, wxSizerFlags().Expand().Center());
	MiscBox->Add(MiscBoxBottom, wxSizerFlags().Expand().Center().Border(wxTOP));

	// Preview
	SubsPreview = nullptr;
	PreviewText = nullptr;
	ColourButton *previewButton = 0;
	if (!SubtitlesProviderFactory::GetClasses().empty()) {
		PreviewText = new wxTextCtrl(this, -1, lagi_wxString(OPT_GET("Tool/Style Editor/Preview Text")->GetString()));
		previewButton = new ColourButton(this, -1, wxSize(45, 16), OPT_GET("Colour/Style Editor/Background/Preview")->GetColor());
		SubsPreview = new SubtitlesPreview(this, wxSize(100, 60), wxSUNKEN_BORDER, OPT_GET("Colour/Style Editor/Background/Preview")->GetColor());

		SubsPreview->SetToolTip(_("Preview of current style"));
		SubsPreview->SetStyle(*style);
		SubsPreview->SetText(PreviewText->GetValue());
		PreviewText->SetToolTip(_("Text to be used for the preview"));
		previewButton->SetToolTip(_("Color of preview background"));

		wxSizer *PreviewBottomSizer = new wxBoxSizer(wxHORIZONTAL);
		PreviewBottomSizer->Add(PreviewText, 1, wxEXPAND | wxRIGHT, 5);
		PreviewBottomSizer->Add(previewButton, 0, wxEXPAND, 0);
		PreviewBox->Add(SubsPreview, 1, wxEXPAND | wxBOTTOM, 5);
		PreviewBox->Add(PreviewBottomSizer, 0, wxEXPAND | wxBOTTOM, 0);
	}
	else {
		wxStaticText *NoSP = new wxStaticText(this, -1, _("No subtitle providers available. Cannot preview subs."));
		PreviewBox->AddStretchSpacer();
		PreviewBox->Add(NoSP, 1, wxEXPAND|wxLEFT|wxRIGHT, 8);
		PreviewBox->AddStretchSpacer();
	}

	// Buttons
	wxStdDialogButtonSizer *ButtonSizer = CreateStdDialogButtonSizer(wxOK | wxCANCEL | wxAPPLY | wxHELP);

	// Left side sizer
	wxSizer *LeftSizer = new wxBoxSizer(wxVERTICAL);
	LeftSizer->Add(NameSizer, 0, wxBOTTOM | wxEXPAND, 5);
	LeftSizer->Add(FontSizer, 0, wxBOTTOM | wxEXPAND, 5);
	LeftSizer->Add(ColorsSizer, 0, wxBOTTOM | wxEXPAND, 5);
	LeftSizer->Add(MarginAlign, 0, wxBOTTOM | wxEXPAND, 0);

	// Right side sizer
	wxSizer *RightSizer = new wxBoxSizer(wxVERTICAL);
	RightSizer->Add(OutlineBox, wxSizerFlags().Expand().Border(wxBOTTOM));
	RightSizer->Add(MiscBox, wxSizerFlags().Expand().Border(wxBOTTOM));
	RightSizer->Add(PreviewBox, wxSizerFlags(1).Expand());

	// Controls Sizer
	wxSizer *ControlSizer = new wxBoxSizer(wxHORIZONTAL);
	ControlSizer->Add(LeftSizer, 0, wxEXPAND, 0);
	ControlSizer->Add(RightSizer, 1, wxLEFT | wxEXPAND, 5);

	// General Layout
	wxSizer *MainSizer = new wxBoxSizer(wxVERTICAL);
	MainSizer->Add(ControlSizer, 1, wxALL | wxALIGN_CENTER | wxEXPAND, 5);
	MainSizer->Add(ButtonSizer, 0, wxBOTTOM | wxEXPAND, 5);

	SetSizerAndFit(MainSizer);

	// Force the style name text field to scroll based on its final size, rather
	// than its initial size
	StyleName->SetInsertionPoint(0);
	StyleName->SetInsertionPoint(-1);

	persist.reset(new PersistLocation(this, "Tool/Style Editor", true));

	Bind(wxEVT_CHILD_FOCUS, &DialogStyleEditor::OnChildFocus, this);

	if (PreviewText) {
		Bind(wxEVT_COMMAND_CHECKBOX_CLICKED, &DialogStyleEditor::OnCommandPreviewUpdate, this);
		Bind(wxEVT_COMMAND_COMBOBOX_SELECTED, &DialogStyleEditor::OnCommandPreviewUpdate, this);
		Bind(wxEVT_COMMAND_SPINCTRL_UPDATED, &DialogStyleEditor::OnCommandPreviewUpdate, this);

		previewButton->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &DialogStyleEditor::OnPreviewColourChange, this);
		FontName->Bind(wxEVT_COMMAND_TEXT_ENTER, &DialogStyleEditor::OnCommandPreviewUpdate, this);
		PreviewText->Bind(wxEVT_COMMAND_TEXT_UPDATED, &DialogStyleEditor::OnPreviewTextChange, this);
	}

	Bind(wxEVT_COMMAND_BUTTON_CLICKED, std::bind(&DialogStyleEditor::Apply, this, true, true), wxID_OK);
	Bind(wxEVT_COMMAND_BUTTON_CLICKED, std::bind(&DialogStyleEditor::Apply, this, true, false), wxID_APPLY);
	Bind(wxEVT_COMMAND_BUTTON_CLICKED, std::bind(&DialogStyleEditor::Apply, this, false, true), wxID_CANCEL);
	Bind(wxEVT_COMMAND_BUTTON_CLICKED, std::bind(&HelpButton::OpenPage, "Style Editor"), wxID_HELP);

	for (int i = 0; i < 4; ++i)
		colorButton[i]->Bind(wxEVT_COMMAND_BUTTON_CLICKED, std::bind(&DialogStyleEditor::OnSetColor, this, i + 1, std::placeholders::_1));
}
예제 #19
0
void DialogShiftTimes::OnClear(wxCommandEvent &) {
	wxRemoveFile(lagi_wxString(history_filename));
	history_box->Clear();
	history->clear();
}
예제 #20
0
	static iterator find_command(std::string const& name) {
		iterator it = cmd_map.find(name);
		if (it == cmd_map.end())
			throw CommandNotFound(STD_STR(wxString::Format(_("'%s' is not a valid command name"), lagi_wxString(name))));
		return it;
	}
예제 #21
0
DialogSpellChecker::DialogSpellChecker(agi::Context *context)
: wxDialog(context->parent, -1, _("Spell Checker"))
, context(context)
, spellchecker(SpellCheckerFactory::GetSpellChecker())
, start_line(0)
, active_line(0)
, has_looped(false)
{
	SetIcon(GETICON(spellcheck_toolbutton_16));

	wxSizer *main_sizer = new wxBoxSizer(wxVERTICAL);

	wxFlexGridSizer *current_word_sizer = new wxFlexGridSizer(2, 5, 5);
	main_sizer->Add(current_word_sizer, wxSizerFlags().Expand().Border(wxALL, 5));

	wxSizer *bottom_sizer = new wxBoxSizer(wxHORIZONTAL);
	main_sizer->Add(bottom_sizer, wxSizerFlags().Expand().Border(~wxTOP & wxALL, 5));

	wxSizer *bottom_left_sizer = new wxBoxSizer(wxVERTICAL);
	bottom_sizer->Add(bottom_left_sizer, wxSizerFlags().Expand().Border(wxRIGHT, 5));

	wxSizer *actions_sizer = new wxBoxSizer(wxVERTICAL);
	bottom_sizer->Add(actions_sizer, wxSizerFlags().Expand());

	// Misspelled word and currently selected correction
	current_word_sizer->AddGrowableCol(1, 1);
	current_word_sizer->Add(new wxStaticText(this, -1, _("Misspelled word:")), 0, wxALIGN_CENTER_VERTICAL);
	current_word_sizer->Add(orig_word = new wxTextCtrl(this, -1, "", wxDefaultPosition, wxDefaultSize, wxTE_READONLY), wxSizerFlags(1).Expand());
	current_word_sizer->Add(new wxStaticText(this, -1, _("Replace with:")), 0, wxALIGN_CENTER_VERTICAL);
	current_word_sizer->Add(replace_word = new wxTextCtrl(this, -1, ""), wxSizerFlags(1).Expand());

	// List of suggested corrections
	suggest_list = new wxListBox(this, -1, wxDefaultPosition, wxSize(300, 150));
	suggest_list->Bind(wxEVT_COMMAND_LISTBOX_SELECTED, &DialogSpellChecker::OnChangeSuggestion, this);
	suggest_list->Bind(wxEVT_COMMAND_LISTBOX_DOUBLECLICKED, &DialogSpellChecker::OnReplace, this);
	bottom_left_sizer->Add(suggest_list, wxSizerFlags(1).Expand());

	// List of supported spellchecker languages
	{
		if (!spellchecker.get()) {
			wxMessageBox("No spellchecker available.", "Error", wxOK | wxICON_ERROR | wxCENTER);
			throw agi::UserCancelException("No spellchecker available");
		}

		dictionary_lang_codes = to_wx(spellchecker->GetLanguageList());
		if (dictionary_lang_codes.empty()) {
			wxMessageBox("No spellchecker dictionaries available.", "Error", wxOK | wxICON_ERROR | wxCENTER);
			throw agi::UserCancelException("No spellchecker dictionaries available");
		}

		wxArrayString language_names(dictionary_lang_codes);
		for (size_t i = 0; i < dictionary_lang_codes.size(); ++i) {
			if (const wxLanguageInfo *info = wxLocale::FindLanguageInfo(dictionary_lang_codes[i]))
				language_names[i] = info->Description;
		}

		language = new wxComboBox(this, -1, "", wxDefaultPosition, wxDefaultSize, language_names, wxCB_DROPDOWN | wxCB_READONLY);
		wxString cur_lang = lagi_wxString(OPT_GET("Tool/Spell Checker/Language")->GetString());
		int cur_lang_index = dictionary_lang_codes.Index(cur_lang);
		if (cur_lang_index == wxNOT_FOUND) cur_lang_index = dictionary_lang_codes.Index("en");
		if (cur_lang_index == wxNOT_FOUND) cur_lang_index = dictionary_lang_codes.Index("en_US");
		if (cur_lang_index == wxNOT_FOUND) cur_lang_index = 0;
		language->SetSelection(cur_lang_index);
		language->Bind(wxEVT_COMMAND_COMBOBOX_SELECTED, &DialogSpellChecker::OnChangeLanguage, this);

		bottom_left_sizer->Add(language, wxSizerFlags().Expand().Border(wxTOP, 5));
	}

	{
		wxSizerFlags button_flags = wxSizerFlags().Expand().Bottom().Border(wxBOTTOM, 5);

		skip_comments = new wxCheckBox(this, -1, _("&Skip Comments"));
		actions_sizer->Add(skip_comments, button_flags);
		skip_comments->SetValue(OPT_GET("Tool/Spell Checker/Skip Comments")->GetBool());
		skip_comments->Bind(wxEVT_COMMAND_CHECKBOX_CLICKED,
			[](wxCommandEvent &evt) { OPT_SET("Tool/Spell Checker/Skip Comments")->SetBool(!!evt.GetInt()); });

		wxButton *button;

		actions_sizer->Add(button = new wxButton(this, -1, _("&Replace")), button_flags);
		button->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &DialogSpellChecker::OnReplace, this);

		actions_sizer->Add(button = new wxButton(this, -1, _("Replace &all")), button_flags);
		button->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &DialogSpellChecker::OnReplaceAll, this);

		actions_sizer->Add(button = new wxButton(this, -1, _("&Ignore")), button_flags);
		button->Bind(wxEVT_COMMAND_BUTTON_CLICKED, [=](wxCommandEvent&) { FindNext(); });

		actions_sizer->Add(button = new wxButton(this, -1, _("Ignore a&ll")), button_flags);
		button->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &DialogSpellChecker::OnIgnoreAll, this);

		actions_sizer->Add(add_button = new wxButton(this, -1, _("Add to &dictionary")), button_flags);
		add_button->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &DialogSpellChecker::OnAdd, this);
		
		actions_sizer->Add(remove_button = new wxButton(this, -1, _("Remove fro&m dictionary")), button_flags);
		remove_button->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &DialogSpellChecker::OnRemove, this);

		actions_sizer->Add(new HelpButton(this, "Spell Checker"), button_flags);

		actions_sizer->Add(new wxButton(this, wxID_CANCEL), button_flags.Border(0));
	}

	SetSizerAndFit(main_sizer);
	CenterOnParent();

	if (FindNext())
		Show();
}
예제 #22
0
void BaseGrid::DrawImage(wxDC &dc, bool paint_columns[]) {
	int w = 0;
	int h = 0;
	GetClientSize(&w,&h);
	w -= scrollBar->GetSize().GetWidth();

	dc.SetFont(font);

	dc.SetBackground(rowColors[COLOR_DEFAULT]);
	dc.Clear();

	// Draw labels
	dc.SetPen(*wxTRANSPARENT_PEN);
	dc.SetBrush(rowColors[COLOR_LEFT_COL]);
	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
	wxColour text_standard(to_wx(OPT_GET("Colour/Subtitle Grid/Standard")->GetColor()));
	wxColour text_selection(to_wx(OPT_GET("Colour/Subtitle Grid/Selection")->GetColor()));
	wxColour text_collision(to_wx(OPT_GET("Colour/Subtitle Grid/Collision")->GetColor()));

	// First grid row
	wxPen grid_pen(to_wx(OPT_GET("Colour/Subtitle Grid/Lines")->GetColor()));
	dc.SetPen(grid_pen);
	dc.DrawLine(0, 0, w, 0);
	dc.SetPen(*wxTRANSPARENT_PEN);

	wxString strings[] = {
		_("#"), _("L"), _("Start"), _("End"), _("Style"), _("Actor"),
		_("Effect"), _("Left"), _("Right"), _("Vert"), _("Text")
	};

	int override_mode = OPT_GET("Subtitle/Grid/Hide Overrides")->GetInt();
	wxString replace_char;
	if (override_mode == 1)
		replace_char = lagi_wxString(OPT_GET("Subtitle/Grid/Hide Overrides Char")->GetString());

	for (int i = 0; i < nDraw + 1; i++) {
		int curRow = i + yPos - 1;
		RowColor curColor = COLOR_DEFAULT;

		// Header
		if (i == 0) {
			curColor = COLOR_HEADER;
			dc.SetTextForeground(text_standard);
		}
		// Lines
		else if (AssDialogue *curDiag = GetDialogue(curRow)) {
			GetRowStrings(curRow, curDiag, paint_columns, strings, !!override_mode, replace_char);

			bool inSel = !!selection.count(curDiag);
			if (inSel && curDiag->Comment)
				curColor = COLOR_SELECTED_COMMENT;
			else if (inSel)
				curColor = COLOR_SELECTION;
			else if (curDiag->Comment)
				curColor = COLOR_COMMENT;
			else if (OPT_GET("Subtitle/Grid/Highlight Subtitles in Frame")->GetBool() && IsDisplayed(curDiag))
				curColor = COLOR_VISIBLE;
			else
				curColor = COLOR_DEFAULT;

			if (active_line != curDiag && curDiag->CollidesWith(active_line))
				dc.SetTextForeground(text_collision);
			else if (inSel)
				dc.SetTextForeground(text_selection);
			else
				dc.SetTextForeground(text_standard);
		}
		else {
			assert(false);
		}

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

		// Draw text
		int dx = 0;
		int dy = i*lineHeight;
		for (int j = 0; j < 11; j++) {
			if (colWidth[j] == 0) continue;

			if (paint_columns[j]) {
				wxSize ext = dc.GetTextExtent(strings[j]);

				int left = dx + 4;
				int top = dy + (lineHeight - ext.GetHeight()) / 2;

				// Centered columns
				if (!(j == 4 || j == 5 || j == 6 || j == 10)) {
					left += (colWidth[j] - 6 - ext.GetWidth()) / 2;
				}

				dc.DrawText(strings[j], left, top);
			}
			dx += colWidth[j];
		}

		// Draw grid
		dc.DestroyClippingRegion();
		dc.SetPen(grid_pen);
		dc.DrawLine(0,dy+lineHeight,w,dy+lineHeight);
		dc.SetPen(*wxTRANSPARENT_PEN);
	}

	// Draw grid columns
	int dx = 0;
	dc.SetPen(grid_pen);
	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,maxH);

	// Draw currently active line border
	if (GetActiveLine()) {
		dc.SetPen(wxPen(to_wx(OPT_GET("Colour/Subtitle Grid/Active Border")->GetColor())));
		dc.SetBrush(*wxTRANSPARENT_BRUSH);
		int dy = (line_index_map[GetActiveLine()]+1-yPos) * lineHeight;
		dc.DrawRectangle(0,dy,w,lineHeight+1);
	}
}
예제 #23
0
void VideoContext::OnVideoError(VideoProviderErrorEvent const& err) {
	wxLogError(
		"Failed seeking video. The video file may be corrupt or incomplete.\n"
		"Error message reported: %s",
		lagi_wxString(err.GetMessage()));
}
예제 #24
0
void VideoContext::OnSubtitlesError(SubtitlesProviderErrorEvent const& err) {
	wxLogError(
		"Failed rendering subtitles. Error message reported: %s",
		lagi_wxString(err.GetMessage()));
}