Add pre-save signal to AssFile and move most of the logic in FrameMain::SaveSubtitles to slots for this signal
Originally committed to SVN as r5207.
This commit is contained in:
parent
59300cbc27
commit
7210ea17d8
9 changed files with 126 additions and 127 deletions
|
@ -172,34 +172,23 @@ void AssFile::Load(const wxString &_filename,wxString charset,bool addToRecent)
|
|||
FileOpen(filename);
|
||||
}
|
||||
|
||||
void AssFile::Save(wxString _filename,bool setfilename,bool addToRecent,const wxString encoding) {
|
||||
// Finds last dot
|
||||
int i = 0;
|
||||
for (i=(int)_filename.size();--i>=0;) {
|
||||
if (_filename[i] == '.') break;
|
||||
}
|
||||
wxString extension = _filename.substr(i+1);
|
||||
extension.Lower();
|
||||
void AssFile::Save(wxString filename, bool setfilename, bool addToRecent, wxString encoding) {
|
||||
SubtitleFormat *writer = SubtitleFormat::GetWriter(filename);
|
||||
if (!writer)
|
||||
throw "Unknown file type.";
|
||||
|
||||
// Get writer
|
||||
SubtitleFormat *writer = SubtitleFormat::GetWriter(_filename);
|
||||
|
||||
// Write file
|
||||
if (writer) {
|
||||
writer->SetTarget(this);
|
||||
writer->WriteFile(_filename,encoding);
|
||||
}
|
||||
|
||||
// Couldn't find a type
|
||||
else throw _T("Unknown file type.");
|
||||
|
||||
// Add to recent
|
||||
if (addToRecent) AddToRecent(_filename);
|
||||
|
||||
// Done
|
||||
if (setfilename) {
|
||||
savedCommitId = commitId;
|
||||
filename = _filename;
|
||||
filename = filename;
|
||||
}
|
||||
|
||||
FileSave();
|
||||
|
||||
writer->SetTarget(this);
|
||||
writer->WriteFile(filename, encoding);
|
||||
|
||||
if (addToRecent) {
|
||||
AddToRecent(filename);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -776,6 +765,8 @@ AssStyle *AssFile::GetStyle(wxString name) {
|
|||
|
||||
void AssFile::AddToRecent(wxString file) {
|
||||
config::mru->Add("Subtitle", STD_STR(file));
|
||||
wxFileName filepath(file);
|
||||
OPT_SET("Path/Last/Subtitles")->SetString(STD_STR(filepath.GetPath()));
|
||||
}
|
||||
|
||||
wxString AssFile::GetWildcardList(int mode) {
|
||||
|
|
|
@ -72,8 +72,14 @@ class AssFile {
|
|||
/// Last saved version of this file
|
||||
int savedCommitId;
|
||||
|
||||
/// A set of changes has been committed to the file (AssFile::CommitType)
|
||||
agi::signal::Signal<int> AnnounceCommit;
|
||||
/// A new file has been opened (filename)
|
||||
agi::signal::Signal<wxString> FileOpen;
|
||||
/// The file is about to be saved
|
||||
/// This signal is intended for adding metadata such as video filename,
|
||||
/// frame number, etc. Ideally this would all be done immediately rather
|
||||
/// than waiting for a save, but that causes (more) issues with undo
|
||||
agi::signal::Signal<> FileSave;
|
||||
|
||||
public:
|
||||
|
|
|
@ -231,7 +231,7 @@ struct subtitle_new : public Command {
|
|||
STR_HELP("New subtitles.")
|
||||
|
||||
void operator()(agi::Context *c) {
|
||||
c->SubsGrid->LoadDefault();
|
||||
c->ass->LoadDefault();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -210,8 +210,6 @@ FrameMain::FrameMain (wxArrayString args)
|
|||
SetDropTarget(new AegisubFileDropTarget(this));
|
||||
|
||||
// Parse arguments
|
||||
StartupLog(_T("Initialize empty file"));
|
||||
SubsGrid->LoadDefault();
|
||||
StartupLog(_T("Load files specified on command line"));
|
||||
LoadList(args);
|
||||
|
||||
|
@ -458,57 +456,44 @@ void FrameMain::LoadSubtitles(wxString filename,wxString charset) {
|
|||
/// @param saveas
|
||||
/// @param withCharset
|
||||
/// @return
|
||||
bool FrameMain::SaveSubtitles(bool saveas,bool withCharset) {
|
||||
// Try to get filename from file
|
||||
bool FrameMain::SaveSubtitles(bool saveas, bool withCharset) {
|
||||
wxString filename;
|
||||
if (saveas == false && ass->CanSave()) filename = ass->filename;
|
||||
if (!saveas && ass->CanSave()) {
|
||||
filename = ass->filename;
|
||||
}
|
||||
|
||||
// Failed, ask user
|
||||
if (filename.IsEmpty()) {
|
||||
if (filename.empty()) {
|
||||
temp_context->videoContext->Stop();
|
||||
wxString path = lagi_wxString(OPT_GET("Path/Last/Subtitles")->GetString());
|
||||
wxFileName origPath(ass->filename);
|
||||
filename = wxFileSelector(_("Save subtitles file"),path,origPath.GetName() + _T(".ass"),_T("ass"),AssFile::GetWildcardList(1),wxFD_SAVE | wxFD_OVERWRITE_PROMPT,this);
|
||||
filename = wxFileSelector(_("Save subtitles file"), path, origPath.GetName() + ".ass", "ass", AssFile::GetWildcardList(1), wxFD_SAVE | wxFD_OVERWRITE_PROMPT, this);
|
||||
}
|
||||
if (filename.empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Actually save
|
||||
if (!filename.empty()) {
|
||||
// Store path
|
||||
wxFileName filepath(filename);
|
||||
OPT_SET("Path/Last/Subtitles")->SetString(STD_STR(filepath.GetPath()));
|
||||
|
||||
// Fix me, ghetto hack for correct relative path generation in SynchronizeProject()
|
||||
ass->filename = filename;
|
||||
|
||||
// Synchronize
|
||||
SynchronizeProject();
|
||||
|
||||
// Get charset
|
||||
wxString charset = _T("");
|
||||
if (withCharset) {
|
||||
charset = wxGetSingleChoice(_("Choose charset code:"), _T("Charset"),agi::charset::GetEncodingsList<wxArrayString>(),this,-1, -1,true,250,200);
|
||||
if (charset.IsEmpty()) return false;
|
||||
}
|
||||
|
||||
// Save
|
||||
try {
|
||||
ass->Save(filename,true,true,charset);
|
||||
}
|
||||
catch (const agi::Exception& err) {
|
||||
wxMessageBox(lagi_wxString(err.GetMessage()), "Error", wxOK | wxICON_ERROR, NULL);
|
||||
return false;
|
||||
}
|
||||
catch (const wchar_t *err) {
|
||||
wxMessageBox(wxString(err), _T("Error"), wxOK | wxICON_ERROR, NULL);
|
||||
return false;
|
||||
}
|
||||
catch (...) {
|
||||
wxMessageBox(_T("Unknown error"), _T("Error"), wxOK | wxICON_ERROR, NULL);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
wxString charset;
|
||||
if (withCharset) {
|
||||
charset = wxGetSingleChoice(_("Choose charset code:"), "Charset", agi::charset::GetEncodingsList<wxArrayString>(),this,-1, -1,true,250,200);
|
||||
if (charset.empty()) return false;
|
||||
}
|
||||
return false;
|
||||
|
||||
try {
|
||||
ass->Save(filename, true, true, charset);
|
||||
}
|
||||
catch (const agi::Exception& err) {
|
||||
wxMessageBox(lagi_wxString(err.GetMessage()), "Error", wxOK | wxICON_ERROR, NULL);
|
||||
return false;
|
||||
}
|
||||
catch (const wchar_t *err) {
|
||||
wxMessageBox(wxString(err), _T("Error"), wxOK | wxICON_ERROR, NULL);
|
||||
return false;
|
||||
}
|
||||
catch (...) {
|
||||
wxMessageBox(_T("Unknown error"), _T("Error"), wxOK | wxICON_ERROR, NULL);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// @brief Try to close subtitles
|
||||
|
@ -627,41 +612,6 @@ void FrameMain::SynchronizeProject() {
|
|||
ass->SetScriptInfo(_T("Video Position"),seekpos);
|
||||
ass->SetScriptInfo(_T("VFR File"),MakeRelativePath(temp_context->videoContext->GetTimecodesName(),ass->filename));
|
||||
ass->SetScriptInfo(_T("Keyframes File"),MakeRelativePath(temp_context->videoContext->GetKeyFramesName(),ass->filename));
|
||||
|
||||
// Store Automation script data
|
||||
// Algorithm:
|
||||
// 1. If script filename has Automation Base Path as a prefix, the path is relative to that (ie. "$")
|
||||
// 2. Otherwise try making it relative to the ass filename
|
||||
// 3. If step 2 failed, or absolut path is shorter than path relative to ass, use absolute path ("/")
|
||||
// 4. Otherwise, use path relative to ass ("~")
|
||||
#ifdef WITH_AUTOMATION
|
||||
wxString scripts_string;
|
||||
wxString autobasefn(lagi_wxString(OPT_GET("Path/Automation/Base")->GetString()));
|
||||
|
||||
const std::vector<Automation4::Script*> &scripts = local_scripts->GetScripts();
|
||||
for (unsigned int i = 0; i < scripts.size(); i++) {
|
||||
Automation4::Script *script = scripts[i];
|
||||
|
||||
if (i != 0)
|
||||
scripts_string += _T("|");
|
||||
|
||||
wxString autobase_rel, assfile_rel;
|
||||
wxString scriptfn(script->GetFilename());
|
||||
autobase_rel = MakeRelativePath(scriptfn, autobasefn);
|
||||
assfile_rel = MakeRelativePath(scriptfn, ass->filename);
|
||||
|
||||
if (autobase_rel.size() <= scriptfn.size() && autobase_rel.size() <= assfile_rel.size()) {
|
||||
scriptfn = _T("$") + autobase_rel;
|
||||
} else if (assfile_rel.size() <= scriptfn.size() && assfile_rel.size() <= autobase_rel.size()) {
|
||||
scriptfn = _T("~") + assfile_rel;
|
||||
} else {
|
||||
scriptfn = _T("/") + wxFileName(scriptfn).GetFullPath(wxPATH_UNIX);
|
||||
}
|
||||
|
||||
scripts_string += scriptfn;
|
||||
}
|
||||
ass->SetScriptInfo(_T("Automation Scripts"), scripts_string);
|
||||
#endif
|
||||
}
|
||||
|
||||
void FrameMain::OnVideoOpen() {
|
||||
|
@ -1404,6 +1354,46 @@ void FrameMain::OnSubtitlesOpen() {
|
|||
SetDisplayMode(1,1);
|
||||
}
|
||||
|
||||
void FrameMain::OnSubtitlesSave() {
|
||||
UpdateTitle();
|
||||
|
||||
// Store Automation script data
|
||||
// Algorithm:
|
||||
// 1. If script filename has Automation Base Path as a prefix, the path is relative to that (ie. "$")
|
||||
// 2. Otherwise try making it relative to the ass filename
|
||||
// 3. If step 2 failed, or absolute path is shorter than path relative to ass, use absolute path ("/")
|
||||
// 4. Otherwise, use path relative to ass ("~")
|
||||
#ifdef WITH_AUTOMATION
|
||||
wxString scripts_string;
|
||||
wxString autobasefn(lagi_wxString(OPT_GET("Path/Automation/Base")->GetString()));
|
||||
|
||||
const std::vector<Automation4::Script*> &scripts = local_scripts->GetScripts();
|
||||
for (unsigned int i = 0; i < scripts.size(); i++) {
|
||||
Automation4::Script *script = scripts[i];
|
||||
|
||||
if (i != 0)
|
||||
scripts_string += _T("|");
|
||||
|
||||
wxString autobase_rel, assfile_rel;
|
||||
wxString scriptfn(script->GetFilename());
|
||||
autobase_rel = MakeRelativePath(scriptfn, autobasefn);
|
||||
assfile_rel = MakeRelativePath(scriptfn, ass->filename);
|
||||
|
||||
if (autobase_rel.size() <= scriptfn.size() && autobase_rel.size() <= assfile_rel.size()) {
|
||||
scriptfn = _T("$") + autobase_rel;
|
||||
} else if (assfile_rel.size() <= scriptfn.size() && assfile_rel.size() <= autobase_rel.size()) {
|
||||
scriptfn = _T("~") + assfile_rel;
|
||||
} else {
|
||||
scriptfn = _T("/") + wxFileName(scriptfn).GetFullPath(wxPATH_UNIX);
|
||||
}
|
||||
|
||||
scripts_string += scriptfn;
|
||||
}
|
||||
ass->SetScriptInfo(_T("Automation Scripts"), scripts_string);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void FrameMain::OnKeyDown(wxKeyEvent &event) {
|
||||
hotkey::check("Main Frame", event.GetKeyCode(), event.GetUnicodeKey(), event.GetModifiers());
|
||||
}
|
||||
|
|
|
@ -175,6 +175,7 @@ private:
|
|||
|
||||
void OnSubtitlesCommit();
|
||||
void OnSubtitlesOpen();
|
||||
void OnSubtitlesSave();
|
||||
|
||||
public:
|
||||
|
||||
|
|
|
@ -752,17 +752,6 @@ void SubtitlesGrid::OnAudioClip(wxCommandEvent &) {
|
|||
}
|
||||
}
|
||||
|
||||
/// @brief Clears grid and sets it to default
|
||||
/// @param _ass
|
||||
void SubtitlesGrid::LoadDefault () {
|
||||
ass->LoadDefault();
|
||||
ClearMaps();
|
||||
UpdateMaps();
|
||||
|
||||
SetActiveLine(GetDialogue(0));
|
||||
SelectRow(0);
|
||||
}
|
||||
|
||||
/// @brief Swaps two lines
|
||||
/// @param n1
|
||||
/// @param n2
|
||||
|
|
|
@ -109,8 +109,6 @@ public:
|
|||
SubtitlesGrid(FrameMain* parentFrame,wxWindow *parent, wxWindowID id, AssFile *subs, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize, long style = wxWANTS_CHARS, const wxString& name = wxPanelNameStr);
|
||||
~SubtitlesGrid();
|
||||
|
||||
void LoadDefault();
|
||||
|
||||
/// @brief Jump to the start/end time of the current subtitle line
|
||||
/// @param start Start vs. End time
|
||||
void SetVideoToSubs(bool start);
|
||||
|
|
|
@ -199,7 +199,8 @@ void VideoContext::SetVideo(const wxString &filename) {
|
|||
}
|
||||
|
||||
provider->LoadSubtitles(grid->ass);
|
||||
grid->ass->AddCommitListener(&VideoContext::SubtitlesChanged, this);
|
||||
grid->ass->AddCommitListener(&VideoContext::OnSubtitlesCommit, this);
|
||||
grid->ass->AddCommitListener(&VideoContext::OnSubtitlesSave, this);
|
||||
VideoOpen();
|
||||
KeyframesOpen(keyFrames);
|
||||
TimecodesOpen(FPS());
|
||||
|
@ -222,7 +223,7 @@ void VideoContext::Reload() {
|
|||
}
|
||||
}
|
||||
|
||||
void VideoContext::SubtitlesChanged() {
|
||||
void VideoContext::OnSubtitlesCommit() {
|
||||
if (!IsLoaded()) return;
|
||||
|
||||
bool wasPlaying = isPlaying;
|
||||
|
@ -234,6 +235,29 @@ void VideoContext::SubtitlesChanged() {
|
|||
if (wasPlaying) Play();
|
||||
}
|
||||
|
||||
void VideoContext::OnSubtitlesSave() {
|
||||
if (!IsLoaded()) {
|
||||
grid->ass->SetScriptInfo("Video File", "");
|
||||
grid->ass->SetScriptInfo("Video Aspect Ratio", "");
|
||||
grid->ass->SetScriptInfo("Video Position", "");
|
||||
grid->ass->SetScriptInfo("VFR File", "");
|
||||
grid->ass->SetScriptInfo("Keyframes File", "");
|
||||
return;
|
||||
}
|
||||
|
||||
wxString ar;
|
||||
if (arType == 4)
|
||||
ar = wxString::Format("c%g", arValue);
|
||||
else
|
||||
ar = wxString::Format("%d", arType);
|
||||
|
||||
grid->ass->SetScriptInfo("Video File", MakeRelativePath(videoName, grid->ass->filename));
|
||||
grid->ass->SetScriptInfo("Video Aspect Ratio", ar);
|
||||
grid->ass->SetScriptInfo("Video Position", wxString::Format("%d", frame_n));
|
||||
grid->ass->SetScriptInfo("VFR File", MakeRelativePath(GetTimecodesName(), grid->ass->filename));
|
||||
grid->ass->SetScriptInfo("Keyframes File", MakeRelativePath(GetKeyFramesName(), grid->ass->filename));
|
||||
}
|
||||
|
||||
void VideoContext::JumpToFrame(int n) {
|
||||
if (!IsLoaded()) return;
|
||||
|
||||
|
@ -466,7 +490,7 @@ void VideoContext::LoadKeyframes(wxString filename) {
|
|||
if (kf.second != 0.) {
|
||||
ovrFPS = agi::vfr::Framerate(kf.second);
|
||||
ovrTimecodeFile.clear();
|
||||
SubtitlesChanged();
|
||||
OnSubtitlesCommit();
|
||||
TimecodesOpen(ovrFPS);
|
||||
}
|
||||
config::mru->Add("Keyframes", STD_STR(filename));
|
||||
|
@ -503,7 +527,7 @@ void VideoContext::LoadTimecodes(wxString filename) {
|
|||
ovrFPS = agi::vfr::Framerate(STD_STR(filename));
|
||||
ovrTimecodeFile = filename;
|
||||
config::mru->Add("Timecodes", STD_STR(filename));
|
||||
SubtitlesChanged();
|
||||
OnSubtitlesCommit();
|
||||
TimecodesOpen(ovrFPS);
|
||||
}
|
||||
catch (const agi::acs::AcsError&) {
|
||||
|
@ -526,7 +550,7 @@ void VideoContext::SaveTimecodes(wxString filename) {
|
|||
void VideoContext::CloseTimecodes() {
|
||||
ovrFPS = agi::vfr::Framerate();
|
||||
ovrTimecodeFile.clear();
|
||||
SubtitlesChanged();
|
||||
OnSubtitlesCommit();
|
||||
TimecodesOpen(videoFPS);
|
||||
}
|
||||
|
||||
|
|
|
@ -155,6 +155,9 @@ private:
|
|||
void OnVideoError(VideoProviderErrorEvent const& err);
|
||||
void OnSubtitlesError(SubtitlesProviderErrorEvent const& err);
|
||||
|
||||
void OnSubtitlesCommit();
|
||||
void OnSubtitlesSave();
|
||||
|
||||
public:
|
||||
/// DOCME
|
||||
SubtitlesGrid *grid;
|
||||
|
@ -233,9 +236,6 @@ public:
|
|||
/// @param end Type of time
|
||||
void JumpToTime(int ms, agi::vfr::Time end = agi::vfr::START);
|
||||
|
||||
/// @brief Refresh the subtitle provider
|
||||
void SubtitlesChanged();
|
||||
|
||||
/// @brief Get the height and width of the current script
|
||||
/// @param[out] w Width
|
||||
/// @param[out] h Height
|
||||
|
|
Loading…
Reference in a new issue