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:
Thomas Goyne 2011-01-16 07:16:40 +00:00
parent 59300cbc27
commit 7210ea17d8
9 changed files with 126 additions and 127 deletions

View File

@ -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) {

View File

@ -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:

View File

@ -231,7 +231,7 @@ struct subtitle_new : public Command {
STR_HELP("New subtitles.")
void operator()(agi::Context *c) {
c->SubsGrid->LoadDefault();
c->ass->LoadDefault();
}
};

View File

@ -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());
}

View File

@ -175,6 +175,7 @@ private:
void OnSubtitlesCommit();
void OnSubtitlesOpen();
void OnSubtitlesSave();
public:

View File

@ -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

View File

@ -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);

View File

@ -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);
}

View File

@ -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