diff --git a/aegisub/src/ass_file.cpp b/aegisub/src/ass_file.cpp index 6118340ca..fe8972fdf 100644 --- a/aegisub/src/ass_file.cpp +++ b/aegisub/src/ass_file.cpp @@ -757,12 +757,15 @@ wxString AssFile::GetWildcardList(int mode) { else return ""; } -int AssFile::Commit(wxString desc, int amendId) { +int AssFile::Commit(wxString desc, CommitType type, int amendId) { + assert(type != COMMIT_UNDO); + ++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; + AnnounceCommit(type); return commitId; } @@ -778,6 +781,7 @@ int AssFile::Commit(wxString desc, int amendId) { UndoStack.pop_front(); } + AnnounceCommit(type); return commitId; } @@ -788,6 +792,8 @@ void AssFile::Undo() { std::swap(RedoStack.back(), *this); UndoStack.pop_back(); *this = UndoStack.back(); + + AnnounceCommit(COMMIT_UNDO); } void AssFile::Redo() { @@ -796,6 +802,8 @@ void AssFile::Redo() { std::swap(*this, RedoStack.back()); UndoStack.push_back(*this); RedoStack.pop_back(); + + AnnounceCommit(COMMIT_UNDO); } wxString AssFile::GetUndoDescription() const { diff --git a/aegisub/src/ass_file.h b/aegisub/src/ass_file.h index 8fc41b506..ec6800e1c 100644 --- a/aegisub/src/ass_file.h +++ b/aegisub/src/ass_file.h @@ -45,6 +45,8 @@ #include #endif +#include + class FrameRate; class AssDialogue; class AssStyle; @@ -70,6 +72,8 @@ class AssFile { /// Last saved version of this file int savedCommitId; + agi::signal::Signal AnnounceCommit; + public: /// The lines in the file std::list Line; @@ -150,11 +154,28 @@ 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); + /// Type of changes made in a commit + enum CommitType { + /// Entire file has been swapped for a different version of the same file + COMMIT_UNDO, + /// Potentially the entire file has been changed; any saved information + /// should be discarded + COMMIT_FULL, + /// The contents of lines have changed, but the number or order of lines + /// has not + COMMIT_TEXT, + /// Only the start and end times of lines has changed + COMMIT_TIMES + }; + + DEFINE_SIGNAL_ADDERS(AnnounceCommit, AddCommitListener) + /// @brief Flag the file as modified and push a copy onto the undo stack /// @param desc Undo description + /// @param type Type of changes made to the file in this commit /// @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); + int Commit(wxString desc, CommitType type = COMMIT_FULL, int commitId = -1); /// @brief Undo the last set of changes to the file void Undo(); /// @brief Redo the last undone changes diff --git a/aegisub/src/audio_box.cpp b/aegisub/src/audio_box.cpp index 1ded485a7..a632eb82a 100644 --- a/aegisub/src/audio_box.cpp +++ b/aegisub/src/audio_box.cpp @@ -62,7 +62,7 @@ /// @brief Constructor /// @param parent /// -AudioBox::AudioBox(wxWindow *parent) : +AudioBox::AudioBox(wxWindow *parent, SubtitlesGrid *grid) : wxPanel(parent,-1,wxDefaultPosition,wxDefaultSize,wxTAB_TRAVERSAL|wxBORDER_RAISED) { // Setup @@ -75,7 +75,7 @@ wxPanel(parent,-1,wxDefaultPosition,wxDefaultSize,wxTAB_TRAVERSAL|wxBORDER_RAISE audioScroll->SetToolTip(_("Seek bar")); Sash = new wxSashWindow(this,Audio_Sash,wxDefaultPosition,wxDefaultSize,wxCLIP_CHILDREN | wxSW_3DBORDER); sashSizer = new wxBoxSizer(wxVERTICAL); - audioDisplay = new AudioDisplay(Sash); + audioDisplay = new AudioDisplay(Sash, grid); sashSizer->Add(audioDisplay,1,wxEXPAND,0); Sash->SetSizer(sashSizer); Sash->SetSashVisible(wxSASH_BOTTOM,true); diff --git a/aegisub/src/audio_box.h b/aegisub/src/audio_box.h index c1de1288a..d847890ab 100644 --- a/aegisub/src/audio_box.h +++ b/aegisub/src/audio_box.h @@ -60,6 +60,7 @@ class AudioDisplay; class AudioKaraoke; class FrameMain; +class SubtitlesGrid; class wxToggleButton; class ToggleBitmap; @@ -197,7 +198,7 @@ public: /// DOCME bool karaokeMode; - AudioBox(wxWindow *parent); + AudioBox(wxWindow *parent, SubtitlesGrid *grid); ~AudioBox(); void SetFile(wxString file,bool FromVideo); diff --git a/aegisub/src/audio_display.cpp b/aegisub/src/audio_display.cpp index ebf0972be..5a8c72995 100644 --- a/aegisub/src/audio_display.cpp +++ b/aegisub/src/audio_display.cpp @@ -79,9 +79,9 @@ /// @brief Constructor /// @param parent -AudioDisplay::AudioDisplay(wxWindow *parent) +AudioDisplay::AudioDisplay(wxWindow *parent, SubtitlesGrid *grid) : wxWindow (parent, -1, wxDefaultPosition, wxSize(200,OPT_GET("Audio/Display Height")->GetInt()), AudioDisplayWindowStyle , _T("Audio Display")) -, grid(0) +, grid(grid) { // Set variables origImage = NULL; @@ -99,7 +99,6 @@ AudioDisplay::AudioDisplay(wxWindow *parent) loaded = false; temporary = false; blockUpdate = false; - dontReadTimes = false; holding = false; draggingScale = false; Position = 0; @@ -127,6 +126,9 @@ AudioDisplay::AudioDisplay(wxWindow *parent) if (OPT_GET("Audio/Display/Draw/Video Position")->GetBool()) vc->AddSeekListener(&AudioDisplay::UpdateImage, this, false); + grid->AddSelectionListener(this); + commitListener = grid->ass->AddCommitListener(&AudioDisplay::OnCommit, this); + // Set cursor //wxCursor cursor(wxCURSOR_BLANK); //SetCursor(cursor); @@ -1119,28 +1121,24 @@ void AudioDisplay::SetSelection(int start, int end) { /// @param diag /// @param n /// @return -void AudioDisplay::SetDialogue(SubtitlesGrid *_grid,AssDialogue *diag,int n) { - // Actual parameters - if (_grid) { - // Set variables - grid = _grid; - line_n = n; - dialogue = diag; +void AudioDisplay::SetDialogue(SubtitlesGrid *,AssDialogue *diag,int n) { + // Set variables + line_n = n; + dialogue = diag; - // Set flags - diagUpdated = false; - NeedCommit = false; + // Set flags + diagUpdated = false; + NeedCommit = false; - // Set times - if (dialogue && !dontReadTimes && OPT_GET("Audio/Grab Times on Select")->GetBool()) { - int s = dialogue->Start.GetMS(); - int e = dialogue->End.GetMS(); + // Set times + if (dialogue && OPT_GET("Audio/Grab Times on Select")->GetBool()) { + int s = dialogue->Start.GetMS(); + int e = dialogue->End.GetMS(); - // Never do it for 0:00:00.00->0:00:00.00 lines - if (s != 0 || e != 0) { - curStartMS = s; - curEndMS = e; - } + // Never do it for 0:00:00.00->0:00:00.00 lines + if (s != 0 || e != 0) { + curStartMS = s; + curEndMS = e; } } @@ -1163,11 +1161,11 @@ void AudioDisplay::SetDialogue(SubtitlesGrid *_grid,AssDialogue *diag,int n) { void AudioDisplay::CommitChanges (bool nextLine) { // Loaded? if (!loaded) return; + commitListener.Block(); // Check validity - bool textNeedsCommit = grid->GetDialogue(line_n)->Text != grid->editBox->TextEdit->GetText(); bool timeNeedsCommit = grid->GetDialogue(line_n)->Start.GetMS() != curStartMS || grid->GetDialogue(line_n)->End.GetMS() != curEndMS; - if (timeNeedsCommit || textNeedsCommit) NeedCommit = true; + NeedCommit = timeNeedsCommit; bool wasKaraSplitting = false; bool validCommit = true; if (!karaoke->enabled && !karaoke->splitting) { @@ -1208,7 +1206,7 @@ void AudioDisplay::CommitChanges (bool nextLine) { curDiag->Start.SetMS(curStartMS); curDiag->End.SetMS(curEndMS); } - if (!karaoke->enabled && textNeedsCommit) { + if (!karaoke->enabled) { // If user was editing karaoke stuff, that should take precedence of manual changes in the editbox, // so only update from editbox when not in kara mode curDiag->Text = grid->editBox->TextEdit->GetText(); @@ -1216,15 +1214,7 @@ void AudioDisplay::CommitChanges (bool nextLine) { if (!grid->IsInSelection(line_n)) break; } - // Update edit box - grid->editBox->StartTime->Update(); - grid->editBox->EndTime->Update(); - grid->editBox->Duration->Update(); - - // Update grid - grid->editBox->Update(!karaoke->enabled); - grid->ass->Commit(_T("")); - grid->CommitChanges(); + grid->ass->Commit(_T(""), karaoke->enabled ? AssFile::COMMIT_TEXT : AssFile::COMMIT_TIMES); karaoke->SetSelection(karaSelStart, karaSelEnd); blockUpdate = false; } @@ -1240,24 +1230,19 @@ void AudioDisplay::CommitChanges (bool nextLine) { def->End.SetMS(def->End.GetMS()+OPT_GET("Timing/Default Duration")->GetInt()); def->Style = grid->GetDialogue(line_n)->Style; grid->InsertLine(def,line_n,true); - curStartMS = curEndMS; - curEndMS = curStartMS + OPT_GET("Timing/Default Duration")->GetInt(); } - else if (grid->GetDialogue(line_n+1)->Start.GetMS() == 0 && grid->GetDialogue(line_n+1)->End.GetMS() == 0) { - curStartMS = curEndMS; - curEndMS = curStartMS + OPT_GET("Timing/Default Duration")->GetInt(); + int endMs = curEndMS; + + grid->NextLine(); + curStartMS = grid->GetActiveLine()->Start.GetMS(); + curEndMS = grid->GetActiveLine()->End.GetMS(); + if (curStartMS == 0 && curEndMS == 0) { + curStartMS = endMs; + curEndMS = endMs + OPT_GET("Timing/Default Duration")->GetInt(); } - else { - curStartMS = grid->GetDialogue(line_n+1)->Start.GetMS(); - curEndMS = grid->GetDialogue(line_n+1)->End.GetMS(); - } - - // Go to next - dontReadTimes = true; - ChangeLine(1,sel.GetCount() > 1 ? true : false); - dontReadTimes = false; } + commitListener.Unblock(); Update(); } @@ -1277,7 +1262,6 @@ void AudioDisplay::AddLead(bool in,bool out) { } // Set changes - UpdateTimeEditCtrls(); NeedCommit = true; if (OPT_GET("Audio/Auto/Commit")->GetBool()) CommitChanges(); Update(); @@ -1674,7 +1658,6 @@ void AudioDisplay::OnMouseEvent(wxMouseEvent& event) { diagUpdated = false; NeedCommit = true; if (curStartMS <= curEndMS) { - UpdateTimeEditCtrls(); if (OPT_GET("Audio/Auto/Commit")->GetBool()) CommitChanges(); } @@ -2218,10 +2201,12 @@ void AudioDisplay::OnLoseFocus(wxFocusEvent &event) { Refresh(false); } } - -/// @brief Update time edit controls -void AudioDisplay::UpdateTimeEditCtrls() { - grid->editBox->StartTime->SetTime(curStartMS); - grid->editBox->EndTime->SetTime(curEndMS); - grid->editBox->Duration->SetTime(curEndMS-curStartMS); +void AudioDisplay::OnActiveLineChanged(AssDialogue *new_line) { + SetDialogue(grid,new_line,grid->GetDialogueIndex(new_line)); +} +void AudioDisplay::OnSelectedSetChanged(const Selection &lines_added, const Selection &lines_removed) { +} +void AudioDisplay::OnCommit(int type) { + AssDialogue *line = grid->GetActiveLine(); + SetDialogue(grid,line,grid->GetDialogueIndex(line)); } diff --git a/aegisub/src/audio_display.h b/aegisub/src/audio_display.h index f6680aad6..6758f74b8 100644 --- a/aegisub/src/audio_display.h +++ b/aegisub/src/audio_display.h @@ -45,7 +45,10 @@ #include #endif +#include + #include "audio_renderer_spectrum.h" +#include "selection_controller.h" class AudioBox; class AudioKaraoke; @@ -61,7 +64,7 @@ class VideoProvider; /// @brief DOCME /// /// DOCME -class AudioDisplay: public wxWindow { +class AudioDisplay: public wxWindow, private SelectionListener { friend class FrameMain; private: @@ -201,6 +204,11 @@ private: int GetBoundarySnap(int x,int range,bool shiftHeld,bool start=true); void DoUpdateImage(); + void OnActiveLineChanged(AssDialogue *new_line); + void OnSelectedSetChanged(const Selection &lines_added, const Selection &lines_removed); + void OnCommit(int); + agi::signal::Connection commitListener; + public: /// DOCME @@ -235,7 +243,7 @@ public: /// DOCME wxTimer UpdateTimer; - AudioDisplay(wxWindow *parent); + AudioDisplay(wxWindow *parent, SubtitlesGrid *grid); ~AudioDisplay(); void UpdateImage(bool weak=false); @@ -251,7 +259,6 @@ public: void Next(bool play=true); void Prev(bool play=true); - void UpdateTimeEditCtrls(); void CommitChanges(bool nextLine=false); void AddLead(bool in,bool out); diff --git a/aegisub/src/base_grid.cpp b/aegisub/src/base_grid.cpp index b292ac62e..a2e50f259 100644 --- a/aegisub/src/base_grid.cpp +++ b/aegisub/src/base_grid.cpp @@ -196,7 +196,6 @@ void BaseGrid::UpdateMaps(bool preserve_selected_rows) { std::bind1st(std::mem_fun(&BaseGrid::GetDialogueIndex), this)); } - active_line = NULL; index_line_map.clear(); line_index_map.clear(); @@ -238,8 +237,14 @@ void BaseGrid::UpdateMaps(bool preserve_selected_rows) { SetSelectedSet(new_sel); } + // Force a reannounce of the active line if it hasn't changed, as it isn't + // safe to touch the active line while processing a commit event which would + // cause this function to be called + AssDialogue *line = active_line; + active_line = NULL; + // The active line may have ceased to exist; pick a new one if so - if (line_index_map.size() && line_index_map.find(active_line) == line_index_map.end()) { + if (line_index_map.size() && line_index_map.find(line) == line_index_map.end()) { if (active_row < (int)index_line_map.size()) { SetActiveLine(index_line_map[active_row]); } @@ -250,6 +255,9 @@ void BaseGrid::UpdateMaps(bool preserve_selected_rows) { SetActiveLine(index_line_map.back()); } } + else { + SetActiveLine(line); + } if (selection.empty() && active_line) { Selection sel; diff --git a/aegisub/src/dialog_detached_video.cpp b/aegisub/src/dialog_detached_video.cpp index 1d06d6858..138711f1d 100644 --- a/aegisub/src/dialog_detached_video.cpp +++ b/aegisub/src/dialog_detached_video.cpp @@ -45,6 +45,7 @@ #include "dialog_detached_video.h" #include "frame_main.h" #include "main.h" +#include "subs_grid.h" #include "video_box.h" #include "video_context.h" #include "video_display.h" @@ -75,7 +76,7 @@ DialogDetachedVideo::DialogDetachedVideo(FrameMain *par, const wxSize &initialDi wxPanel *panel = new wxPanel(this,-1,wxDefaultPosition,wxDefaultSize,wxTAB_TRAVERSAL | wxCLIP_CHILDREN); // Video area; - videoBox = new VideoBox(panel, true, NULL); + videoBox = new VideoBox(panel, true, NULL, VideoContext::Get()->grid->ass); videoBox->videoDisplay->freeSize = true; videoBox->videoDisplay->SetClientSize(initialDisplaySize); videoBox->videoSlider->grid = par->SubsGrid; diff --git a/aegisub/src/dialog_fonts_collector.cpp b/aegisub/src/dialog_fonts_collector.cpp index 7047e1654..f9210ca63 100644 --- a/aegisub/src/dialog_fonts_collector.cpp +++ b/aegisub/src/dialog_fonts_collector.cpp @@ -54,7 +54,6 @@ #include "compat.h" #include "dialog_fonts_collector.h" #include "font_file_lister.h" -#include "frame_main.h" #include "help_button.h" #include "libresrc/libresrc.h" #include "main.h" @@ -94,9 +93,6 @@ DialogFontsCollector::DialogFontsCollector(wxWindow *parent, AssFile *ass) // Set icon SetIcon(BitmapToIcon(GETIMAGE(font_collector_button_24))); - // Parent - main = (FrameMain*) parent; - // Destination box wxString dest = lagi_wxString(OPT_GET("Path/Fonts Collector Destination")->GetString()); if (dest == _T("?script")) { @@ -515,7 +511,6 @@ void FontsCollectorThread::Collect() { if (oper == 3 && someOk) { wxMutexGuiEnter(); subs->Commit(_("font attachment")); - collector->main->SubsGrid->CommitChanges(); wxMutexGuiLeave(); } } diff --git a/aegisub/src/dialog_fonts_collector.h b/aegisub/src/dialog_fonts_collector.h index 98b984937..7be8a6827 100644 --- a/aegisub/src/dialog_fonts_collector.h +++ b/aegisub/src/dialog_fonts_collector.h @@ -46,7 +46,6 @@ class AssFile; class AssOverrideParameter; class DialogFontsCollector; -class FrameMain; class wxZipOutputStream; class ScintillaTextCtrl; @@ -133,9 +132,6 @@ class DialogFontsCollector : public wxDialog { /// DOCME wxRadioBox *CollectAction; - /// DOCME - FrameMain *main; - void OnStart(wxCommandEvent &event); void OnClose(wxCommandEvent &event); void OnBrowse(wxCommandEvent &event); @@ -161,5 +157,3 @@ struct ColourString { /// DOCME int colour; }; - - diff --git a/aegisub/src/dialog_kara_timing_copy.cpp b/aegisub/src/dialog_kara_timing_copy.cpp index 0eeb856c9..c99699d85 100644 --- a/aegisub/src/dialog_kara_timing_copy.cpp +++ b/aegisub/src/dialog_kara_timing_copy.cpp @@ -941,8 +941,6 @@ void DialogKanjiTimer::OnClose(wxCommandEvent &event) { } if (modified) { grid->ass->Commit(_("kanji timing")); - grid->CommitChanges(); - grid->UpdateMaps(); LinesToChange.clear(); } Close(); diff --git a/aegisub/src/dialog_resample.cpp b/aegisub/src/dialog_resample.cpp index 4ab842757..90321b637 100644 --- a/aegisub/src/dialog_resample.cpp +++ b/aegisub/src/dialog_resample.cpp @@ -320,8 +320,7 @@ void DialogResample::OnResample (wxCommandEvent &event) { subs->SetScriptInfo(_T("PlayResY"),wxString::Format(_T("%i"),y2)); // Flag as modified - subs->Commit(_("resolution resampling")); - grid->CommitChanges(); + subs->Commit(_("resolution resampling"), AssFile::COMMIT_TEXT); EndModal(0); } diff --git a/aegisub/src/dialog_search_replace.cpp b/aegisub/src/dialog_search_replace.cpp index 86306c3fa..f2bd3de33 100644 --- a/aegisub/src/dialog_search_replace.cpp +++ b/aegisub/src/dialog_search_replace.cpp @@ -186,8 +186,6 @@ END_EVENT_TABLE() /// @param event /// void DialogSearchReplace::OnClose (wxCommandEvent &event) { - Search.OnDialogClose(); - // Just hide Show(false); } @@ -435,8 +433,7 @@ void SearchReplaceEngine::ReplaceNext(bool DoReplace) { } // Commit - grid->ass->Commit(_("replace")); - grid->CommitChanges(); + grid->ass->Commit(_("replace"), AssFile::COMMIT_TEXT); } else { @@ -453,7 +450,6 @@ void SearchReplaceEngine::ReplaceNext(bool DoReplace) { // Update video if (updateVideo) { - grid->CommitChanges(); grid->SetVideoToSubs(true); } else if (DoReplace) Modified = true; @@ -541,8 +537,7 @@ void SearchReplaceEngine::ReplaceAll() { // Commit if (count > 0) { - grid->ass->Commit(_("replace")); - grid->CommitChanges(); + grid->ass->Commit(_("replace"), AssFile::COMMIT_TEXT); wxMessageBox(wxString::Format(_("%i matches were replaced."),count)); } @@ -572,16 +567,6 @@ void SearchReplaceEngine::OnDialogOpen() { replaceLen = 0; } - - -/// @brief Search dialog closed -/// -void SearchReplaceEngine::OnDialogClose() { - if (Modified) grid->CommitChanges(); -} - - - /// @brief Open dialog /// @param replace /// @return diff --git a/aegisub/src/dialog_search_replace.h b/aegisub/src/dialog_search_replace.h index 49fa23b3a..148f76ee6 100644 --- a/aegisub/src/dialog_search_replace.h +++ b/aegisub/src/dialog_search_replace.h @@ -123,7 +123,6 @@ public: void ReplaceAll(); void OpenDialog(bool HasReplace); void OnDialogOpen(); - void OnDialogClose(); SearchReplaceEngine(); friend class DialogSearchReplace; diff --git a/aegisub/src/dialog_shift_times.cpp b/aegisub/src/dialog_shift_times.cpp index ffc1480df..1faee1288 100644 --- a/aegisub/src/dialog_shift_times.cpp +++ b/aegisub/src/dialog_shift_times.cpp @@ -309,8 +309,7 @@ void DialogShiftTimes::OnOK(wxCommandEvent &event) { OPT_SET("Tool/Shift Times/Direction")->SetBool(backward); // End dialog - grid->ass->Commit(_("shifting")); - grid->CommitChanges(); + grid->ass->Commit(_("shifting"), AssFile::COMMIT_TIMES); EndModal(0); } diff --git a/aegisub/src/dialog_spellchecker.cpp b/aegisub/src/dialog_spellchecker.cpp index f27d5be22..b1d63077a 100644 --- a/aegisub/src/dialog_spellchecker.cpp +++ b/aegisub/src/dialog_spellchecker.cpp @@ -390,8 +390,7 @@ void DialogSpellChecker::Replace() { lastPos = wordStart + replaceWord->GetValue().Length(); // Commit - grid->ass->Commit(_("Spell check replace")); - grid->CommitChanges(); + grid->ass->Commit(_("Spell check replace"), AssFile::COMMIT_TEXT); } diff --git a/aegisub/src/dialog_style_editor.cpp b/aegisub/src/dialog_style_editor.cpp index e5b50d6b0..1f3f05154 100644 --- a/aegisub/src/dialog_style_editor.cpp +++ b/aegisub/src/dialog_style_editor.cpp @@ -580,8 +580,7 @@ void DialogStyleEditor::Apply (bool apply,bool close) { *style = *work; style->UpdateData(); if (isLocal) { - grid->ass->Commit(_("style change")); - grid->CommitChanges(); + grid->ass->Commit(_("style change"), AssFile::COMMIT_TEXT); } // Exit diff --git a/aegisub/src/dialog_style_manager.cpp b/aegisub/src/dialog_style_manager.cpp index 93bb187b4..ae92c6ab8 100644 --- a/aegisub/src/dialog_style_manager.cpp +++ b/aegisub/src/dialog_style_manager.cpp @@ -607,7 +607,6 @@ void DialogStyleManager::OnCopyToCurrent (wxCommandEvent &) { CurrentList->SetStringSelection(*name, true); } grid->ass->Commit(_("style copy")); - grid->CommitChanges(); wxCommandEvent dummy; OnCurrentChange(dummy); } @@ -656,7 +655,6 @@ void DialogStyleManager::OnCurrentCopy (wxCommandEvent &) { else delete temp; grid->ass->Commit(_("style copy")); - grid->CommitChanges(); UpdateMoveButtons(); } @@ -709,7 +707,6 @@ void DialogStyleManager::PasteToCurrent() { LoadCurrentStyles(grid->ass); grid->ass->Commit(_("style paste")); - grid->CommitChanges(); } else wxMessageBox(_("Could not parse style"), _("Could not parse style"), wxOK | wxICON_EXCLAMATION , this); @@ -855,7 +852,6 @@ void DialogStyleManager::OnCurrentDelete (wxCommandEvent &) { CurrentDelete->Enable(false); grid->ass->Commit(_("style delete")); - grid->CommitChanges(); } UpdateMoveButtons(); } @@ -917,7 +913,6 @@ void DialogStyleManager::OnCurrentImport(wxCommandEvent &) { if (modified) { LoadCurrentStyles(grid->ass); grid->ass->Commit(_("style import")); - grid->CommitChanges(); } } catch (...) { @@ -1114,7 +1109,6 @@ void DialogStyleManager::MoveStyles(bool storage, int type) { // Flag as modified grid->ass->Commit(_("style move")); - grid->CommitChanges(); } // Update diff --git a/aegisub/src/dialog_styling_assistant.cpp b/aegisub/src/dialog_styling_assistant.cpp index 47d06c32e..9f9634c99 100644 --- a/aegisub/src/dialog_styling_assistant.cpp +++ b/aegisub/src/dialog_styling_assistant.cpp @@ -169,8 +169,7 @@ wxDialog (parent, -1, _("Styling assistant"), wxDefaultPosition, wxDefaultSize, DialogStyling::~DialogStyling () { GetPosition(&lastx, &lasty); if (needCommit) { - grid->ass->Commit(_("style changes")); - grid->CommitChanges(); + grid->ass->Commit(_("style changes"), AssFile::COMMIT_TEXT); } } @@ -232,8 +231,7 @@ void DialogStyling::SetStyle (wxString curName, bool jump) { // Update grid/subs grid->Refresh(false); if (PreviewCheck->IsChecked()) { - grid->ass->Commit(_("styling assistant")); - grid->CommitChanges(); + grid->ass->Commit(_("styling assistant"), AssFile::COMMIT_TEXT); } else needCommit = true; @@ -264,8 +262,7 @@ void DialogStyling::OnActivate(wxActivateEvent &event) { // Dialog lost focus if (!event.GetActive()) { if (needCommit) { - grid->ass->Commit(_("styling assistant")); - grid->CommitChanges(); + grid->ass->Commit(_("styling assistant"), AssFile::COMMIT_TEXT); needCommit = false; } return; diff --git a/aegisub/src/dialog_timing_processor.cpp b/aegisub/src/dialog_timing_processor.cpp index 0e634bfc1..6d3aca2dd 100644 --- a/aegisub/src/dialog_timing_processor.cpp +++ b/aegisub/src/dialog_timing_processor.cpp @@ -541,6 +541,5 @@ void DialogTimingProcessor::Process() { } // Update grid - grid->ass->Commit(_("timing processor")); - grid->CommitChanges(); + grid->ass->Commit(_("timing processor"), AssFile::COMMIT_TIMES); } diff --git a/aegisub/src/dialog_translation.cpp b/aegisub/src/dialog_translation.cpp index bbb7b4a05..6d5d5e6fa 100644 --- a/aegisub/src/dialog_translation.cpp +++ b/aegisub/src/dialog_translation.cpp @@ -357,9 +357,7 @@ void DialogTranslation::OnTransBoxKey(wxKeyEvent &event) { // Update line cur->UpdateText(); cur->ClearBlocks(); - subs->Commit(_("translation assistant")); - grid->CommitChanges(); - ((FrameMain*)main)->UpdateTitle(); + subs->Commit(_("translation assistant"), AssFile::COMMIT_TEXT); UpdatePreview(); // Next diff --git a/aegisub/src/frame_main.cpp b/aegisub/src/frame_main.cpp index 702c1ea47..7381e2fe2 100644 --- a/aegisub/src/frame_main.cpp +++ b/aegisub/src/frame_main.cpp @@ -551,6 +551,8 @@ void FrameMain::InitMenu() { /// @brief Initialize contents void FrameMain::InitContents() { AssFile::top = ass = new AssFile; + ass->AddCommitListener(&FrameMain::OnSubtitlesFileChanged, this); + // Set a background panel StartupLog(_T("Create background panel")); Panel = new wxPanel(this,-1,wxDefaultPosition,wxDefaultSize,wxTAB_TRAVERSAL | wxCLIP_CHILDREN); @@ -563,7 +565,7 @@ void FrameMain::InitContents() { // Video area; StartupLog(_T("Create video box")); - videoBox = new VideoBox(Panel, false, ZoomBox); + videoBox = new VideoBox(Panel, false, ZoomBox, ass); TopSizer->Add(videoBox,0,wxEXPAND,0); // Subtitles area @@ -576,13 +578,13 @@ void FrameMain::InitContents() { // Audio area StartupLog(_T("Create audio box")); - audioBox = new AudioBox(Panel); + audioBox = new AudioBox(Panel, SubsGrid); audioBox->frameMain = this; VideoContext::Get()->audio = audioBox->audioDisplay; // Top sizer StartupLog(_T("Create subtitle editing box")); - EditBox = new SubsEditBox(Panel,SubsGrid, audioBox->audioDisplay); + EditBox = new SubsEditBox(Panel,SubsGrid); StartupLog(_T("Arrange controls in sizers")); ToolSizer = new wxBoxSizer(wxVERTICAL); ToolSizer->Add(audioBox,0,wxEXPAND | wxBOTTOM,5); @@ -682,7 +684,6 @@ void FrameMain::LoadSubtitles (wxString filename,wxString charset) { SubsGrid->ClearMaps(); if (isFile) { ass->Load(filename,charset); - SubsGrid->UpdateMaps(); if (SubsGrid->GetRows()) { SubsGrid->SetActiveLine(SubsGrid->GetDialogue(0)); SubsGrid->SelectRow(0); @@ -737,8 +738,6 @@ void FrameMain::LoadSubtitles (wxString filename,wxString charset) { // Update title bar UpdateTitle(); - - VideoContext::Get()->Refresh(); } /// @brief Save subtitles @@ -1109,7 +1108,6 @@ void FrameMain::LoadVideo(wxString file,bool autoload) { SubsGrid->ass->SetScriptInfo(_T("PlayResX"), wxString::Format(_T("%d"), vidx)); SubsGrid->ass->SetScriptInfo(_T("PlayResY"), wxString::Format(_T("%d"), vidy)); SubsGrid->ass->Commit(_("Change script resolution")); - SubsGrid->CommitChanges(); break; case 0: default: @@ -1119,7 +1117,6 @@ void FrameMain::LoadVideo(wxString file,bool autoload) { } } - SubsGrid->CommitChanges(); SetDisplayMode(1,-1); EditBox->UpdateFrameTiming(); @@ -1159,7 +1156,6 @@ void FrameMain::LoadVFR(wxString filename) { else { VideoContext::Get()->LoadTimecodes(filename); } - SubsGrid->CommitChanges(); EditBox->UpdateFrameTiming(); } diff --git a/aegisub/src/frame_main.h b/aegisub/src/frame_main.h index ebb9b411a..31a252e93 100644 --- a/aegisub/src/frame_main.h +++ b/aegisub/src/frame_main.h @@ -322,6 +322,9 @@ private: void RebuildRecentList(wxString listName,wxMenu *menu,int startID); void SynchronizeProject(bool FromSubs=false); + void OnSubtitlesFileChanged(); + + public: /// DOCME diff --git a/aegisub/src/frame_main_events.cpp b/aegisub/src/frame_main_events.cpp index d0769fbed..be9de9e42 100644 --- a/aegisub/src/frame_main_events.cpp +++ b/aegisub/src/frame_main_events.cpp @@ -914,10 +914,7 @@ void FrameMain::OnShift(wxCommandEvent&) { void FrameMain::OnOpenProperties (wxCommandEvent &) { VideoContext::Get()->Stop(); DialogProperties Properties(this, ass); - int res = Properties.ShowModal(); - if (res) { - SubsGrid->CommitChanges(); - } + Properties.ShowModal(); } /// @brief Open styles manager @@ -925,8 +922,6 @@ void FrameMain::OnOpenStylesManager(wxCommandEvent&) { VideoContext::Get()->Stop(); DialogStyleManager StyleManager(this,SubsGrid); StyleManager.ShowModal(); - EditBox->UpdateGlobals(); - SubsGrid->CommitChanges(); } /// @brief Open attachments @@ -1040,10 +1035,7 @@ void FrameMain::OnAutomationMacro (wxCommandEvent &event) { int first_sel = SubsGrid->GetFirstSelRow(); // Run the macro... activeMacroItems[event.GetId()-Menu_Automation_Macro]->Process(SubsGrid->ass, selected_lines, first_sel, this); - // Have the grid update its maps, this properly refreshes it to reflect the changed subs - SubsGrid->UpdateMaps(); SubsGrid->SetSelectionFromAbsolute(selected_lines); - SubsGrid->CommitChanges(); SubsGrid->EndBatch(); #endif } @@ -1113,9 +1105,7 @@ void FrameMain::OnSnapToScene (wxCommandEvent &) { } // Commit - SubsGrid->editBox->Update(true); - SubsGrid->ass->Commit(_("snap to scene")); - SubsGrid->CommitChanges(); + SubsGrid->ass->Commit(_("snap to scene"), AssFile::COMMIT_TIMES); } /// @brief Shift to frame @@ -1141,27 +1131,19 @@ void FrameMain::OnShiftToFrame (wxCommandEvent &) { } // Commit - SubsGrid->ass->Commit(_("shift to frame")); - SubsGrid->CommitChanges(false); - SubsGrid->editBox->Update(true); + SubsGrid->ass->Commit(_("shift to frame"), AssFile::COMMIT_TIMES); } /// @brief Undo void FrameMain::OnUndo(wxCommandEvent&) { VideoContext::Get()->Stop(); ass->Undo(); - UpdateTitle(); - SubsGrid->UpdateMaps(true); - VideoContext::Get()->Refresh(); } /// @brief Redo void FrameMain::OnRedo(wxCommandEvent&) { VideoContext::Get()->Stop(); ass->Redo(); - UpdateTitle(); - SubsGrid->UpdateMaps(true); - VideoContext::Get()->Refresh(); } /// @brief Find @@ -1331,22 +1313,16 @@ void FrameMain::OnSelect (wxCommandEvent &) { void FrameMain::OnSortStart (wxCommandEvent &) { ass->Sort(); ass->Commit(_("sort")); - SubsGrid->UpdateMaps(); - SubsGrid->CommitChanges(); } /// @brief Sort subtitles by end time void FrameMain::OnSortEnd (wxCommandEvent &) { ass->Sort(AssFile::CompEnd); ass->Commit(_("sort")); - SubsGrid->UpdateMaps(); - SubsGrid->CommitChanges(); } /// @brief Sort subtitles by style name void FrameMain::OnSortStyle (wxCommandEvent &) { ass->Sort(AssFile::CompStyle); ass->Commit(_("sort")); - SubsGrid->UpdateMaps(); - SubsGrid->CommitChanges(); } /// @brief Open styling assistant @@ -1535,7 +1511,6 @@ void FrameMain::OnMedusaShiftStartForward(wxCommandEvent &) { audioBox->audioDisplay->curStartMS += 10; audioBox->audioDisplay->Update(); audioBox->audioDisplay->wxWindow::Update(); - audioBox->audioDisplay->UpdateTimeEditCtrls(); } /// @brief DOCME @@ -1543,7 +1518,6 @@ void FrameMain::OnMedusaShiftStartBack(wxCommandEvent &) { audioBox->audioDisplay->curStartMS -= 10; audioBox->audioDisplay->Update(); audioBox->audioDisplay->wxWindow::Update(); - audioBox->audioDisplay->UpdateTimeEditCtrls(); } /// @brief DOCME @@ -1551,7 +1525,6 @@ void FrameMain::OnMedusaShiftEndForward(wxCommandEvent &) { audioBox->audioDisplay->curEndMS += 10; audioBox->audioDisplay->Update(); audioBox->audioDisplay->wxWindow::Update(); - audioBox->audioDisplay->UpdateTimeEditCtrls(); } /// @brief DOCME @@ -1559,7 +1532,6 @@ void FrameMain::OnMedusaShiftEndBack(wxCommandEvent &) { audioBox->audioDisplay->curEndMS -= 10; audioBox->audioDisplay->Update(); audioBox->audioDisplay->wxWindow::Update(); - audioBox->audioDisplay->UpdateTimeEditCtrls(); } /// @brief DOCME @@ -1590,3 +1562,11 @@ void FrameMain::OnMedusaPrev(wxCommandEvent &) { void FrameMain::OnMedusaEnter(wxCommandEvent &) { audioBox->audioDisplay->CommitChanges(true); } + +void FrameMain::OnSubtitlesFileChanged() { + if (OPT_GET("App/Auto/Save on Every Change")->GetBool()) { + if (ass->IsModified() && !ass->filename.empty()) SaveSubtitles(false); + } + + UpdateTitle(); +} diff --git a/aegisub/src/subs_edit_box.cpp b/aegisub/src/subs_edit_box.cpp index 142b02c4a..fd3fb7227 100644 --- a/aegisub/src/subs_edit_box.cpp +++ b/aegisub/src/subs_edit_box.cpp @@ -159,12 +159,11 @@ void bind_focus_handler(T *control, Event event, wxString value, wxString alt, w control->Bind(event, handler); } -SubsEditBox::SubsEditBox (wxWindow *parent, SubtitlesGrid *grid, AudioDisplay *audio) +SubsEditBox::SubsEditBox(wxWindow *parent, SubtitlesGrid *grid) : wxPanel(parent, -1, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL | wxRAISED_BORDER, "SubsEditBox") , line(NULL) , splitLineMode(false) , controlState(true) -, audio(audio) , grid(grid) { grid->editBox = this; @@ -329,12 +328,35 @@ SubsEditBox::SubsEditBox (wxWindow *parent, SubtitlesGrid *grid, AudioDisplay *a OnSize(evt); grid->AddSelectionListener(this); + grid->ass->AddCommitListener(&SubsEditBox::Update, this); } SubsEditBox::~SubsEditBox() { grid->RemoveSelectionListener(this); } -void SubsEditBox::Update(bool timeOnly, bool setAudio) { +void SubsEditBox::Update(int type) { + if (type == AssFile::COMMIT_FULL || type == AssFile::COMMIT_UNDO) { + /// @todo maybe preserve selection over undo? + StyleBox->Clear(); + StyleBox->Append(grid->ass->GetStyles()); + + ActorBox->Freeze(); + ActorBox->Clear(); + int nrows = grid->GetRows(); + for (int i=0;iGetDialogue(i)->Actor; + // OSX doesn't like combo boxes that are empty. + if (actor.empty()) actor = "Actor"; + if (ActorBox->FindString(actor) == wxNOT_FOUND) { + ActorBox->Append(actor); + } + } + ActorBox->Thaw(); + + TextEdit->SetSelection(0,0); + return; + } + SetControlsState(!!line); if (!line) { return; @@ -344,7 +366,7 @@ void SubsEditBox::Update(bool timeOnly, bool setAudio) { StartTime->SetTime(line->Start); EndTime->SetTime(line->End); Duration->SetTime(line->End-line->Start); - if (!timeOnly) { + if (type != AssFile::COMMIT_TIMES) { TextEdit->SetTextTo(line->Text); Layer->SetValue(line->Layer); MarginL->ChangeValue(line->GetMarginString(0,false)); @@ -357,32 +379,6 @@ void SubsEditBox::Update(bool timeOnly, bool setAudio) { ActorBox->SetStringSelection(line->Actor); } - if (setAudio) audio->SetDialogue(grid,line,grid->GetDialogueIndex(line)); - - SetEvtHandlerEnabled(true); -} - -void SubsEditBox::UpdateGlobals() { - SetEvtHandlerEnabled(false); - StyleBox->Clear(); - StyleBox->Append(grid->ass->GetStyles()); - - ActorBox->Freeze(); - ActorBox->Clear(); - int nrows = grid->GetRows(); - for (int i=0;iGetDialogue(i)->Actor; - // OSX doesn't like combo boxes that are empty. - if (actor.empty()) actor = "Actor"; - if (ActorBox->FindString(actor) == wxNOT_FOUND) { - ActorBox->Append(actor); - } - } - ActorBox->Thaw(); - - // Set subs update - OnActiveLineChanged(grid->GetActiveLine()); - TextEdit->SetSelection(0,0); SetEvtHandlerEnabled(true); } @@ -390,7 +386,7 @@ void SubsEditBox::OnActiveLineChanged(AssDialogue *new_line) { SetEvtHandlerEnabled(false); line = new_line; - Update(); + Update(AssFile::COMMIT_TEXT); /// @todo VideoContext should be doing this if (VideoContext::Get()->IsLoaded()) { @@ -464,9 +460,8 @@ void SubsEditBox::SetSelectedRows(setter set, T value, wxString desc, bool amend for_each(sel.begin(), sel.end(), std::tr1::bind(set, _1, value)); - commitId = grid->ass->Commit(desc, (amend && desc == lastCommitType) ? commitId : -1); + commitId = grid->ass->Commit(desc, AssFile::COMMIT_TEXT, (amend && desc == lastCommitType) ? commitId : -1); lastCommitType = desc; - grid->CommitChanges(false); } template @@ -476,7 +471,6 @@ void SubsEditBox::SetSelectedRows(T AssDialogue::*field, T value, wxString desc, void SubsEditBox::CommitText(wxString desc) { SetSelectedRows(&AssDialogue::Text, TextEdit->GetText(), desc, true); - audio->SetDialogue(grid,line,grid->GetDialogueIndex(line)); } void SubsEditBox::CommitTimes(TimeField field) { @@ -499,10 +493,7 @@ void SubsEditBox::CommitTimes(TimeField field) { } } - timeCommitId[field] = grid->ass->Commit(_("modify times"), timeCommitId[field]); - grid->CommitChanges(); - int sel0 = grid->GetFirstSelRow(); - audio->SetDialogue(grid,grid->GetDialogue(sel0),sel0); + timeCommitId[field] = grid->ass->Commit(_("modify times"), AssFile::COMMIT_TIMES, timeCommitId[field]); } void SubsEditBox::OnSize(wxSizeEvent &evt) { diff --git a/aegisub/src/subs_edit_box.h b/aegisub/src/subs_edit_box.h index 0f3735958..5b7e49276 100644 --- a/aegisub/src/subs_edit_box.h +++ b/aegisub/src/subs_edit_box.h @@ -42,7 +42,6 @@ #include "selection_controller.h" -class AudioDisplay; class AssDialogue; class SubtitlesGrid; class SubsTextEditCtrl; @@ -63,8 +62,6 @@ class wxTextCtrl; /// /// Controls the text edit and all surrounding controls class SubsEditBox : public wxPanel, protected SelectionListener { - friend class AudioDisplay; - enum TimeField { TIME_START = 0, TIME_END, @@ -85,7 +82,6 @@ class SubsEditBox : public wxPanel, protected SelectionListener { wxColour origBgColour; // Externally supplied controls - AudioDisplay *audio; SubtitlesGrid *grid; // Box controls @@ -185,23 +181,19 @@ class SubsEditBox : public wxPanel, protected SelectionListener { /// @param amend Coalesce sequences of commits of the same type template void SetSelectedRows(T AssDialogue::*field, T value, wxString desc, bool amend = false); + + /// @brief Reload the current line from the file + /// @param type AssFile::CommitType + void Update(int type); public: SubsTextEditCtrl *TextEdit; /// @brief Constructor /// @param parent Parent window /// @param grid Associated grid - /// @param audio Associated audio display - SubsEditBox(wxWindow *parent, SubtitlesGrid *grid, AudioDisplay *audio); + SubsEditBox(wxWindow *parent, SubtitlesGrid *grid); ~SubsEditBox(); - /// @brief Reload the current line from the file - /// @param timeOnly Only reload times - /// @param setAudio Also update the audio display - void Update(bool timeOnly = false, bool setAudio = true); - /// Reload non-line-specific things like styles from the file - void UpdateGlobals(); - /// @brief Enable or disable frame timing mode void UpdateFrameTiming(); }; diff --git a/aegisub/src/subs_grid.cpp b/aegisub/src/subs_grid.cpp index dd9402870..e9e34e7b6 100644 --- a/aegisub/src/subs_grid.cpp +++ b/aegisub/src/subs_grid.cpp @@ -111,6 +111,7 @@ SubtitlesGrid::SubtitlesGrid(FrameMain* parentFr, wxWindow *parent, wxWindowID i OnHighlightVisibleChange(*OPT_GET("Subtitle/Grid/Highlight Subtitles in Frame")); OPT_SUB("Subtitle/Grid/Highlight Subtitles in Frame", &SubtitlesGrid::OnHighlightVisibleChange, this); + ass->AddCommitListener(&SubtitlesGrid::OnCommit, this); } /// @brief Destructor @@ -118,6 +119,17 @@ SubtitlesGrid::~SubtitlesGrid() { ClearMaps(); } +void SubtitlesGrid::OnCommit(int type) { + if (type == AssFile::COMMIT_FULL) + UpdateMaps(); + else if (type == AssFile::COMMIT_UNDO) + UpdateMaps(true); + + if (type != AssFile::COMMIT_TIMES) + SetColumnWidths(); + Refresh(false); +} + /// @brief Popup menu /// @param alternate void SubtitlesGrid::OnPopupMenu(bool alternate) { @@ -385,7 +397,6 @@ void SubtitlesGrid::OnSplitByKaraoke (wxCommandEvent &) { } if (didSplit) { ass->Commit(_("splitting")); - CommitChanges(); } EndBatch(); } @@ -615,8 +626,6 @@ void SubtitlesGrid::OnRecombine(wxCommandEvent &) { } ass->Commit(_("combining")); - UpdateMaps(); - CommitChanges(); // Remove now non-existent lines from the selection Selection lines; @@ -724,15 +733,6 @@ void SubtitlesGrid::LoadDefault () { SelectRow(0); } -/// @brief Update internal data structures -void SubtitlesGrid::UpdateMaps(bool preserve_selected_rows) { - BaseGrid::UpdateMaps(preserve_selected_rows); - - if (editBox) { - editBox->UpdateGlobals(); - } -} - /// @brief Swaps two lines /// @param n1 /// @param n2 @@ -744,7 +744,6 @@ void SubtitlesGrid::SwapLines(int n1,int n2) { std::swap(*dlg1, *dlg2); ass->Commit(_("swap lines")); - CommitChanges(); } /// @brief Insert a line @@ -758,12 +757,13 @@ void SubtitlesGrid::InsertLine(AssDialogue *line,int n,bool after,bool update) { if (after) ++pos; entryIter newIter = ass->Line.insert(pos,line); - BaseGrid::UpdateMaps(); // Update if (update) { ass->Commit(_("line insertion")); - CommitChanges(); + } + else { + UpdateMaps(); } } @@ -876,10 +876,7 @@ void SubtitlesGrid::PasteLines(int n,bool pasteOver) { // Update data post-insertion if (inserted > 0) { - // Commit - UpdateMaps(); - ass->Commit(_("paste")); - CommitChanges(); + ass->Commit(_("paste"), pasteOver ? AssFile::COMMIT_TEXT : AssFile::COMMIT_FULL); // Set selection if (!pasteOver) { @@ -920,11 +917,11 @@ void SubtitlesGrid::DeleteLines(wxArrayInt target, bool flagModified) { old_active_line_index = 0; } - UpdateMaps(); - if (flagModified) { ass->Commit(_("delete")); - CommitChanges(); + } + else { + UpdateMaps(); } } @@ -975,7 +972,6 @@ void SubtitlesGrid::JoinLines(int n1,int n2,bool concat) { DeleteLines(GetRangeArray(n1+1,n2), false); ass->Commit(_("join lines")); - CommitChanges(); // Select new line SetActiveLine(cur); @@ -1016,7 +1012,6 @@ void SubtitlesGrid::AdjoinLines(int n1,int n2,bool setStart) { } ass->Commit(_("adjoin")); - CommitChanges(); } void SubtitlesGrid::JoinAsKaraoke(int n1,int n2) { @@ -1059,7 +1054,6 @@ void SubtitlesGrid::JoinAsKaraoke(int n1,int n2) { DeleteLines(GetRangeArray(n1+1,n2), false); ass->Commit(_("join as karaoke")); - CommitChanges(); // Select new line SetActiveLine(cur); @@ -1128,7 +1122,6 @@ void SubtitlesGrid::SplitLine(AssDialogue *n1,int pos,bool estimateTimes) { } ass->Commit(_("split")); - CommitChanges(); } bool SubtitlesGrid::SplitLineByKaraoke(int lineNumber) { @@ -1170,35 +1163,6 @@ bool SubtitlesGrid::SplitLineByKaraoke(int lineNumber) { return true; } -void SubtitlesGrid::CommitChanges(bool ebox, bool video, bool autosave) { - if (video && context->IsLoaded()) { - bool playing = false; - if (context->IsPlaying()) { - playing = true; - context->Stop(); - } - - context->Refresh(); - - if (playing) context->Play(); - } - - if (autosave) { - // Autosave if option is enabled - if (OPT_GET("App/Auto/Save on Every Change")->GetBool()) { - if (ass->IsModified() && !ass->filename.IsEmpty()) parentFrame->SaveSubtitles(false); - } - - // Update parent frame - parentFrame->UpdateTitle(); - SetColumnWidths(); - Refresh(false); - } - if (ebox) { - editBox->Update(false, false); - } -} - void SubtitlesGrid::SetSubsToVideo(bool start) { if (!context->IsLoaded()) return; @@ -1218,9 +1182,7 @@ void SubtitlesGrid::SetSubsToVideo(bool start) { } if (modified) { - ass->Commit(_("timing")); - CommitChanges(); - editBox->Update(true); + ass->Commit(_("timing"), AssFile::COMMIT_TIMES); } } diff --git a/aegisub/src/subs_grid.h b/aegisub/src/subs_grid.h index bed7fd4a9..5d1332860 100644 --- a/aegisub/src/subs_grid.h +++ b/aegisub/src/subs_grid.h @@ -97,6 +97,8 @@ private: void OnHighlightVisibleChange(agi::OptionValue const& opt); + void OnCommit(int type); + public: /// Currently open file AssFile *ass; @@ -105,13 +107,6 @@ public: ~SubtitlesGrid(); void LoadDefault(); - /// @brief Commit changes and update the current file - /// @param ebox Update the edit box - /// @param video Update the video display - /// @param complete Autosave (if enabled) and update other things which care about the file - void CommitChanges(bool ebox = true, bool video = true, bool complete = true); - - void UpdateMaps(bool preserve_selected_rows = false); /// @brief Jump to the start/end time of the current subtitle line /// @param start Start vs. End time diff --git a/aegisub/src/video_box.cpp b/aegisub/src/video_box.cpp index bc0cbef50..58f373bea 100644 --- a/aegisub/src/video_box.cpp +++ b/aegisub/src/video_box.cpp @@ -63,7 +63,7 @@ /// @param parent /// @param isDetached /// -VideoBox::VideoBox(wxWindow *parent, bool isDetached, wxComboBox *zoomBox) +VideoBox::VideoBox(wxWindow *parent, bool isDetached, wxComboBox *zoomBox, AssFile *ass) : wxPanel (parent,-1) { // Parent @@ -112,7 +112,7 @@ VideoBox::VideoBox(wxWindow *parent, bool isDetached, wxComboBox *zoomBox) visualToolBar->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE)); // Display - videoDisplay = new VideoDisplay(this,videoSlider,VideoPosition,VideoSubsPos,zoomBox,videoPage,-1,wxDefaultPosition,wxDefaultSize,wxSUNKEN_BORDER); + videoDisplay = new VideoDisplay(this,VideoPosition,VideoSubsPos,zoomBox,videoPage,ass); // Set display videoSlider->Display = videoDisplay; diff --git a/aegisub/src/video_box.h b/aegisub/src/video_box.h index f3d2917f8..1bc72c9a5 100644 --- a/aegisub/src/video_box.h +++ b/aegisub/src/video_box.h @@ -34,11 +34,6 @@ /// @ingroup main_ui video /// - - - -/////////// -// Headers #ifndef AGI_PRE #include #include @@ -47,9 +42,7 @@ #include #endif - -////////////// -// Prototypes +class AssFile; class VideoDisplay; class VideoSlider; class ToggleBitmap; @@ -104,7 +97,7 @@ public: /// DOCME VideoSlider *videoSlider; - VideoBox (wxWindow *parent, bool isDetached, wxComboBox *zoomBox); + VideoBox (wxWindow *parent, bool isDetached, wxComboBox *zoomBox, AssFile *ass); DECLARE_EVENT_TABLE() }; diff --git a/aegisub/src/video_context.cpp b/aegisub/src/video_context.cpp index 72e487653..d379085b1 100644 --- a/aegisub/src/video_context.cpp +++ b/aegisub/src/video_context.cpp @@ -30,7 +30,7 @@ // $Id$ /// @file video_context.cpp -/// @brief Keep track of loaded video and video displays +/// @brief Keep track of loaded video /// @ingroup video /// @@ -73,7 +73,6 @@ #include "utils.h" #include "video_box.h" #include "video_context.h" -#include "video_display.h" #include "video_frame.h" /// IDs @@ -100,7 +99,6 @@ VideoContext::VideoContext() , arType(0) , hasSubtitles(false) , playAudioOnStep(OPT_GET("Audio/Plays When Stepping Video")) -, singleFrame(false) , grid(NULL) , audio(NULL) , VFR_Input(videoFPS) @@ -167,8 +165,6 @@ void VideoContext::SetVideo(const wxString &filename) { if (filename.empty()) return; try { - grid->CommitChanges(true); - provider.reset(new ThreadedFrameSource(filename, this)); videoProvider = provider->GetVideoProvider(); videoFile = filename; @@ -207,6 +203,7 @@ void VideoContext::SetVideo(const wxString &filename) { } provider->LoadSubtitles(grid->ass); + grid->ass->AddCommitListener(&VideoContext::SubtitlesChanged, this); VideoOpen(); KeyframesOpen(keyFrames); } @@ -228,11 +225,16 @@ void VideoContext::Reload() { } } -void VideoContext::Refresh() { +void VideoContext::SubtitlesChanged() { if (!IsLoaded()) return; + bool wasPlaying = isPlaying; + Stop(); + provider->LoadSubtitles(grid->ass); - SubtitlesChange(); + GetFrameAsync(frame_n); + + if (wasPlaying) Play(); } void VideoContext::JumpToFrame(int n) { @@ -446,6 +448,7 @@ void VideoContext::SetAspectRatio(int type, double value) { arType = type; arValue = MID(.5, value, 5.); + ARChange(arType, arValue); } void VideoContext::LoadKeyframes(wxString filename) { @@ -488,7 +491,7 @@ void VideoContext::LoadTimecodes(wxString filename) { ovrFPS = agi::vfr::Framerate(STD_STR(filename)); ovrTimecodeFile = filename; config::mru->Add("Timecodes", STD_STR(filename)); - Refresh(); + SubtitlesChanged(); } catch (const agi::acs::AcsError&) { wxLogError(L"Could not open file " + filename); @@ -510,7 +513,7 @@ void VideoContext::SaveTimecodes(wxString filename) { void VideoContext::CloseTimecodes() { ovrFPS = agi::vfr::Framerate(); ovrTimecodeFile.clear(); - Refresh(); + SubtitlesChanged(); } int VideoContext::TimeAtFrame(int frame, agi::vfr::Time type) const { diff --git a/aegisub/src/video_context.h b/aegisub/src/video_context.h index bd7bf3879..f5fb22d81 100644 --- a/aegisub/src/video_context.h +++ b/aegisub/src/video_context.h @@ -62,7 +62,6 @@ class SubtitlesProviderErrorEvent; class ThreadedFrameSource; class VideoProvider; class VideoProviderErrorEvent; -class VideoDisplay; namespace agi { class OptionValue; @@ -77,20 +76,16 @@ class VideoContext : public wxEvtHandler { friend class AudioProvider; friend class KeyFrameFile; - /// Current frame number changed + /// Current frame number changed (new frame number) agi::signal::Signal Seek; /// A new video was opened agi::signal::Signal<> VideoOpen; - /// Subtitles file changed - /// @todo Move this to AssFile - agi::signal::Signal<> SubtitlesChange; - /// New keyframes opened + /// New keyframes opened (new keyframe data) agi::signal::Signal const&> KeyframesOpen; + /// Aspect ratio was changed (type, value) + agi::signal::Signal ARChange; private: - /// DOCME - std::list displayList; - /// DOCME std::tr1::shared_ptr videoProvider; @@ -156,8 +151,6 @@ private: agi::vfr::Framerate videoFPS; agi::vfr::Framerate ovrFPS; - bool singleFrame; - void OnVideoError(VideoProviderErrorEvent const& err); void OnSubtitlesError(SubtitlesProviderErrorEvent const& err); @@ -240,7 +233,7 @@ public: void JumpToTime(int ms, agi::vfr::Time end = agi::vfr::START); /// @brief Refresh the subtitle provider - void Refresh(); + void SubtitlesChanged(); /// @brief Get the height and width of the current script /// @param[out] w Width @@ -263,7 +256,7 @@ public: DEFINE_SIGNAL_ADDERS(Seek, AddSeekListener) DEFINE_SIGNAL_ADDERS(VideoOpen, AddVideoOpenListener) DEFINE_SIGNAL_ADDERS(KeyframesOpen, AddKeyframesOpenListener) - DEFINE_SIGNAL_ADDERS(SubtitlesChange, AddSubtitlesChangeListener) + DEFINE_SIGNAL_ADDERS(ARChange, AddARChangeListener) const std::vector& GetKeyFrames() const { return keyFrames; }; wxString GetKeyFramesName() const { return keyFramesFilename; } diff --git a/aegisub/src/video_display.cpp b/aegisub/src/video_display.cpp index da29ed34d..d32ba3b51 100644 --- a/aegisub/src/video_display.cpp +++ b/aegisub/src/video_display.cpp @@ -59,6 +59,7 @@ #include "video_display.h" #include "ass_dialogue.h" +#include "ass_file.h" #include "hotkeys.h" #include "main.h" #include "subs_grid.h" @@ -66,7 +67,6 @@ #include "video_out_gl.h" #include "video_box.h" #include "video_context.h" -#include "video_slider.h" #include "visual_tool.h" #include "visual_tool_clip.h" #include "visual_tool_cross.h" @@ -97,7 +97,6 @@ BEGIN_EVENT_TABLE(VideoDisplay, wxGLCanvas) EVT_PAINT(VideoDisplay::OnPaint) EVT_SIZE(VideoDisplay::OnSizeEvent) EVT_ERASE_BACKGROUND(VideoDisplay::OnEraseBackground) - EVT_SHOW(VideoDisplay::OnShow) EVT_MENU(VIDEO_MENU_COPY_COORDS,VideoDisplay::OnCopyCoords) EVT_MENU(VIDEO_MENU_COPY_TO_CLIPBOARD,VideoDisplay::OnCopyToClipboard) @@ -125,24 +124,17 @@ public: VideoDisplay::VideoDisplay( VideoBox *box, - VideoSlider *ControlSlider, wxTextCtrl *PositionDisplay, wxTextCtrl *SubsPosition, wxComboBox *zoomBox, wxWindow* parent, - wxWindowID id, - const wxPoint& pos, - const wxSize& size, - long style, - const wxString& name) -: wxGLCanvas (parent, id, attribList, pos, size, style, name) + AssFile *model) +: wxGLCanvas (parent, -1, attribList, wxDefaultPosition, wxDefaultSize, wxSUNKEN_BORDER, wxPanelNameStr) , alwaysShowTools(OPT_GET("Tool/Visual/Always Show")) -, origSize(size) +, vc(VideoContext::Get()) , currentFrame(-1) , w(8), h(8), viewport_x(0), viewport_width(0), viewport_bottom(0), viewport_top(0), viewport_height(0) -, locked(false) , zoomValue(OPT_GET("Video/Default Zoom")->GetInt() * .125 + .125) -, ControlSlider(ControlSlider) , SubsPosition(SubsPosition) , PositionDisplay(PositionDisplay) , videoOut(new VideoOutGL()) @@ -151,23 +143,28 @@ VideoDisplay::VideoDisplay( , scriptW(INT_MIN) , scriptH(INT_MIN) , zoomBox(zoomBox) +, model(model) , box(box) , freeSize(false) { + assert(vc); + assert(box); + assert(model); + if (zoomBox) zoomBox->SetValue(wxString::Format("%g%%", zoomValue * 100.)); box->Bind(wxEVT_COMMAND_TOOL_CLICKED, &VideoDisplay::OnMode, this, Video_Mode_Standard, Video_Mode_Vector_Clip); - VideoContext *vc = VideoContext::Get(); vc->Bind(EVT_FRAME_READY, &VideoDisplay::UploadFrameData, this); slots.push_back(vc->AddSeekListener(&VideoDisplay::SetFrame, this)); slots.push_back(vc->AddVideoOpenListener(&VideoDisplay::OnVideoOpen, this)); - slots.push_back(vc->AddSubtitlesChangeListener(&VideoDisplay::Refresh, this)); + slots.push_back(vc->AddARChangeListener(&VideoDisplay::UpdateSize, this)); + slots.push_back(model->AddCommitListener(&VideoDisplay::OnCommit, this)); SetCursor(wxNullCursor); } VideoDisplay::~VideoDisplay () { - VideoContext::Get()->Unbind(EVT_FRAME_READY, &VideoDisplay::UploadFrameData, this); + vc->Unbind(EVT_FRAME_READY, &VideoDisplay::UploadFrameData, this); } bool VideoDisplay::InitContext() { @@ -195,7 +192,7 @@ void VideoDisplay::UpdateRelativeTimes(int time) { int startOff = 0; int endOff = 0; - if (AssDialogue *curLine = VideoContext::Get()->grid->GetActiveLine()) { + if (AssDialogue *curLine = vc->grid->GetActiveLine()) { startOff = time - curLine->Start.GetMS(); endOff = time - curLine->End.GetMS(); } @@ -210,13 +207,11 @@ void VideoDisplay::UpdateRelativeTimes(int time) { void VideoDisplay::SetFrame(int frameNumber) { - VideoContext *context = VideoContext::Get(); - currentFrame = frameNumber; // Get time for frame { - int time = context->TimeAtFrame(frameNumber, agi::vfr::EXACT); + int time = vc->TimeAtFrame(frameNumber, agi::vfr::EXACT); int h = time / 3600000; int m = time % 3600000 / 60000; int s = time % 60000 / 1000; @@ -224,7 +219,7 @@ void VideoDisplay::SetFrame(int frameNumber) { // Set the text box for frame number and time PositionDisplay->SetValue(wxString::Format(L"%01i:%02i:%02i.%03i - %i", h, m, s, ms, frameNumber)); - if (std::binary_search(context->GetKeyFrames().begin(), context->GetKeyFrames().end(), frameNumber)) { + if (std::binary_search(vc->GetKeyFrames().begin(), vc->GetKeyFrames().end(), frameNumber)) { // Set the background color to indicate this is a keyframe PositionDisplay->SetBackgroundColour(lagi_wxColour(OPT_GET("Colour/Subtitle Grid/Background/Selection")->GetColour())); PositionDisplay->SetForegroundColour(lagi_wxColour(OPT_GET("Colour/Subtitle Grid/Selection")->GetColour())); @@ -238,9 +233,9 @@ void VideoDisplay::SetFrame(int frameNumber) { } // Render the new frame - if (context->IsLoaded()) { + if (vc->IsLoaded()) { tool->SetFrame(frameNumber); - context->GetFrameAsync(currentFrame); + vc->GetFrameAsync(currentFrame); } } @@ -256,7 +251,7 @@ void VideoDisplay::UploadFrameData(FrameReadyEvent &evt) { L"programs and updating your video card drivers may fix this.\n" L"Error message reported: %s", err.GetMessage().c_str()); - VideoContext::Get()->Reset(); + vc->Reset(); } catch (const VideoOutRenderException& err) { wxLogError( @@ -267,23 +262,24 @@ void VideoDisplay::UploadFrameData(FrameReadyEvent &evt) { Render(); } -void VideoDisplay::Refresh() { - if (!tool.get()) tool.reset(new VisualToolCross(this, video, toolBar)); - if (!InitContext()) return; - VideoContext::Get()->GetFrameAsync(currentFrame); - tool->Refresh(); - UpdateRelativeTimes(VideoContext::Get()->TimeAtFrame(currentFrame, agi::vfr::EXACT)); -} - void VideoDisplay::OnVideoOpen() { UpdateSize(); - Refresh(); + currentFrame = 0; + vc->GetFrameAsync(0); + UpdateRelativeTimes(0); + if (!tool.get()) tool.reset(new VisualToolCross(this, video, toolBar)); + tool->Refresh(); +} +void VideoDisplay::OnCommit(int type) { + if (type == AssFile::COMMIT_FULL || type == AssFile::COMMIT_UNDO) + vc->GetScriptSize(scriptW, scriptH); + if (tool.get()) tool->Refresh(); + UpdateRelativeTimes(vc->TimeAtFrame(currentFrame, agi::vfr::EXACT)); } void VideoDisplay::Render() try { if (!InitContext()) return; - VideoContext *context = VideoContext::Get(); - if (!context->IsLoaded()) return; + if (!vc->IsLoaded()) return; assert(wxIsMainThread()); if (!viewport_height || !viewport_width) UpdateSize(); @@ -295,7 +291,7 @@ void VideoDisplay::Render() try { E(glOrtho(0.0f, w, h, 0.0f, -1000.0f, 1000.0f)); if (OPT_GET("Video/Overscan Mask")->GetBool()) { - double ar = context->GetAspectRatioValue(); + double ar = vc->GetAspectRatioValue(); // Based on BBC's guidelines: http://www.bbc.co.uk/guidelines/dq/pdf/tv/tv_standards_london.pdf // 16:9 or wider @@ -312,7 +308,6 @@ void VideoDisplay::Render() try { } if (video.x > INT_MIN || video.y > INT_MIN || alwaysShowTools->GetBool()) { - context->GetScriptSize(scriptW, scriptH); tool->Draw(); } @@ -324,27 +319,27 @@ catch (const VideoOutException &err) { L"An error occurred trying to render the video frame on the screen.\n" L"Error message reported: %s", err.GetMessage().c_str()); - VideoContext::Get()->Reset(); + vc->Reset(); } catch (const OpenGlException &err) { wxLogError( L"An error occurred trying to render visual overlays on the screen.\n" L"Error message reported: %s", err.GetMessage().c_str()); - VideoContext::Get()->Reset(); + vc->Reset(); } catch (const wchar_t *err) { wxLogError( L"An error occurred trying to render the video frame on the screen.\n" L"Error message reported: %s", err); - VideoContext::Get()->Reset(); + vc->Reset(); } catch (...) { wxLogError( L"An error occurred trying to render the video frame to screen.\n" L"No further error message given."); - VideoContext::Get()->Reset(); + vc->Reset(); } void VideoDisplay::DrawOverscanMask(int sizeH, int sizeV, wxColor color, double alpha) const { @@ -372,15 +367,17 @@ void VideoDisplay::DrawOverscanMask(int sizeH, int sizeV, wxColor color, double E(glDisable(GL_BLEND)); } - -void VideoDisplay::UpdateSize() { - VideoContext *con = VideoContext::Get(); - wxASSERT(con); - if (!con->IsLoaded()) return; +void VideoDisplay::UpdateSize(int arType, double arValue) { + if (!vc->IsLoaded()) return; if (!IsShownOnScreen()) return; - int vidW = con->GetWidth(); - int vidH = con->GetHeight(); + int vidW = vc->GetWidth(); + int vidH = vc->GetHeight(); + + if (arType == -1) { + arType = vc->GetAspectRatioType(); + arValue = vc->GetAspectRatioValue(); + } if (freeSize) { GetClientSize(&w,&h); @@ -391,8 +388,8 @@ void VideoDisplay::UpdateSize() { viewport_height = h; // Set aspect ratio - float displayAr = float(w) / float(h); - float videoAr = con->GetAspectRatioType() == 0 ? float(vidW)/float(vidH) : con->GetAspectRatioValue(); + double displayAr = double(w) / h; + double videoAr = arType == 0 ? double(vidW)/vidH : arValue; // Window is wider than video, blackbox left/right if (displayAr - videoAr > 0.01f) { @@ -415,7 +412,7 @@ void VideoDisplay::UpdateSize() { parent->GetClientSize(&maxW, &maxH); h = vidH * zoomValue; - w = con->GetAspectRatioType() == 0 ? vidW * zoomValue : vidH * zoomValue * con->GetAspectRatioValue(); + w = arType == 0 ? vidW * zoomValue : vidH * zoomValue * arValue; // Cap the canvas size to the window size int cw = std::min(w, maxW), ch = std::min(h, maxH); @@ -430,7 +427,7 @@ void VideoDisplay::UpdateSize() { SetMinClientSize(size); SetMaxClientSize(size); - locked = true; + SetEvtHandlerEnabled(false); box->GetParent()->Layout(); // The sizer makes us use the full width, which at very low zoom levels @@ -438,10 +435,10 @@ void VideoDisplay::UpdateSize() { // parent window sizes, reset our size to the correct value SetSize(cw, ch); - locked = false; + SetEvtHandlerEnabled(true); } - con->GetScriptSize(scriptW, scriptH); + vc->GetScriptSize(scriptW, scriptH); video.w = w; video.h = h; @@ -450,22 +447,7 @@ void VideoDisplay::UpdateSize() { wxGLCanvas::Refresh(false); } -void VideoDisplay::Reset() { - // Only calculate sizes if it's visible - if (!IsShownOnScreen()) return; - int w = origSize.GetX(); - int h = origSize.GetY(); - wxASSERT(w > 0); - wxASSERT(h > 0); - SetClientSize(w,h); - GetSize(&w,&h); - wxASSERT(w > 0); - wxASSERT(h > 0); - SetSizeHints(w,h,w,h); -} - void VideoDisplay::OnPaint(wxPaintEvent&) { - wxPaintDC dc(this); Render(); } @@ -475,11 +457,10 @@ void VideoDisplay::OnSizeEvent(wxSizeEvent &event) { } void VideoDisplay::OnMouseEvent(wxMouseEvent& event) { - if (locked) return; assert(w > 0); // Disable when playing - if (VideoContext::Get()->IsPlaying()) return; + if (vc->IsPlaying()) return; if (event.ButtonUp(wxMOUSE_BTN_RIGHT)) { wxMenu menu; @@ -554,10 +535,6 @@ double VideoDisplay::GetZoom() const { return zoomValue; } -void VideoDisplay::OnShow(wxShowEvent&) { - OnVideoOpen(); -} - template void VideoDisplay::SetTool() { tool.reset(); @@ -609,24 +586,24 @@ void VideoDisplay::FromScriptCoords(int *x, int *y) const { void VideoDisplay::OnCopyToClipboard(wxCommandEvent &) { if (wxTheClipboard->Open()) { - wxTheClipboard->SetData(new wxBitmapDataObject(wxBitmap(VideoContext::Get()->GetFrame(currentFrame)->GetImage(),24))); + wxTheClipboard->SetData(new wxBitmapDataObject(wxBitmap(vc->GetFrame(currentFrame)->GetImage(),24))); wxTheClipboard->Close(); } } void VideoDisplay::OnCopyToClipboardRaw(wxCommandEvent &) { if (wxTheClipboard->Open()) { - wxTheClipboard->SetData(new wxBitmapDataObject(wxBitmap(VideoContext::Get()->GetFrame(currentFrame,true)->GetImage(),24))); + wxTheClipboard->SetData(new wxBitmapDataObject(wxBitmap(vc->GetFrame(currentFrame,true)->GetImage(),24))); wxTheClipboard->Close(); } } void VideoDisplay::OnSaveSnapshot(wxCommandEvent &) { - VideoContext::Get()->SaveSnapshot(false); + vc->SaveSnapshot(false); } void VideoDisplay::OnSaveSnapshotRaw(wxCommandEvent &) { - VideoContext::Get()->SaveSnapshot(true); + vc->SaveSnapshot(true); } void VideoDisplay::OnCopyCoords(wxCommandEvent &) { diff --git a/aegisub/src/video_display.h b/aegisub/src/video_display.h index 0549dcf2a..f96f1016d 100644 --- a/aegisub/src/video_display.h +++ b/aegisub/src/video_display.h @@ -45,9 +45,10 @@ #include // Prototypes +class AssFile; class FrameReadyEvent; -class VideoSlider; class VideoBox; +class VideoContext; class VideoOutGL; class IVisualTool; class wxToolBar; @@ -70,8 +71,9 @@ class VideoDisplay : public wxGLCanvas { std::list slots; const agi::OptionValue* alwaysShowTools; - /// The unscaled size of the displayed video - wxSize origSize; + + /// The video context providing video to this display + VideoContext *vc; /// The frame number currently being displayed int currentFrame; @@ -92,9 +94,6 @@ class VideoDisplay : public wxGLCanvas { /// The height of the video in screen pixels int viewport_height; - /// Lock to disable mouse updates during resize operations - bool locked; - /// @brief Draw an overscan mask /// @param sizeH The amount of horizontal overscan on one side /// @param sizeV The amount of vertical overscan on one side @@ -134,9 +133,6 @@ class VideoDisplay : public wxGLCanvas { /// The current zoom level, where 1.0 = 100% double zoomValue; - /// The video position slider - VideoSlider *ControlSlider; - /// The display for the the video position relative to the current subtitle line wxTextCtrl *SubsPosition; @@ -167,12 +163,9 @@ class VideoDisplay : public wxGLCanvas { /// @brief Set this video display to the given frame /// @frameNumber The desired frame number void SetFrame(int frameNumber); - /// @brief Signal that the file has changed - void Refresh(); + void OnVideoOpen(); - - void OnShow(wxShowEvent &event); - + void OnCommit(int type); void OnMode(const wxCommandEvent &event); void SetMode(int mode); @@ -190,6 +183,8 @@ class VideoDisplay : public wxGLCanvas { /// The dropdown box for selecting zoom levels wxComboBox *zoomBox; + AssFile *model; + public: /// The VideoBox this display is contained in VideoBox *box; @@ -198,27 +193,14 @@ public: bool freeSize; /// @brief Constructor - /// @param parent Pointer to a parent window. - /// @param id Window identifier. If -1, will automatically create an identifier. - /// @param pos Window position. wxDefaultPosition is (-1, -1) which indicates that wxWidgets should generate a default position for the window. - /// @param size Window size. wxDefaultSize is (-1, -1) which indicates that wxWidgets should generate a default size for the window. If no suitable size can be found, the window will be sized to 20x20 pixels so that the window is visible but obviously not correctly sized. - /// @param style Window style. - /// @param name Window name. VideoDisplay( VideoBox *box, - VideoSlider *ControlSlider, wxTextCtrl *PositionDisplay, wxTextCtrl *SubsPosition, wxComboBox *zoomBox, wxWindow* parent, - wxWindowID id, - const wxPoint& pos = wxDefaultPosition, - const wxSize& size = wxDefaultSize, - long style = 0, - const wxString& name = wxPanelNameStr); + AssFile *model); ~VideoDisplay(); - /// @brief Reset the size of the display to the video size - void Reset(); /// @brief Render the currently visible frame void Render(); @@ -227,7 +209,7 @@ public: /// @param show Whether or not the cursor should be visible void ShowCursor(bool show); /// @brief Set the size of the display based on the current zoom and video resolution - void UpdateSize(); + void UpdateSize(int arType = -1, double arValue = -1.); /// @brief Set the zoom level /// @param value The new zoom level void SetZoom(double value); @@ -245,6 +227,5 @@ public: /// @param y y coordinate; in/out void FromScriptCoords(int *x, int *y) const; - DECLARE_EVENT_TABLE() }; diff --git a/aegisub/src/visual_tool.cpp b/aegisub/src/visual_tool.cpp index 013df852d..f89825cf8 100644 --- a/aegisub/src/visual_tool.cpp +++ b/aegisub/src/visual_tool.cpp @@ -246,9 +246,7 @@ void VisualTool::Commit(wxString message) { if (message.empty()) { message = _("visual typesetting"); } - commitId = grid->ass->Commit(message, commitId); - - grid->CommitChanges(); + commitId = grid->ass->Commit(message, AssFile::COMMIT_TEXT, commitId); externalChange = true; }