mirror of https://github.com/odrling/Aegisub
Rework how committing changes works
Rather than everything having to separately commit changes to the ass and then tell the subs grid to notify various parts of Aegisub about the changes, committing the AssFile now triggers an event which objects listen for. AssFile::Commit now also has an argument to indicate what sorts of changes were made to the file. For now these types are very broad. Originally committed to SVN as r4901.
This commit is contained in:
parent
d9006b0eb4
commit
6d2b941e76
|
@ -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 {
|
||||
|
|
|
@ -45,6 +45,8 @@
|
|||
#include <wx/arrstr.h>
|
||||
#endif
|
||||
|
||||
#include <libaegisub/signals.h>
|
||||
|
||||
class FrameRate;
|
||||
class AssDialogue;
|
||||
class AssStyle;
|
||||
|
@ -70,6 +72,8 @@ class AssFile {
|
|||
/// Last saved version of this file
|
||||
int savedCommitId;
|
||||
|
||||
agi::signal::Signal<int> AnnounceCommit;
|
||||
|
||||
public:
|
||||
/// The lines in the file
|
||||
std::list<AssEntry*> 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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
else {
|
||||
curStartMS = grid->GetDialogue(line_n+1)->Start.GetMS();
|
||||
curEndMS = grid->GetDialogue(line_n+1)->End.GetMS();
|
||||
}
|
||||
int endMs = curEndMS;
|
||||
|
||||
// Go to next
|
||||
dontReadTimes = true;
|
||||
ChangeLine(1,sel.GetCount() > 1 ? true : false);
|
||||
dontReadTimes = false;
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
|
|
@ -45,7 +45,10 @@
|
|||
#include <wx/window.h>
|
||||
#endif
|
||||
|
||||
#include <libaegisub/signals.h>
|
||||
|
||||
#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<AssDialogue> {
|
||||
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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -941,8 +941,6 @@ void DialogKanjiTimer::OnClose(wxCommandEvent &event) {
|
|||
}
|
||||
if (modified) {
|
||||
grid->ass->Commit(_("kanji timing"));
|
||||
grid->CommitChanges();
|
||||
grid->UpdateMaps();
|
||||
LinesToChange.clear();
|
||||
}
|
||||
Close();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -123,7 +123,6 @@ public:
|
|||
void ReplaceAll();
|
||||
void OpenDialog(bool HasReplace);
|
||||
void OnDialogOpen();
|
||||
void OnDialogClose();
|
||||
|
||||
SearchReplaceEngine();
|
||||
friend class DialogSearchReplace;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -541,6 +541,5 @@ void DialogTimingProcessor::Process() {
|
|||
}
|
||||
|
||||
// Update grid
|
||||
grid->ass->Commit(_("timing processor"));
|
||||
grid->CommitChanges();
|
||||
grid->ass->Commit(_("timing processor"), AssFile::COMMIT_TIMES);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -322,6 +322,9 @@ private:
|
|||
void RebuildRecentList(wxString listName,wxMenu *menu,int startID);
|
||||
void SynchronizeProject(bool FromSubs=false);
|
||||
|
||||
void OnSubtitlesFileChanged();
|
||||
|
||||
|
||||
public:
|
||||
|
||||
/// DOCME
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;i<nrows;i++) {
|
||||
wxString actor = grid->GetDialogue(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;i<nrows;i++) {
|
||||
wxString actor = grid->GetDialogue(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<class T>
|
||||
|
@ -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) {
|
||||
|
|
|
@ -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<AssDialogue> {
|
||||
friend class AudioDisplay;
|
||||
|
||||
enum TimeField {
|
||||
TIME_START = 0,
|
||||
TIME_END,
|
||||
|
@ -85,7 +82,6 @@ class SubsEditBox : public wxPanel, protected SelectionListener<AssDialogue> {
|
|||
wxColour origBgColour;
|
||||
|
||||
// Externally supplied controls
|
||||
AudioDisplay *audio;
|
||||
SubtitlesGrid *grid;
|
||||
|
||||
// Box controls
|
||||
|
@ -185,23 +181,19 @@ class SubsEditBox : public wxPanel, protected SelectionListener<AssDialogue> {
|
|||
/// @param amend Coalesce sequences of commits of the same type
|
||||
template<class T>
|
||||
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();
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -34,11 +34,6 @@
|
|||
/// @ingroup main_ui video
|
||||
///
|
||||
|
||||
|
||||
|
||||
|
||||
///////////
|
||||
// Headers
|
||||
#ifndef AGI_PRE
|
||||
#include <wx/panel.h>
|
||||
#include <wx/sizer.h>
|
||||
|
@ -47,9 +42,7 @@
|
|||
#include <wx/toolbar.h>
|
||||
#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()
|
||||
};
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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<int> 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<std::vector<int> const&> KeyframesOpen;
|
||||
/// Aspect ratio was changed (type, value)
|
||||
agi::signal::Signal<int, double> ARChange;
|
||||
|
||||
private:
|
||||
/// DOCME
|
||||
std::list<VideoDisplay*> displayList;
|
||||
|
||||
/// DOCME
|
||||
std::tr1::shared_ptr<VideoProvider> 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<int>& GetKeyFrames() const { return keyFrames; };
|
||||
wxString GetKeyFramesName() const { return keyFramesFilename; }
|
||||
|
|
|
@ -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<class T>
|
||||
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 &) {
|
||||
|
|
|
@ -45,9 +45,10 @@
|
|||
#include <libaegisub/signals.h>
|
||||
|
||||
// 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<agi::signal::Connection> 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()
|
||||
};
|
||||
|
|
|
@ -246,9 +246,7 @@ void VisualTool<FeatureType>::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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue