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); } }
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"]); }
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; } }
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))); }
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")); }
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); }
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); }
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(); }
/// @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")); } } }
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."); }
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 }
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; }
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); } } }
/// @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; }
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(); }
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); }
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); }
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)); }
void DialogShiftTimes::OnClear(wxCommandEvent &) { wxRemoveFile(lagi_wxString(history_filename)); history_box->Clear(); history->clear(); }
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; }
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(); }
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); } }
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())); }
void VideoContext::OnSubtitlesError(SubtitlesProviderErrorEvent const& err) { wxLogError( "Failed rendering subtitles. Error message reported: %s", lagi_wxString(err.GetMessage())); }