예제 #1
0
void OptionPage::OptionChoice(wxFlexGridSizer *flex, const wxString &name, const wxArrayString &choices, const char *opt_name) {
	parent->AddChangeableOption(opt_name);
	const agi::OptionValue *opt = OPT_GET(opt_name);

	wxComboBox *cb = new wxComboBox(this, -1, wxEmptyString, wxDefaultPosition, wxDefaultSize, choices, wxCB_READONLY | wxCB_DROPDOWN);
	Add(flex, name, cb);

	switch (opt->GetType()) {
		case agi::OptionValue::Type_Int: {
			int val = opt->GetInt();
			cb->Select(val < (int)choices.size() ? val : opt->GetDefaultInt());
			cb->Bind(wxEVT_COMMAND_COMBOBOX_SELECTED, IntCBUpdater(opt_name, parent));
			break;
		}
		case agi::OptionValue::Type_String: {
			wxString val(to_wx(opt->GetString()));
			if (cb->FindString(val) != wxNOT_FOUND)
				cb->SetStringSelection(val);
			else if (!choices.empty())
				cb->SetSelection(0);
			cb->Bind(wxEVT_COMMAND_COMBOBOX_SELECTED, StringUpdater(opt_name, parent));
			break;
		}

		default:
			throw PreferenceNotSupported("Unsupported type");
	}
}
예제 #2
0
void AudioBox::OnMouseWheel(wxMouseEvent &evt) {
	if (!ForwardMouseWheelEvent(audioDisplay, evt))
		return;

	bool zoom = evt.CmdDown() != OPT_GET("Audio/Wheel Default to Zoom")->GetBool();
	if (!zoom)
	{
		int amount = -evt.GetWheelRotation() * GetClientSize().GetWidth() / (evt.GetWheelDelta() * 3);
		// If the user did a horizontal scroll the amount should be inverted
		// for it to be natural.
		if (evt.GetWheelAxis() == 1) amount = -amount;

		// Reset any accumulated zoom
		mouse_zoom_accum = 0;

		audioDisplay->ScrollBy(amount);
	}
	else if (evt.GetWheelAxis() == 0)
	{
		mouse_zoom_accum += evt.GetWheelRotation();
		int zoom_delta = mouse_zoom_accum / evt.GetWheelDelta();
		mouse_zoom_accum %= evt.GetWheelDelta();
		int new_zoom = audioDisplay->GetZoomLevel() + zoom_delta;
		audioDisplay->SetZoomLevel(new_zoom);
		HorizontalZoom->SetValue(-new_zoom);
		OPT_SET("Audio/Zoom/Horizontal")->SetInt(new_zoom);
	}
}
예제 #3
0
void DialogAttachments::OnAttachFont(wxCommandEvent &) {
	wxFileDialog diag(this,
		_("Choose file to be attached"),
		to_wx(OPT_GET("Path/Fonts Collector Destination")->GetString()), "", "Font Files (*.ttf)|*.ttf",
		wxFD_OPEN | wxFD_FILE_MUST_EXIST | wxFD_MULTIPLE);

	AttachFile(diag, _("attach font file"));
}
예제 #4
0
AudioWaveformRenderer::AudioWaveformRenderer(std::string const& color_scheme_name)
: audio_buffer(0)
, render_averages(OPT_GET("Audio/Display/Waveform Style")->GetInt() == Waveform_MaxAvg)
{
	colors.reserve(AudioStyle_MAX);
	for (int i = 0; i < AudioStyle_MAX; ++i)
		colors.emplace_back(6, color_scheme_name, i);
}
예제 #5
0
VideoDisplay::VideoDisplay(wxToolBar *toolbar, bool freeSize, wxComboBox *zoomBox, wxWindow *parent, agi::Context *c)
: wxGLCanvas(parent, -1, attribList)
, autohideTools(OPT_GET("Tool/Visual/Autohide"))
, con(c)
, zoomValue(OPT_GET("Video/Default Zoom")->GetInt() * .125 + .125)
, toolBar(toolbar)
, zoomBox(zoomBox)
, freeSize(freeSize)
, retina_helper(agi::make_unique<RetinaHelper>(this))
, scale_factor(retina_helper->GetScaleFactor())
, scale_factor_connection(retina_helper->AddScaleFactorListener([=](int new_scale_factor) {
	double new_zoom = zoomValue * new_scale_factor / scale_factor;
	scale_factor = new_scale_factor;
	SetZoom(new_zoom);
}))
{
	zoomBox->SetValue(fmt_wx("%g%%", zoomValue * 100.));
	zoomBox->Bind(wxEVT_COMBOBOX, &VideoDisplay::SetZoomFromBox, this);
	zoomBox->Bind(wxEVT_TEXT_ENTER, &VideoDisplay::SetZoomFromBoxText, this);

	con->videoController->Bind(EVT_FRAME_READY, &VideoDisplay::UploadFrameData, this);
	connections = agi::signal::make_vector({
		con->project->AddVideoProviderListener(&VideoDisplay::UpdateSize, this),
		con->videoController->AddARChangeListener(&VideoDisplay::UpdateSize, this),
	});

	Bind(wxEVT_PAINT, std::bind(&VideoDisplay::Render, this));
	Bind(wxEVT_SIZE, &VideoDisplay::OnSizeEvent, this);
	Bind(wxEVT_CONTEXT_MENU, &VideoDisplay::OnContextMenu, this);
	Bind(wxEVT_ENTER_WINDOW, &VideoDisplay::OnMouseEvent, this);
	Bind(wxEVT_CHAR_HOOK, &VideoDisplay::OnKeyDown, this);
	Bind(wxEVT_LEAVE_WINDOW, &VideoDisplay::OnMouseLeave, this);
	Bind(wxEVT_LEFT_DCLICK, &VideoDisplay::OnMouseEvent, this);
	Bind(wxEVT_LEFT_DOWN, &VideoDisplay::OnMouseEvent, this);
	Bind(wxEVT_LEFT_UP, &VideoDisplay::OnMouseEvent, this);
	Bind(wxEVT_MOTION, &VideoDisplay::OnMouseEvent, this);
	Bind(wxEVT_MOUSEWHEEL, &VideoDisplay::OnMouseWheel, this);

	SetCursor(wxNullCursor);

	c->videoDisplay = this;

	con->videoController->JumpToFrame(con->videoController->GetFrameN());

	SetLayoutDirection(wxLayout_LeftToRight);
}
예제 #6
0
bool DialogSpellChecker::CheckLine(AssDialogue *active_line, int start_pos, int *commit_id) {
	if (active_line->Comment && OPT_GET("Tool/Spell Checker/Skip Comments")->GetBool()) return false;

	std::string text = active_line->Text;
	auto tokens = agi::ass::TokenizeDialogueBody(text);
	agi::ass::SplitWords(text, tokens);

	bool ignore_uppercase = OPT_GET("Tool/Spell Checker/Skip Uppercase")->GetBool();

	word_start = 0;
	for (auto const& tok : tokens) {
		if (tok.type != agi::ass::DialogueTokenType::WORD || word_start < start_pos) {
			word_start += tok.length;
			continue;
		}

		word_len = tok.length;
		std::string word = text.substr(word_start, word_len);

		if (auto_ignore.count(word) || spellchecker->CheckWord(word) || (ignore_uppercase && word == boost::locale::to_upper(word))) {
			word_start += tok.length;
			continue;
		}

		auto auto_rep = auto_replace.find(word);
		if (auto_rep == auto_replace.end()) {
#ifdef __WXGTK__
			// http://trac.wxwidgets.org/ticket/14369
			orig_word->Remove(0, -1);
			replace_word->Remove(0, -1);
#endif

			context->selectionController->SetSelectionAndActive({ active_line }, active_line);
			SetWord(word);
			return true;
		}

		text.replace(word_start, word_len, auto_rep->second);
		active_line->Text = text;
		*commit_id = context->ass->Commit(_("spell check replace"), AssFile::COMMIT_DIAG_TEXT, *commit_id);
		word_start += auto_rep->second.size();
	}
	return false;
}
예제 #7
0
AudioMarkerProviderKeyframes::AudioMarkerProviderKeyframes(agi::Context *c, const char *opt_name)
: vc(c->videoController)
, keyframe_slot(vc->AddKeyframesListener(&AudioMarkerProviderKeyframes::Update, this))
, timecode_slot(vc->AddTimecodesListener(&AudioMarkerProviderKeyframes::Update, this))
, enabled_slot(OPT_SUB(opt_name, &AudioMarkerProviderKeyframes::Update, this))
, enabled_opt(OPT_GET(opt_name))
, style(new Pen("Colour/Audio Display/Keyframe"))
{
	Update();
}
예제 #8
0
DialogPasteOver::DialogPasteOver(wxWindow *parent)
: wxDialog (parent, -1, _("Select Fields to Paste Over"))
{
	// Label and list sizer
	wxSizer *ListSizer = new wxStaticBoxSizer(wxVERTICAL, this, _("Fields"));
	ListSizer->Add(new wxStaticText(this, -1, _("Please select the fields that you want to paste over:")), wxSizerFlags());

	// List box
	wxArrayString choices;
	choices.Add(_("Layer"));
	choices.Add(_("Start Time"));
	choices.Add(_("End Time"));
	choices.Add(_("Style"));
	choices.Add(_("Actor"));
	choices.Add(_("Margin Left"));
	choices.Add(_("Margin Right"));
	choices.Add(_("Margin Vertical"));
	choices.Add(_("Effect"));
	choices.Add(_("Text"));
	ListBox = new wxCheckListBox(this, -1, wxDefaultPosition, wxDefaultSize, choices);
	ListSizer->Add(ListBox, wxSizerFlags(0).Expand().Border(wxTOP));

	std::vector<bool> options = OPT_GET("Tool/Paste Lines Over/Fields")->GetListBool();
	if (options.size() != choices.size())
		options.resize(choices.size(), false);

	for (size_t i = 0; i < choices.size(); ++i)
		ListBox->Check(i, options[i]);

	// Top buttons
	wxButton *btn;
	wxSizer *TopButtonSizer = new wxBoxSizer(wxHORIZONTAL);

	TopButtonSizer->Add(btn = new wxButton(this, -1, _("&All")), wxSizerFlags(1));
	btn->Bind(wxEVT_COMMAND_BUTTON_CLICKED, std::tr1::bind(&DialogPasteOver::CheckAll, this, true));
	TopButtonSizer->Add(btn = new wxButton(this, -1, _("&None")), wxSizerFlags(1));
	btn->Bind(wxEVT_COMMAND_BUTTON_CLICKED, std::tr1::bind(&DialogPasteOver::CheckAll, this, false));
	TopButtonSizer->Add(btn = new wxButton(this, -1, _("&Times")), wxSizerFlags(1));
	btn->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &DialogPasteOver::OnTimes, this);
	TopButtonSizer->Add(btn = new wxButton(this, -1, _("T&ext")), wxSizerFlags(1));
	btn->Bind(wxEVT_COMMAND_BUTTON_CLICKED, &DialogPasteOver::OnText, this);

	// Buttons
	wxStdDialogButtonSizer *ButtonSizer = CreateStdDialogButtonSizer(wxOK | wxCANCEL | wxHELP);
	Bind(wxEVT_COMMAND_BUTTON_CLICKED, &DialogPasteOver::OnOK, this, wxID_OK);
	Bind(wxEVT_COMMAND_BUTTON_CLICKED, std::tr1::bind(&HelpButton::OpenPage, "Paste Over"), wxID_HELP);

	// Main sizer
	wxSizer *MainSizer = new wxBoxSizer(wxVERTICAL);
	MainSizer->Add(ListSizer,0,wxEXPAND | wxLEFT | wxRIGHT,5);
	MainSizer->Add(TopButtonSizer,0,wxLEFT | wxRIGHT | wxEXPAND,5);
	MainSizer->Add(ButtonSizer,0,wxALL | wxEXPAND,5);
	SetSizerAndFit(MainSizer);
	CenterOnParent();
}
예제 #9
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::fs::FileSystemError 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(to_wx(err.GetMessage()), "Error loading audio", wxOK | wxICON_ERROR | wxCENTER);
		}
	}
}
예제 #10
0
wxThread::ExitCode AegisubVersionCheckerThread::Entry()
{
	if (!interactive)
	{
		// Automatic checking enabled?
		if (!OPT_GET("App/Auto/Check For Updates")->GetBool())
			return 0;

		// Is it actually time for a check?
		time_t next_check = OPT_GET("Version/Next Check")->GetInt();
		if (next_check > wxDateTime::GetTimeNow())
			return 0;
	}

	if (VersionCheckLock.TryLock() != wxMUTEX_NO_ERROR) return 0;

	try {
		DoCheck();
	}
	catch (const agi::Exception &e) {
		PostErrorEvent(wxString::Format(
			_("There was an error checking for updates to Aegisub:\n%s\n\nIf other applications can access the Internet fine, this is probably a temporary server problem on our end."),
			e.GetMessage()));
	}
	catch (...) {
		PostErrorEvent(_("An unknown error occurred while checking for updates to Aegisub."));
	}

	VersionCheckLock.Unlock();

	// While Options isn't perfectly thread safe, this should still be okay.
	// Traversing the std::map to find the key-value pair doesn't modify any data as long as
	// the key already exists (which it does at this point), and modifying the value only
	// touches that specific key-value pair and will never cause a rebalancing of the tree,
	// because the tree only depends on the keys.
	// Lastly, writing options to disk only happens when Options.Save() is called.
	time_t new_next_check_time = wxDateTime::GetTimeNow() + 60*60; // in one hour
	OPT_SET("Version/Next Check")->SetInt((int)new_next_check_time);

	return 0;
}
예제 #11
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);
}
예제 #12
0
AudioColorScheme::AudioColorScheme(int prec, std::string const& scheme_name, int audio_rendering_style)
: palette((3<<prec) + 3)
, factor(1<<prec)
{
	std::string opt_base = "Colour/Schemes/" + scheme_name + "/";
	switch (static_cast<AudioRenderingStyle>(audio_rendering_style))
	{
		case AudioStyle_Normal:   opt_base += "Normal/"; break;
		case AudioStyle_Inactive: opt_base += "Inactive/"; break;
		case AudioStyle_Selected: opt_base += "Selection/"; break;
		case AudioStyle_Primary:  opt_base += "Primary/"; break;
		default: throw agi::InternalError("Unknown audio rendering styling");
	}

	double h_base  = OPT_GET(opt_base + "Hue Offset")->GetDouble();
	double h_scale = OPT_GET(opt_base + "Hue Scale")->GetDouble();
	double s_base  = OPT_GET(opt_base + "Saturation Offset")->GetDouble();
	double s_scale = OPT_GET(opt_base + "Saturation Scale")->GetDouble();
	double l_base  = OPT_GET(opt_base + "Lightness Offset")->GetDouble();
	double l_scale = OPT_GET(opt_base + "Lightness Scale")->GetDouble();

	for (size_t i = 0; i <= factor; ++i)
	{
		float t = (float)i / factor;
		hsl_to_rgb(
			mid<int>(0, h_base + t * h_scale, 255),
			mid<int>(0, s_base + t * s_scale, 255),
			mid<int>(0, l_base + t * l_scale, 255),
			&palette[i * 3 + 0],
			&palette[i * 3 + 1],
			&palette[i * 3 + 2]);
	}
}
예제 #13
0
파일: project.cpp 프로젝트: Aegisub/Aegisub
void Project::LoadVideo(agi::fs::path path) {
	if (path.empty()) return;
	if (!DoLoadVideo(path)) return;
	if (OPT_GET("Video/Open Audio")->GetBool() && audio_file != video_file && video_provider->HasAudio())
		DoLoadAudio(video_file, true);

	double dar = video_provider->GetDAR();
	if (dar > 0)
		context->videoController->SetAspectRatio(dar);
	else
		context->videoController->SetAspectRatio(AspectRatio::Default);
	context->videoController->JumpToFrame(0);
}
예제 #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 SubsController::OnCommit(AssFileCommit c) {
	if (c.message.empty() && !undo_stack.empty()) return;

	static int next_commit_id = 1;

	commit_id = next_commit_id++;
	// Allow coalescing only if it's the last change and the file has not been
	// saved since the last change
	if (commit_id == *c.commit_id+1 && redo_stack.empty() && saved_commit_id+1 != commit_id && autosaved_commit_id+1 != commit_id) {
		// If only one line changed just modify it instead of copying the file
		if (c.single_line) {
			entryIter this_it = context->ass->Line.begin(), undo_it = undo_stack.back().file.Line.begin();
			while (&*this_it != c.single_line) {
				++this_it;
				++undo_it;
			}
			undo_stack.back().file.Line.insert(undo_it, *c.single_line->Clone());
			delete &*undo_it;
		}
		else
			undo_stack.back().file = *context->ass;

		*c.commit_id = commit_id;
		return;
	}

	redo_stack.clear();

	undo_stack.emplace_back(*context->ass, c.message, commit_id);

	int depth = std::max<int>(OPT_GET("Limits/Undo Levels")->GetInt(), 2);
	while ((int)undo_stack.size() > depth)
		undo_stack.pop_front();

	if (undo_stack.size() > 1 && OPT_GET("App/Auto/Save on Every Change")->GetBool() && !filename.empty() && CanSave())
		Save(filename);

	*c.commit_id = commit_id;
}
예제 #16
0
BaseGrid::BaseGrid(wxWindow* parent, agi::Context *context, const wxSize& size, long style, const wxString& name)
: wxWindow(parent, -1, wxDefaultPosition, size, style, name)
, lineHeight(1) // non-zero to avoid div by 0
, holding(false)
, scrollBar(new wxScrollBar(this, GRID_SCROLLBAR, wxDefaultPosition, wxDefaultSize, wxSB_VERTICAL))
, byFrame(false)
, extendRow(-1)
, active_line(0)
, batch_level(0)
, batch_active_line_changed(false)
, seek_listener(context->videoController->AddSeekListener(std::bind(&BaseGrid::Refresh, this, false, nullptr)))
, context_menu(0)
, yPos(0)
, context(context)
{
	scrollBar->SetScrollbar(0,10,100,10);

	wxBoxSizer *scrollbarpositioner = new wxBoxSizer(wxHORIZONTAL);
	scrollbarpositioner->AddStretchSpacer();
	scrollbarpositioner->Add(scrollBar, 0, wxEXPAND, 0);

	SetSizerAndFit(scrollbarpositioner);

	SetBackgroundStyle(wxBG_STYLE_PAINT);

	UpdateStyle();
	OnHighlightVisibleChange(*OPT_GET("Subtitle/Grid/Highlight Subtitles in Frame"));

	OPT_SUB("Subtitle/Grid/Font Face", &BaseGrid::UpdateStyle, this);
	OPT_SUB("Subtitle/Grid/Font Size", &BaseGrid::UpdateStyle, this);
	OPT_SUB("Subtitle/Grid/Highlight Subtitles in Frame", &BaseGrid::OnHighlightVisibleChange, this);
	context->ass->AddCommitListener(&BaseGrid::OnSubtitlesCommit, this);
	context->ass->AddFileOpenListener(&BaseGrid::OnSubtitlesOpen, this);
	context->ass->AddFileSaveListener(&BaseGrid::OnSubtitlesSave, this);

	OPT_SUB("Colour/Subtitle Grid/Active Border", &BaseGrid::UpdateStyle, this);
	OPT_SUB("Colour/Subtitle Grid/Background/Background", &BaseGrid::UpdateStyle, this);
	OPT_SUB("Colour/Subtitle Grid/Background/Comment", &BaseGrid::UpdateStyle, this);
	OPT_SUB("Colour/Subtitle Grid/Background/Inframe", &BaseGrid::UpdateStyle, this);
	OPT_SUB("Colour/Subtitle Grid/Background/Selected Comment", &BaseGrid::UpdateStyle, this);
	OPT_SUB("Colour/Subtitle Grid/Background/Selection", &BaseGrid::UpdateStyle, this);
	OPT_SUB("Colour/Subtitle Grid/Collision", &BaseGrid::UpdateStyle, this);
	OPT_SUB("Colour/Subtitle Grid/Header", &BaseGrid::UpdateStyle, this);
	OPT_SUB("Colour/Subtitle Grid/Left Column", &BaseGrid::UpdateStyle, this);
	OPT_SUB("Colour/Subtitle Grid/Lines", &BaseGrid::UpdateStyle, this);
	OPT_SUB("Colour/Subtitle Grid/Selection", &BaseGrid::UpdateStyle, this);
	OPT_SUB("Colour/Subtitle Grid/Standard", &BaseGrid::UpdateStyle, this);
	OPT_SUB("Subtitle/Grid/Hide Overrides", std::bind(&BaseGrid::Refresh, this, false, nullptr));

	Bind(wxEVT_CONTEXT_MENU, &BaseGrid::OnContextMenu, this);
}
예제 #17
0
void AudioDisplay::ReloadRenderingSettings()
{
	std::string colour_scheme_name;

	if (OPT_GET("Audio/Spectrum")->GetBool())
	{
		colour_scheme_name = OPT_GET("Colour/Audio Display/Spectrum")->GetString();
		AudioSpectrumRenderer *audio_spectrum_renderer = new AudioSpectrumRenderer(colour_scheme_name);

		int64_t spectrum_quality = OPT_GET("Audio/Renderer/Spectrum/Quality")->GetInt();
#ifdef WITH_FFTW3
		// FFTW is so fast we can afford to upgrade quality by two levels
		spectrum_quality += 2;
#endif
		spectrum_quality = mid<int64_t>(0, spectrum_quality, 5);

		// Quality indexes:        0  1  2  3   4   5
		int spectrum_width[]    = {8, 9, 9, 9, 10, 11};
		int spectrum_distance[] = {8, 8, 7, 6,  6,  5};

		audio_spectrum_renderer->SetResolution(
			spectrum_width[spectrum_quality],
			spectrum_distance[spectrum_quality]);

		audio_renderer_provider.reset(audio_spectrum_renderer);
	}
	else
	{
		colour_scheme_name = OPT_GET("Colour/Audio Display/Waveform")->GetString();
		audio_renderer_provider.reset(new AudioWaveformRenderer(colour_scheme_name));
	}

	audio_renderer->SetRenderer(audio_renderer_provider.get());
	scrollbar->SetColourScheme(colour_scheme_name);
	timeline->SetColourScheme(colour_scheme_name);

	Refresh();
}
예제 #18
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"));
		}
	}
}
예제 #19
0
FFMS_IndexErrorHandling FFmpegSourceProvider::GetErrorHandlingMode() {
	std::string Mode = OPT_GET("Provider/Audio/FFmpegSource/Decode Error Handling")->GetString();

	if (boost::iequals(Mode, "ignore"))
		return FFMS_IEH_IGNORE;
	else if (boost::iequals(Mode, "clear"))
		return FFMS_IEH_CLEAR_TRACK;
	else if (boost::iequals(Mode, "stop"))
		return FFMS_IEH_STOP_TRACK;
	else if (boost::iequals(Mode, "abort"))
		return FFMS_IEH_ABORT;
	else
		return FFMS_IEH_STOP_TRACK; // questionable default?
}
예제 #20
0
/// @brief Get provider
/// @param video
/// @return
///
VideoProvider *VideoProviderFactory::GetProvider(wxString video) {
	std::vector<std::string> list = GetClasses(OPT_GET("Video/Provider")->GetString());
	if (video.StartsWith("?dummy")) list.insert(list.begin(), "Dummy");
	list.insert(list.begin(), "YUV4MPEG");

	bool fileFound = false;
	bool fileSupported = false;
	std::string errors;
	errors.reserve(1024);
	for (auto const& factory : list) {
		std::string err;
		try {
			VideoProvider *provider = Create(factory, video);
			LOG_I("manager/video/provider") << factory << ": opened " << from_wx(video);
			if (provider->WantsCaching()) {
				return new VideoProviderCache(provider);
			}
			return provider;
		}
		catch (agi::FileNotFoundError const&) {
			err = factory + ": file not found.";
			// Keep trying other providers as this one may just not be able to
			// open a valid path
		}
		catch (VideoNotSupported const&) {
			fileFound = true;
			err = factory + ": video is not in a supported format.";
		}
		catch (VideoOpenError const& ex) {
			fileSupported = true;
			err = factory + ": " + ex.GetMessage();
		}
		catch (agi::vfr::Error const& ex) {
			fileSupported = true;
			err = factory + ": " + ex.GetMessage();
		}
		errors += err;
		errors += "\n";
		LOG_D("manager/video/provider") << err;
	}

	// No provider could open the file
	LOG_E("manager/video/provider") << "Could not open " << from_wx(video);
	std::string msg = "Could not open " + from_wx(video) + ":\n" + errors;

	if (!fileFound) throw agi::FileNotFoundError(from_wx(video));
	if (!fileSupported) throw VideoNotSupported(msg);
	throw VideoOpenError(msg);
}
예제 #21
0
std::unique_ptr<AudioPlayer> AudioPlayerFactory::GetAudioPlayer(AudioProvider *provider) {
	std::vector<std::string> list = GetClasses(OPT_GET("Audio/Player")->GetString());
	if (list.empty()) throw agi::NoAudioPlayersError("No audio players are available.", 0);

	std::string error;
	for (auto const& factory_name : list) {
		try {
			return Create(factory_name, provider);
		}
		catch (agi::AudioPlayerOpenError const& err) {
			error += factory_name + " factory: " + err.GetChainedMessage() + "\n";
		}
	}
	throw agi::AudioPlayerOpenError(error, 0);
}
예제 #22
0
std::unique_ptr<agi::SpellChecker> SpellCheckerFactory::GetSpellChecker() {
	std::vector<std::string> list = GetClasses(OPT_GET("Tool/Spell Checker/Backend")->GetString());
	if (list.empty()) return nullptr;

	std::string error;
	for (auto const& name : list) {
		try {
			auto checker = Create(name);
			if (checker) return checker;
		}
		catch (...) { error += name + " factory: Unknown error\n"; }
	}

	throw error;
}
예제 #23
0
void OptionPage::OptionFont(wxSizer *sizer, std::string opt_prefix) {
	const agi::OptionValue *face_opt = OPT_GET(opt_prefix + "Font Face");
	const agi::OptionValue *size_opt = OPT_GET(opt_prefix + "Font Size");

	parent->AddChangeableOption(face_opt->GetName());
	parent->AddChangeableOption(size_opt->GetName());

	wxTextCtrl *font_name = new wxTextCtrl(this, -1, face_opt->GetString());
	font_name->SetMinSize(wxSize(160, -1));
	font_name->Bind(wxEVT_COMMAND_TEXT_UPDATED, StringUpdater(face_opt->GetName().c_str(), parent));

	wxSpinCtrl *font_size = new wxSpinCtrl(this, -1, wxString::Format("%d", (int)size_opt->GetInt()), wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 3, 42, size_opt->GetInt());
	font_size->Bind(wxEVT_COMMAND_SPINCTRL_UPDATED, IntUpdater(size_opt->GetName().c_str(), parent));

	wxButton *pick_btn = new wxButton(this, -1, _("Choose..."));
	pick_btn->Bind(wxEVT_COMMAND_BUTTON_CLICKED, std::bind(font_button, parent, font_name, font_size));

	wxSizer *button_sizer = new wxBoxSizer(wxHORIZONTAL);
	button_sizer->Add(font_name, wxSizerFlags(1).Expand());
	button_sizer->Add(pick_btn, wxSizerFlags().Expand());

	Add(sizer, _("Font Face"), button_sizer);
	Add(sizer, _("Font Size"), font_size);
}
예제 #24
0
void OptionPage::OptionFont(wxSizer *sizer, std::string opt_prefix) {
	const auto face_opt = OPT_GET(opt_prefix + "Font Face");
	const auto size_opt = OPT_GET(opt_prefix + "Font Size");

	parent->AddChangeableOption(face_opt->GetName());
	parent->AddChangeableOption(size_opt->GetName());

	auto font_name = new wxTextCtrl(this, -1, to_wx(face_opt->GetString()));
	font_name->SetMinSize(wxSize(160, -1));
	font_name->Bind(wxEVT_TEXT, StringUpdater(face_opt->GetName().c_str(), parent));

	auto font_size = new wxSpinCtrl(this, -1, std::to_wstring((int)size_opt->GetInt()), wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 3, 42, size_opt->GetInt());
	font_size->Bind(wxEVT_SPINCTRL, IntUpdater(size_opt->GetName().c_str(), parent));

	auto pick_btn = new wxButton(this, -1, _("Choose..."));
	pick_btn->Bind(wxEVT_BUTTON, std::bind(font_button, parent, font_name, font_size));

	auto button_sizer = new wxBoxSizer(wxHORIZONTAL);
	button_sizer->Add(font_name, wxSizerFlags(1).Expand());
	button_sizer->Add(pick_btn, wxSizerFlags().Expand());

	Add(sizer, _("Font Face"), button_sizer);
	Add(sizer, _("Font Size"), font_size);
}
예제 #25
0
void AssFile::LoadDefault(bool include_dialogue_line, std::string const& style_catalog) {
	Info.emplace_back("Title", "Default Aegisub file");
	Info.emplace_back("ScriptType", "v4.00+");
	Info.emplace_back("WrapStyle", "0");
	Info.emplace_back("ScaledBorderAndShadow", "yes");
	if (!OPT_GET("Subtitle/Default Resolution/Auto")->GetBool()) {
		Info.emplace_back("PlayResX", std::to_string(OPT_GET("Subtitle/Default Resolution/Width")->GetInt()));
		Info.emplace_back("PlayResY", std::to_string(OPT_GET("Subtitle/Default Resolution/Height")->GetInt()));
	}
	Info.emplace_back("YCbCr Matrix", "None");

	// Add default style
	Styles.push_back(*new AssStyle);

	// Add/replace any catalog styles requested
	if (AssStyleStorage::CatalogExists(style_catalog)) {
		AssStyleStorage catalog;
		catalog.LoadCatalog(style_catalog);
		catalog.ReplaceIntoFile(*this);
	}

	if (include_dialogue_line)
		Events.push_back(*new AssDialogue);
}
예제 #26
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();
}
예제 #27
0
/// @brief Get player 
/// @return 
///
AudioPlayer* AudioPlayerFactory::GetAudioPlayer() {
	std::vector<std::string> list = GetClasses(OPT_GET("Audio/Player")->GetString());
	if (list.empty()) throw _T("No audio players are available.");

	wxString error;
	for (unsigned int i=0;i<list.size();i++) {
		try {
			AudioPlayer *player = Create(list[i]);
			if (player) return player;
		}
		catch (wxString err) { error += list[i] + _T(" factory: ") + err + _T("\n"); }
		catch (const wxChar *err) { error += list[i] + _T(" factory: ") + wxString(err) + _T("\n"); }
		catch (...) { error += list[i] + _T(" factory: Unknown error\n"); }
	}
	throw error;
}
예제 #28
0
std::unique_ptr<VideoProvider> VideoProviderFactory::GetProvider(agi::fs::path const& filename, std::string const& colormatrix, agi::BackgroundRunner *br) {
	auto preferred = OPT_GET("Video/Provider")->GetString();
	auto sorted = GetSorted(boost::make_iterator_range(std::begin(providers), std::end(providers)), preferred);

	bool found = false;
	bool supported = false;
	std::string errors;
	errors.reserve(1024);

	for (auto factory : sorted) {
		std::string err;
		try {
			auto provider = factory->create(filename, colormatrix, br);
			if (!provider) continue;
			LOG_I("manager/video/provider") << factory->name << ": opened " << filename;
			return provider->WantsCaching() ? CreateCacheVideoProvider(std::move(provider)) : std::move(provider);
		}
		catch (agi::fs::FileNotFound const&) {
			err = "file not found.";
			// Keep trying other providers as this one may just not be able to
			// open a valid path
		}
		catch (VideoNotSupported const&) {
			found = true;
			err = "video is not in a supported format.";
		}
		catch (VideoOpenError const& ex) {
			supported = true;
			err = ex.GetMessage();
		}
		catch (agi::vfr::Error const& ex) {
			supported = true;
			err = ex.GetMessage();
		}

		errors += std::string(factory->name) + ": " + err + "\n";
		LOG_D("manager/video/provider") << factory->name << ": " << err;
	}

	// No provider could open the file
	LOG_E("manager/video/provider") << "Could not open " << filename;
	std::string msg = "Could not open " + filename.string() + ":\n" + errors;

	if (!found) throw agi::fs::FileNotFound(filename.string());
	if (!supported) throw VideoNotSupported(msg);
	throw VideoOpenError(msg);
}
예제 #29
0
std::unique_ptr<VideoProvider> VideoProviderFactory::GetProvider(agi::fs::path const& video_file, std::string const& colormatrix) {
	std::vector<std::string> factories = GetClasses(OPT_GET("Video/Provider")->GetString());
	factories.insert(factories.begin(), "YUV4MPEG");
	factories.insert(factories.begin(), "Dummy");

	bool found = false;
	bool supported = false;
	std::string errors;
	errors.reserve(1024);

	for (auto const& factory : factories) {
		std::string err;
		try {
			auto provider = Create(factory, video_file, colormatrix);
			LOG_I("manager/video/provider") << factory << ": opened " << video_file;
			return provider->WantsCaching() ? agi::util::make_unique<VideoProviderCache>(std::move(provider)) : std::move(provider);
		}
		catch (agi::fs::FileNotFound const&) {
			err = "file not found.";
			// Keep trying other providers as this one may just not be able to
			// open a valid path
		}
		catch (VideoNotSupported const&) {
			found = true;
			err = "video is not in a supported format.";
		}
		catch (VideoOpenError const& ex) {
			supported = true;
			err = ex.GetMessage();
		}
		catch (agi::vfr::Error const& ex) {
			supported = true;
			err = ex.GetMessage();
		}

		errors += factory + ": " + err + "\n";
		LOG_D("manager/video/provider") << factory << ": " << err;
	}

	// No provider could open the file
	LOG_E("manager/video/provider") << "Could not open " << video_file;
	std::string msg = "Could not open " + video_file.string() + ":\n" + errors;

	if (!found) throw agi::fs::FileNotFound(video_file.string());
	if (!supported) throw VideoNotSupported(msg);
	throw VideoOpenError(msg);
}
예제 #30
0
std::unique_ptr<SubtitlesProvider> SubtitlesProviderFactory::GetProvider(agi::BackgroundRunner *br) {
	auto preferred = OPT_GET("Subtitle/Provider")->GetString();
	auto sorted = GetSorted(factories(), preferred);

	std::string error;
	for (auto factory : sorted) {
		try {
			auto provider = factory->create(factory->subtype, br);
			if (provider) return provider;
		}
		catch (agi::UserCancelException const&) { throw; }
		catch (agi::Exception const& err) { error += factory->name + ": " + err.GetMessage() + "\n"; }
		catch (...) { error += factory->name + ": Unknown error\n"; }
	}

	throw error;
}