Rewrite Undo/Redo code

Make the undo and redo stacks non-static members of AssFile, making it
theoretically possible to have multiple open AssFiles with working undo.

Slightly improve tracking of whether the file is modified: saving,
making a change, then undoing the change now results in the file being
shown as unmodified as with most programs with undo.

Add basic undo coalescing support.

Originally committed to SVN as r4667.
This commit is contained in:
Thomas Goyne 2010-07-09 07:31:34 +00:00
parent 518e78ac6f
commit 2e5dc176db
22 changed files with 158 additions and 219 deletions

View file

@ -61,10 +61,17 @@
#include "utils.h"
#include "version.h"
namespace std {
template<>
void swap(AssFile &lft, AssFile &rgt) {
lft.swap(rgt);
}
}
/// @brief AssFile constructor
AssFile::AssFile () {
loaded = false;
Modified = false;
AssFile::AssFile ()
: loaded(false)
{
}
/// @brief AssFile destructor
@ -74,6 +81,7 @@ AssFile::~AssFile() {
void AssFile::Load (const wxString &_filename,wxString charset,bool addToRecent) {
bool ok = false;
Clear();
try {
// Try to open file
@ -141,6 +149,10 @@ void AssFile::Load (const wxString &_filename,wxString charset,bool addToRecent)
AddComment(_T("http://www.aegisub.org/"));
SetScriptInfo(_T("ScriptType"),_T("v4.00+"));
// Push the initial state of the file onto the undo stack
Commit("", commitId);
savedCommitId = commitId;
// Add to recent
if (addToRecent) AddToRecent(_filename);
}
@ -171,7 +183,7 @@ void AssFile::Save(wxString _filename,bool setfilename,bool addToRecent,const wx
// Done
if (setfilename) {
Modified = false;
savedCommitId = commitId;
filename = _filename;
}
}
@ -416,7 +428,11 @@ void AssFile::Clear() {
loaded = false;
filename.clear();
Modified = false;
UndoStack.clear();
RedoStack.clear();
undoDescription.clear();
commitId = -1;
savedCommitId = 0;
}
void AssFile::LoadDefault (bool defline) {
@ -445,20 +461,30 @@ void AssFile::LoadDefault (bool defline) {
AddLine(def.GetEntryData(),_T("[Events]"),version);
}
Commit("");
savedCommitId = commitId;
loaded = true;
}
AssFile::AssFile (const AssFile &from) {
filename = from.filename;
loaded = from.loaded;
Modified = from.Modified;
void AssFile::swap(AssFile &that) throw() {
// Intentionally does not swap undo stack related things
std::swap(filename, that.filename);
std::swap(loaded, that.loaded);
std::swap(commitId, that.commitId);
std::swap(undoDescription, that.undoDescription);
std::swap(Line, that.Line);
}
AssFile::AssFile(const AssFile &from)
: undoDescription(from.undoDescription)
, commitId(from.commitId)
, filename(from.filename)
, loaded(from.loaded)
{
std::transform(from.Line.begin(), from.Line.end(), std::back_inserter(Line), std::mem_fun(&AssEntry::Clone));
}
AssFile& AssFile::operator=(AssFile from) {
filename = from.filename;
loaded = from.loaded;
Modified = from.Modified;
std::swap(Line, from.Line);
std::swap(*this, from);
return *this;
}
@ -747,120 +773,55 @@ void AssFile::CompressForStack() {
}
}
bool AssFile::IsModified() {
return Modified;
}
void AssFile::FlagAsModified(wxString desc) {
if (!RedoStack.empty()) {
delete_clear(RedoStack);
int AssFile::Commit(wxString desc, int amendId) {
++commitId;
// Allow coalescing only if it's the last change and the file has not been
// saved since the last change
if (commitId == amendId+1 && RedoStack.empty() && savedCommitId != commitId) {
UndoStack.back() = *this;
UndoStack.back().CompressForStack();
return commitId;
}
Modified = true;
StackPush(desc);
}
RedoStack.clear();
void AssFile::StackPush(wxString desc) {
// Places copy on stack
AssFile *curcopy = new AssFile(*top);
curcopy->CompressForStack();
curcopy->undodescription = desc;
UndoStack.push_back(curcopy);
StackModified = true;
// Place copy on stack
undoDescription = desc;
UndoStack.push_back(*this);
UndoStack.back().CompressForStack();
// Cap depth
int n = 0;
for (std::list<AssFile*>::iterator cur=UndoStack.begin();cur!=UndoStack.end();cur++) {
n++;
}
int depth = OPT_GET("Limits/Undo Levels")->GetInt();
while (n > depth) {
delete UndoStack.front();
while ((int)UndoStack.size() > depth) {
UndoStack.pop_front();
n--;
}
}
void AssFile::StackPop() {
bool addcopy = false;
wxString undodesc="";
if (StackModified) {
undodesc=UndoStack.back()->undodescription;
delete UndoStack.back();
UndoStack.pop_back();
StackModified = false;
addcopy = true;
}
if (!UndoStack.empty()) {
//delete top;
AssFile *undo = UndoStack.back();
top->CompressForStack();
top->undodescription = undodesc;
RedoStack.push_back(top);
top = undo;
UndoStack.pop_back();
Popping = true;
}
if (addcopy) {
StackPush(top->undodescription);
}
return commitId;
}
void AssFile::StackRedo() {
bool addcopy = false;
if (StackModified) {
delete UndoStack.back();
UndoStack.pop_back();
StackModified = false;
addcopy = true;
}
void AssFile::Undo() {
if (UndoStack.size() <= 1) return;
if (!RedoStack.empty()) {
top->CompressForStack();
UndoStack.push_back(top);
top = RedoStack.back();
RedoStack.pop_back();
Popping = true;
}
if (addcopy) {
StackPush(top->undodescription);
}
RedoStack.push_back(AssFile());
std::swap(RedoStack.back(), *this);
UndoStack.pop_back();
*this = UndoStack.back();
}
void AssFile::StackClear() {
delete_clear(UndoStack);
delete_clear(RedoStack);
void AssFile::Redo() {
if (RedoStack.empty()) return;
Popping = false;
std::swap(*this, RedoStack.back());
UndoStack.push_back(*this);
RedoStack.pop_back();
}
void AssFile::StackReset() {
StackClear();
delete top;
top = new AssFile;
StackModified = false;
wxString AssFile::GetUndoDescription() const {
return IsUndoStackEmpty() ? "" : UndoStack.back().undoDescription;
}
bool AssFile::IsUndoStackEmpty() {
if (StackModified) return (UndoStack.size() <= 1);
else return UndoStack.empty();
}
bool AssFile::IsRedoStackEmpty() {
return RedoStack.empty();
}
wxString AssFile::GetUndoDescription() {
return (IsUndoStackEmpty())?_T(""):(UndoStack.back())->undodescription;
}
wxString AssFile::GetRedoDescription() {
return (IsRedoStackEmpty())?_T(""):(RedoStack.back())->undodescription;
wxString AssFile::GetRedoDescription() const {
return IsRedoStackEmpty() ? "" : RedoStack.back().undoDescription;
}
bool AssFile::CompStart(const AssDialogue* lft, const AssDialogue* rgt) {
@ -909,7 +870,3 @@ void AssFile::Sort(std::list<AssDialogue*> &lst, CompFunc comp) {
}
AssFile *AssFile::top;
std::list<AssFile*> AssFile::UndoStack;
std::list<AssFile*> AssFile::RedoStack;
bool AssFile::Popping;
bool AssFile::StackModified;

View file

@ -62,26 +62,15 @@ typedef std::list<AssEntry*>::iterator entryIter;
///
/// DOCME
class AssFile {
private:
/// DOCME
bool Modified;
/// DOCME
static std::list<AssFile*> UndoStack;
/// DOCME
static std::list<AssFile*> RedoStack;
/// DOCME
static bool StackModified;
static void StackClear();
wxString undodescription;
std::list<AssFile> UndoStack;
std::list<AssFile> RedoStack;
wxString undoDescription;
/// Revision counter for undo coalescing and modified state tracking
int commitId;
/// Last saved version of this file
int savedCommitId;
public:
/// The lines in the file
std::list<AssEntry*> Line;
/// The filename of this file, if any
@ -95,12 +84,10 @@ public:
~AssFile();
/// Does the file have unsaved changes?
bool IsModified();
/// @brief Flag the file as modified and push a copy onto the undo stack
/// @param desc Undo description
void FlagAsModified(wxString desc);
bool IsModified() const {return commitId != savedCommitId; };
/// Clear the file
void Clear();
/// Discard some parsed data to reduce the size of the undo stack
void CompressForStack();
/// @brief Load default file
@ -119,6 +106,7 @@ public:
/// @return Pointer to style or NULL
AssStyle *GetStyle(wxString name);
void swap(AssFile &) throw();
/// @brief Load from a file
/// @param file File name
@ -164,26 +152,23 @@ public:
/// @param[out] outGroup Group it was actually added to; attachments do something strange here
void AddLine(wxString data,wxString group,int &version,wxString *outGroup=NULL);
/// Pop subs from stack and set 'top' to it
static void StackPop();
/// Redo action on stack
static void StackRedo();
/// @brief Put a copy of 'top' on the stack
/// @param desc Undo message
static void StackPush(wxString desc);
/// Clear the stack. Do before loading new subtitles.
static void StackReset();
/// @brief Flag the file as modified and push a copy onto the undo stack
/// @param desc Undo description
/// @param commitId Commit to amend rather than pushing a new commit
/// @return Unique identifier for the new undo group
int Commit(wxString desc, int commitId = -1);
/// @brief Undo the last set of changes to the file
void Undo();
/// @brief Redo the last undone changes
void Redo();
/// Check if undo stack is empty
static bool IsUndoStackEmpty();
bool IsUndoStackEmpty() const { return UndoStack.size() <= 1; };
/// Check if redo stack is empty
static bool IsRedoStackEmpty();
bool IsRedoStackEmpty() const { return RedoStack.empty(); };
/// Get the description of the first undoable change
static wxString GetUndoDescription();
wxString GetUndoDescription() const;
/// Get the description of the first redoable change
static wxString GetRedoDescription();
/// Flags the stack as popping. You must unset this after popping
static bool Popping;
wxString GetRedoDescription() const;
/// Current script file. It is "above" the stack.
static AssFile *top;

View file

@ -1209,7 +1209,7 @@ void AudioDisplay::CommitChanges (bool nextLine) {
// Update grid
grid->editBox->Update(!karaoke->enabled);
grid->ass->FlagAsModified(_T(""));
grid->ass->Commit(_T(""));
grid->CommitChanges();
karaoke->SetSelection(karaSelStart, karaSelEnd);
blockUpdate = false;

View file

@ -1014,7 +1014,7 @@ namespace Automation4 {
description = wxString(lua_tostring(L, 1), wxConvUTF8);
lua_pop(L, 1);
}
AssFile::top->FlagAsModified(description);
AssFile::top->Commit(description);
laf->ass = AssFile::top; // make sure we're still working on the most recent undo point
return 0;

View file

@ -174,7 +174,7 @@ DialogAttachments::~DialogAttachments() {
}
if (removed_any) {
AssFile::top->FlagAsModified(_("remove empty attachments sections"));
AssFile::top->Commit(_("remove empty attachments sections"));
}
}
@ -223,7 +223,7 @@ void DialogAttachments::OnAttachFont(wxCommandEvent &event) {
AssFile::top->InsertAttachment(newAttach);
}
AssFile::top->FlagAsModified(_("attach font file"));
AssFile::top->Commit(_("attach font file"));
// Update
UpdateList();
@ -261,7 +261,7 @@ void DialogAttachments::OnAttachGraphics(wxCommandEvent &event) {
AssFile::top->InsertAttachment(newAttach);
}
AssFile::top->FlagAsModified(_("attach graphics file"));
AssFile::top->Commit(_("attach graphics file"));
// Update
UpdateList();
@ -316,7 +316,7 @@ void DialogAttachments::OnDelete(wxCommandEvent &event) {
i = listView->GetNextSelected(i);
}
AssFile::top->FlagAsModified(_("remove attachment"));
AssFile::top->Commit(_("remove attachment"));
// Update list
UpdateList();

View file

@ -514,7 +514,7 @@ void FontsCollectorThread::Collect() {
// Modify file if it was attaching
if (oper == 3 && someOk) {
wxMutexGuiEnter();
subs->FlagAsModified(_("font attachment"));
subs->Commit(_("font attachment"));
collector->main->SubsGrid->CommitChanges();
wxMutexGuiLeave();
}

View file

@ -940,7 +940,7 @@ void DialogKanjiTimer::OnClose(wxCommandEvent &event) {
line->Text = p.second;
}
if (modified) {
grid->ass->FlagAsModified(_("kanji timing"));
grid->ass->Commit(_("kanji timing"));
grid->CommitChanges();
grid->UpdateMaps();
LinesToChange.clear();

View file

@ -211,7 +211,7 @@ void DialogProperties::OnOK(wxCommandEvent &event) {
count += SetInfoIfDifferent(_T("Collisions"),col[collision->GetSelection()]);
count += SetInfoIfDifferent(_T("ScaledBorderAndShadow"),ScaleBorder->GetValue()? _T("yes") : _T("no"));
if (count) AssFile::top->FlagAsModified(_("property changes"));
if (count) AssFile::top->Commit(_("property changes"));
EndModal(count?1:0);
}

View file

@ -321,7 +321,7 @@ void DialogResample::OnResample (wxCommandEvent &event) {
subs->SetScriptInfo(_T("PlayResY"),wxString::Format(_T("%i"),y2));
// Flag as modified
subs->FlagAsModified(_("resolution resampling"));
subs->Commit(_("resolution resampling"));
grid->CommitChanges();
grid->editBox->Update();
EndModal(0);

View file

@ -437,7 +437,7 @@ void SearchReplaceEngine::ReplaceNext(bool DoReplace) {
}
// Commit
grid->ass->FlagAsModified(_("replace"));
grid->ass->Commit(_("replace"));
grid->CommitChanges();
}
@ -544,7 +544,7 @@ void SearchReplaceEngine::ReplaceAll() {
// Commit
if (count > 0) {
grid->ass->FlagAsModified(_("replace"));
grid->ass->Commit(_("replace"));
grid->CommitChanges();
grid->editBox->Update();
wxMessageBox(wxString::Format(_("%i matches were replaced."),count));

View file

@ -311,7 +311,7 @@ void DialogShiftTimes::OnOK(wxCommandEvent &event) {
OPT_SET("Tool/Shift Times/Direction")->SetBool(backward);
// End dialog
grid->ass->FlagAsModified(_("shifting"));
grid->ass->Commit(_("shifting"));
grid->CommitChanges();
grid->UpdateMaps();
grid->editBox->Update();

View file

@ -390,7 +390,7 @@ void DialogSpellChecker::Replace() {
lastPos = wordStart + replaceWord->GetValue().Length();
// Commit
grid->ass->FlagAsModified(_("Spell check replace"));
grid->ass->Commit(_("Spell check replace"));
grid->CommitChanges();
}

View file

@ -581,7 +581,7 @@ void DialogStyleEditor::Apply (bool apply,bool close) {
*style = *work;
style->UpdateData();
if (isLocal) {
AssFile::top->FlagAsModified(_("style change"));
AssFile::top->Commit(_("style change"));
grid->CommitChanges();
}

View file

@ -576,7 +576,7 @@ void DialogStyleManager::OnCopyToCurrent (wxCommandEvent &) {
for (list<wxString>::iterator name = copied.begin(); name != copied.end(); ++name) {
CurrentList->SetStringSelection(*name, true);
}
grid->ass->FlagAsModified(_("style copy"));
grid->ass->Commit(_("style copy"));
grid->CommitChanges();
wxCommandEvent dummy;
OnCurrentChange(dummy);
@ -625,7 +625,7 @@ void DialogStyleManager::OnCurrentCopy (wxCommandEvent &) {
}
else delete temp;
grid->ass->FlagAsModified(_("style copy"));
grid->ass->Commit(_("style copy"));
grid->CommitChanges();
UpdateMoveButtons();
}
@ -678,7 +678,7 @@ void DialogStyleManager::PasteToCurrent() {
AssFile::top->InsertStyle(s);
LoadCurrentStyles(AssFile::top);
grid->ass->FlagAsModified(_("style paste"));
grid->ass->Commit(_("style paste"));
grid->CommitChanges();
}
else
@ -822,7 +822,7 @@ void DialogStyleManager::OnCurrentDelete (wxCommandEvent &) {
CurrentCopy->Enable(false);
CurrentDelete->Enable(false);
grid->ass->FlagAsModified(_("style delete"));
grid->ass->Commit(_("style delete"));
grid->CommitChanges();
}
UpdateMoveButtons();
@ -884,7 +884,7 @@ void DialogStyleManager::OnCurrentImport(wxCommandEvent &) {
// Update
if (modified) {
LoadCurrentStyles(grid->ass);
grid->ass->FlagAsModified(_("style import"));
grid->ass->Commit(_("style import"));
grid->CommitChanges();
}
}
@ -1081,7 +1081,7 @@ void DialogStyleManager::MoveStyles(bool storage, int type) {
}
// Flag as modified
grid->ass->FlagAsModified(_("style move"));
grid->ass->Commit(_("style move"));
grid->CommitChanges();
}

View file

@ -169,7 +169,7 @@ wxDialog (parent, -1, _("Styling assistant"), wxDefaultPosition, wxDefaultSize,
DialogStyling::~DialogStyling () {
GetPosition(&lastx, &lasty);
if (needCommit) {
grid->ass->FlagAsModified(_("style changes"));
grid->ass->Commit(_("style changes"));
grid->CommitChanges();
}
}
@ -232,7 +232,7 @@ void DialogStyling::SetStyle (wxString curName, bool jump) {
// Update grid/subs
grid->Refresh(false);
if (PreviewCheck->IsChecked()) {
grid->ass->FlagAsModified(_("styling assistant"));
grid->ass->Commit(_("styling assistant"));
grid->CommitChanges();
}
else needCommit = true;
@ -264,7 +264,7 @@ void DialogStyling::OnActivate(wxActivateEvent &event) {
// Dialog lost focus
if (!event.GetActive()) {
if (needCommit) {
grid->ass->FlagAsModified(_("styling assistant"));
grid->ass->Commit(_("styling assistant"));
grid->CommitChanges();
needCommit = false;
}

View file

@ -542,6 +542,6 @@ void DialogTimingProcessor::Process() {
}
// Update grid
grid->ass->FlagAsModified(_("timing processor"));
grid->ass->Commit(_("timing processor"));
grid->CommitChanges();
}

View file

@ -357,7 +357,7 @@ void DialogTranslation::OnTransBoxKey(wxKeyEvent &event) {
// Update line
cur->UpdateText();
cur->ClearBlocks();
subs->FlagAsModified(_("translation assistant"));
subs->Commit(_("translation assistant"));
grid->CommitChanges();
((FrameMain*)main)->UpdateTitle();
UpdatePreview();

View file

@ -570,6 +570,7 @@ void FrameMain::InitMenu() {
/// @brief Initialize contents
void FrameMain::InitContents() {
AssFile::top = new AssFile;
// Set a background panel
StartupLog(_T("Create background panel"));
Panel = new wxPanel(this,-1,wxDefaultPosition,wxDefaultSize,wxTAB_TRAVERSAL | wxCLIP_CHILDREN);
@ -590,8 +591,6 @@ void FrameMain::InitContents() {
StartupLog(_T("Create subtitles grid"));
SubsGrid = new SubtitlesGrid(this,Panel,-1,wxDefaultPosition,wxSize(600,100),wxWANTS_CHARS | wxSUNKEN_BORDER,_T("Subs grid"));
BottomSizer->Add(SubsGrid,1,wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM,0);
StartupLog(_T("Reset undo stack"));
AssFile::StackReset();
videoBox->videoSlider->grid = SubsGrid;
VideoContext::Get()->grid = SubsGrid;
StartupLog(_T("Reset video zoom"));
@ -638,7 +637,6 @@ void FrameMain::DeInitContents() {
SubsGrid->ClearMaps();
delete EditBox;
delete videoBox;
AssFile::StackReset();
delete AssFile::top;
HelpButton::ClearPages();
VideoContext::Get()->audio = NULL;
@ -708,7 +706,6 @@ void FrameMain::LoadSubtitles (wxString filename,wxString charset) {
// Proceed into loading
SubsGrid->ClearMaps();
AssFile::StackReset();
if (isFile) {
AssFile::top->Load(filename,charset);
SubsGrid->UpdateMaps();
@ -1135,7 +1132,7 @@ void FrameMain::LoadVideo(wxString file,bool autoload) {
// Always change script res
SubsGrid->ass->SetScriptInfo(_T("PlayResX"), wxString::Format(_T("%d"), vidx));
SubsGrid->ass->SetScriptInfo(_T("PlayResY"), wxString::Format(_T("%d"), vidy));
SubsGrid->ass->FlagAsModified(_("Change script resolution"));
SubsGrid->ass->Commit(_("Change script resolution"));
SubsGrid->CommitChanges();
break;
case 0:
@ -1350,8 +1347,8 @@ bool FrameMain::LoadList(wxArrayString list) {
/// @brief Sets the descriptions for undo/redo
void FrameMain::SetUndoRedoDesc() {
editMenu->SetHelpString(0,_T("Undo ")+AssFile::GetUndoDescription());
editMenu->SetHelpString(1,_T("Redo ")+AssFile::GetRedoDescription());
editMenu->SetHelpString(0,_T("Undo ")+AssFile::top->GetUndoDescription());
editMenu->SetHelpString(1,_T("Redo ")+AssFile::top->GetRedoDescription());
}
/// @brief Check if ASSDraw is available

View file

@ -435,16 +435,16 @@ void FrameMain::OnMenuOpen (wxMenuEvent &event) {
else if (curMenu == editMenu) {
// Undo state
wxMenuItem *item;
wxString undo_text = _("&Undo") + wxString(_T(" ")) + AssFile::GetUndoDescription() + wxString(_T("\t")) + Hotkeys.GetText(_T("Undo"));
wxString undo_text = _("&Undo") + wxString(_T(" ")) + AssFile::top->GetUndoDescription() + wxString(_T("\t")) + Hotkeys.GetText(_T("Undo"));
item = editMenu->FindItem(Menu_Edit_Undo);
item->SetItemLabel(undo_text);
item->Enable(!AssFile::IsUndoStackEmpty());
item->Enable(!AssFile::top->IsUndoStackEmpty());
// Redo state
wxString redo_text = _("&Redo") + wxString(_T(" ")) + AssFile::GetRedoDescription() + wxString(_T("\t")) + Hotkeys.GetText(_T("Redo"));
wxString redo_text = _("&Redo") + wxString(_T(" ")) + AssFile::top->GetRedoDescription() + wxString(_T("\t")) + Hotkeys.GetText(_T("Redo"));
item = editMenu->FindItem(Menu_Edit_Redo);
item->SetItemLabel(redo_text);
item->Enable(!AssFile::IsRedoStackEmpty());
item->Enable(!AssFile::top->IsRedoStackEmpty());
// Copy/cut/paste
wxArrayInt sels = SubsGrid->GetSelection();
@ -1133,7 +1133,7 @@ void FrameMain::OnSnapToScene (wxCommandEvent &) {
// Commit
SubsGrid->editBox->Update(true);
SubsGrid->ass->FlagAsModified(_("snap to scene"));
SubsGrid->ass->Commit(_("snap to scene"));
SubsGrid->CommitChanges();
}
@ -1160,7 +1160,7 @@ void FrameMain::OnShiftToFrame (wxCommandEvent &) {
}
// Commit
SubsGrid->ass->FlagAsModified(_("shift to frame"));
SubsGrid->ass->Commit(_("shift to frame"));
SubsGrid->CommitChanges();
SubsGrid->editBox->Update(true,false);
}
@ -1168,17 +1168,17 @@ void FrameMain::OnShiftToFrame (wxCommandEvent &) {
/// @brief Undo
void FrameMain::OnUndo(wxCommandEvent&) {
VideoContext::Get()->Stop();
AssFile::StackPop();
AssFile::top->Undo();
UpdateTitle();
SubsGrid->UpdateMaps();
AssFile::Popping = false;
}
/// @brief Redo
void FrameMain::OnRedo(wxCommandEvent&) {
VideoContext::Get()->Stop();
AssFile::StackRedo();
AssFile::top->Redo();
UpdateTitle();
SubsGrid->UpdateMaps();
AssFile::Popping = false;
}
/// @brief Find
@ -1347,21 +1347,21 @@ void FrameMain::OnSelect (wxCommandEvent &) {
/// @brief Sort subtitles by start time
void FrameMain::OnSortStart (wxCommandEvent &) {
AssFile::top->Sort();
AssFile::top->FlagAsModified(_("sort"));
AssFile::top->Commit(_("sort"));
SubsGrid->UpdateMaps();
SubsGrid->CommitChanges();
}
/// @brief Sort subtitles by end time
void FrameMain::OnSortEnd (wxCommandEvent &) {
AssFile::top->Sort(AssFile::CompEnd);
AssFile::top->FlagAsModified(_("sort"));
AssFile::top->Commit(_("sort"));
SubsGrid->UpdateMaps();
SubsGrid->CommitChanges();
}
/// @brief Sort subtitles by style name
void FrameMain::OnSortStyle (wxCommandEvent &) {
AssFile::top->Sort(AssFile::CompStyle);
AssFile::top->FlagAsModified(_("sort"));
AssFile::top->Commit(_("sort"));
SubsGrid->UpdateMaps();
SubsGrid->CommitChanges();
}

View file

@ -573,7 +573,7 @@ void SubsEditBox::OnStyleChange(wxCommandEvent &event) {
cur->Style = StyleBox->GetValue();
}
}
grid->ass->FlagAsModified(_("style change"));
grid->ass->Commit(_("style change"));
grid->CommitChanges();
grid->EndBatch();
}
@ -605,7 +605,7 @@ void SubsEditBox::OnActorChange(wxCommandEvent &event) {
}
// Update grid
grid->ass->FlagAsModified(_("actor change"));
grid->ass->Commit(_("actor change"));
grid->CommitChanges();
grid->EndBatch();
}
@ -633,7 +633,7 @@ void SubsEditBox::OnLayerChange(wxSpinEvent &event) {
}
// Done
grid->ass->FlagAsModified(_("layer change"));
grid->ass->Commit(_("layer change"));
grid->CommitChanges();
}
@ -660,7 +660,7 @@ void SubsEditBox::OnLayerEnter(wxCommandEvent &event) {
}
// Done
grid->ass->FlagAsModified(_("layer change"));
grid->ass->Commit(_("layer change"));
grid->CommitChanges();
}
@ -746,7 +746,7 @@ void SubsEditBox::CommitTimes(bool start,bool end,bool fromStart,bool commit) {
StartTime->Update();
EndTime->Update();
Duration->Update();
grid->ass->FlagAsModified(_("modify times"));
grid->ass->Commit(_("modify times"));
grid->CommitChanges();
int sel0 = grid->GetFirstSelRow();
audio->SetDialogue(grid,grid->GetDialogue(sel0),sel0);
@ -772,7 +772,7 @@ void SubsEditBox::OnMarginLChange(wxCommandEvent &event) {
}
}
MarginL->SetValue(cur->GetMarginString(0,false));
grid->ass->FlagAsModified(_("MarginL change"));
grid->ass->Commit(_("MarginL change"));
grid->CommitChanges();
grid->EndBatch();
}
@ -795,7 +795,7 @@ void SubsEditBox::OnMarginRChange(wxCommandEvent &event) {
}
}
MarginR->SetValue(cur->GetMarginString(1,false));
grid->ass->FlagAsModified(_("MarginR change"));
grid->ass->Commit(_("MarginR change"));
grid->CommitChanges();
grid->EndBatch();
}
@ -819,7 +819,7 @@ void SubsEditBox::OnMarginVChange(wxCommandEvent &event) {
}
}
MarginV->SetValue(cur->GetMarginString(2,false));
grid->ass->FlagAsModified(_("MarginV change"));
grid->ass->Commit(_("MarginV change"));
grid->CommitChanges();
grid->EndBatch();
}
@ -841,7 +841,7 @@ void SubsEditBox::OnEffectChange(wxCommandEvent &event) {
cur->Effect = Effect->GetValue();
}
}
grid->ass->FlagAsModified(_("effect change"));
grid->ass->Commit(_("effect change"));
grid->CommitChanges();
grid->EndBatch();
}
@ -862,7 +862,7 @@ void SubsEditBox::OnCommentChange(wxCommandEvent &event) {
cur->Comment = CommentBox->GetValue();
}
}
grid->ass->FlagAsModified(_("comment change"));
grid->ass->Commit(_("comment change"));
grid->CommitChanges();
grid->EndBatch();
}
@ -945,7 +945,7 @@ void SubsEditBox::Commit(bool stay) {
// Update file
if (textNeedsCommit) {
grid->ass->FlagAsModified(_("editing"));
grid->ass->Commit(_("editing"));
grid->CommitChanges();
}
else if (StartTime->HasBeenModified() || EndTime->HasBeenModified()) {

View file

@ -427,7 +427,7 @@ void SubtitlesGrid::OnSplitByKaraoke (wxCommandEvent &event) {
didSplit |= SplitLineByKaraoke(sels[i]);
}
if (didSplit) {
ass->FlagAsModified(_("splitting"));
ass->Commit(_("splitting"));
CommitChanges();
}
EndBatch();
@ -692,7 +692,7 @@ void SubtitlesGrid::OnRecombine(wxCommandEvent &event) {
}
// Commit
ass->FlagAsModified(_("combining"));
ass->Commit(_("combining"));
CommitChanges();
}
@ -848,7 +848,7 @@ void SubtitlesGrid::SwapLines(int n1,int n2) {
std::swap(*dlg1, *dlg2);
UpdateMaps();
ass->FlagAsModified(_("swap lines"));
ass->Commit(_("swap lines"));
CommitChanges();
}
@ -872,7 +872,7 @@ void SubtitlesGrid::InsertLine(AssDialogue *line,int n,bool after,bool update) {
// Update
if (update) {
ass->FlagAsModified(_("line insertion"));
ass->Commit(_("line insertion"));
CommitChanges();
AdjustScrollbar();
}
@ -1005,7 +1005,7 @@ void SubtitlesGrid::PasteLines(int n,bool pasteOver) {
// Commit
UpdateMaps();
AdjustScrollbar();
ass->FlagAsModified(_("paste"));
ass->Commit(_("paste"));
CommitChanges();
// Set selection
@ -1055,7 +1055,7 @@ void SubtitlesGrid::DeleteLines(wxArrayInt target, bool flagModified) {
UpdateMaps();
AdjustScrollbar();
if (flagModified) {
ass->FlagAsModified(_("delete"));
ass->Commit(_("delete"));
CommitChanges();
}
@ -1118,7 +1118,7 @@ void SubtitlesGrid::JoinLines(int n1,int n2,bool concat) {
// Delete remaining lines (this will auto commit)
DeleteLines(GetRangeArray(n1+1,n2), false);
ass->FlagAsModified(_("join lines"));
ass->Commit(_("join lines"));
CommitChanges();
// Select new line
@ -1160,7 +1160,7 @@ void SubtitlesGrid::AdjoinLines(int n1,int n2,bool setStart) {
}
// Commit
AssFile::top->FlagAsModified(_("adjoin"));
AssFile::top->Commit(_("adjoin"));
CommitChanges();
}
@ -1210,7 +1210,7 @@ void SubtitlesGrid::JoinAsKaraoke(int n1,int n2) {
// Delete remaining lines (this will auto commit)
DeleteLines(GetRangeArray(n1+1,n2), false);
ass->FlagAsModified(_("join as karaoke"));
ass->Commit(_("join as karaoke"));
CommitChanges();
// Select new line
@ -1330,7 +1330,7 @@ void SubtitlesGrid::SplitLine(int n,int pos,int mode,wxString textIn) {
//editBox->SetToLine(n);
// Commit
ass->FlagAsModified(_("split"));
ass->Commit(_("split"));
CommitChanges();
}
@ -1439,7 +1439,7 @@ void SubtitlesGrid::SetSubsToVideo(bool start) {
// Commit
if (modified) {
ass->FlagAsModified(_("timing"));
ass->Commit(_("timing"));
CommitChanges();
editBox->Update(true);
}

View file

@ -266,7 +266,7 @@ void VisualTool<FeatureType>::Commit(bool full, wxString message) {
if (message.empty()) {
message = _("visual typesetting");
}
grid->ass->FlagAsModified(message);
grid->ass->Commit(message);
}
grid->CommitChanges(false,!full);
if (full)