Move "active line" responsibility to the grid. There are at the very least a bunch of redraw issues that need to be sorted out, probably much worse things are hiding.

Originally committed to SVN as r4604.
This commit is contained in:
Niels Martin Hansen 2010-06-26 11:32:16 +00:00
parent c4a27da4fc
commit c9c2fa6404
17 changed files with 238 additions and 188 deletions

View file

@ -942,8 +942,8 @@ void AudioDisplay::SetFile(wxString file) {
assert(loaded == (provider != NULL)); assert(loaded == (provider != NULL));
// Set default selection // Set default selection
int n = grid->editBox->linen; AssDialogue *dlg = grid->GetActiveLine();
SetDialogue(grid,grid->GetDialogue(n),n); SetDialogue(grid,dlg,grid->GetDialogueIndex(dlg));
} }
/// @brief Load from video /// @brief Load from video
@ -2181,7 +2181,7 @@ void AudioDisplay::ChangeLine(int delta, bool block) {
// Set stuff // Set stuff
NeedCommit = false; NeedCommit = false;
dialogue = NULL; dialogue = NULL;
grid->editBox->SetToLine(next); grid->SetActiveLine(grid->GetDialogue(next));
grid->SelectRow(next); grid->SelectRow(next);
grid->MakeCellVisible(next,0,true); grid->MakeCellVisible(next,0,true);
if (!dialogue) UpdateImage(true); if (!dialogue) UpdateImage(true);

View file

@ -80,6 +80,7 @@ BaseGrid::BaseGrid(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wx
holding = false; holding = false;
byFrame = false; byFrame = false;
lineHeight = 1; // non-zero to avoid div by 0 lineHeight = 1; // non-zero to avoid div by 0
active_line = 0;
// Set scrollbar // Set scrollbar
scrollBar = new wxScrollBar(this,GRID_SCROLLBAR,wxDefaultPosition,wxDefaultSize,wxSB_VERTICAL); scrollBar = new wxScrollBar(this,GRID_SCROLLBAR,wxDefaultPosition,wxDefaultSize,wxSB_VERTICAL);
@ -492,7 +493,7 @@ void BaseGrid::DrawImage(wxDC &dc) {
// Check for collisions // Check for collisions
bool collides = false; bool collides = false;
if (curDiag) { if (curDiag) {
AssDialogue *sel = GetDialogue(editBox->linen); AssDialogue *sel = GetActiveLine();
if (sel && sel != curDiag) { if (sel && sel != curDiag) {
if (curDiag->CollidesWith(sel)) collides = true; if (curDiag->CollidesWith(sel)) collides = true;
} }
@ -636,10 +637,12 @@ void BaseGrid::DrawImage(wxDC &dc) {
} }
// Draw currently active line border // Draw currently active line border
dc.SetPen(wxPen(lagi_wxColour(OPT_GET("Colour/Subtitle Grid/Active Border")->GetColour()))); if (GetActiveLine()) {
dc.SetBrush(*wxTRANSPARENT_BRUSH); dc.SetPen(wxPen(lagi_wxColour(OPT_GET("Colour/Subtitle Grid/Active Border")->GetColour())));
dy = (editBox->linen+1-yPos) * lineHeight; dc.SetBrush(*wxTRANSPARENT_BRUSH);
dc.DrawRectangle(0,dy,w,lineHeight+1); dy = (line_index_map[GetActiveLine()]+1-yPos) * lineHeight;
dc.DrawRectangle(0,dy,w,lineHeight+1);
}
} }
@ -694,8 +697,8 @@ void BaseGrid::OnMouseEvent(wxMouseEvent &event) {
if (holding && !click) { if (holding && !click) {
row = MID(0,row,GetRows()-1); row = MID(0,row,GetRows()-1);
} }
bool validRow = row >= 0 && row < GetRows(); AssDialogue *dlg = GetDialogue(row);
if (!validRow) row = -1; if (!dlg) row = 0;
// Get focus // Get focus
if (event.ButtonDown()) { if (event.ButtonDown()) {
@ -706,7 +709,7 @@ void BaseGrid::OnMouseEvent(wxMouseEvent &event) {
// Click type // Click type
bool startedHolding = false; bool startedHolding = false;
if (click && !holding && validRow) { if (click && !holding && dlg!=0) {
holding = true; holding = true;
startedHolding = true; startedHolding = true;
CaptureMouse(); CaptureMouse();
@ -736,7 +739,7 @@ void BaseGrid::OnMouseEvent(wxMouseEvent &event) {
} }
// Click // Click
if ((click || holding || dclick) && validRow) { if ((click || holding || dclick) && dlg!=0) {
// Disable extending // Disable extending
extendRow = -1; extendRow = -1;
@ -749,8 +752,8 @@ void BaseGrid::OnMouseEvent(wxMouseEvent &event) {
// Normal click // Normal click
if ((click || dclick) && !shift && !ctrl && !alt) { if ((click || dclick) && !shift && !ctrl && !alt) {
editBox->SetToLine(row); SetActiveLine(dlg);
if (dclick) VideoContext::Get()->JumpToTime(GetDialogue(row)->Start.GetMS()); if (dclick) VideoContext::Get()->JumpToTime(dlg->Start.GetMS());
SelectRow(row,false); SelectRow(row,false);
parentFrame->UpdateToolbar(); parentFrame->UpdateToolbar();
lastRow = row; lastRow = row;
@ -759,7 +762,7 @@ void BaseGrid::OnMouseEvent(wxMouseEvent &event) {
// Keep selection // Keep selection
if (click && !shift && !ctrl && alt) { if (click && !shift && !ctrl && alt) {
editBox->SetToLine(row); SetActiveLine(dlg);
return; return;
} }
@ -770,17 +773,16 @@ void BaseGrid::OnMouseEvent(wxMouseEvent &event) {
int i1 = row; int i1 = row;
int i2 = lastRow; int i2 = lastRow;
if (i1 > i2) { if (i1 > i2) {
int aux = i1; std::swap(i1, i2);
i1 = i2;
i2 = aux;
} }
// Toggle each // Toggle each
bool notFirst = false; Selection newsel;
for (int i=i1;i<=i2;i++) { for (int i=i1;i<=i2;i++) {
SelectRow(i,notFirst,true); newsel.insert(GetDialogue(i));
notFirst = true;
} }
SetSelectedSet(newsel);
parentFrame->UpdateToolbar(); parentFrame->UpdateToolbar();
} }
return; return;
@ -1038,6 +1040,11 @@ void BaseGrid::UpdateMaps() {
} }
} }
if (line_index_map.find(active_line) == line_index_map.end()) {
// this isn't supposed to happen
SetActiveLine(0);
}
Refresh(false); Refresh(false);
} }
@ -1106,14 +1113,14 @@ void BaseGrid::OnKeyPress(wxKeyEvent &event) {
// Move selection // Move selection
if (!ctrl && !shift && !alt) { if (!ctrl && !shift && !alt) {
// Move to extent first // Move to extent first
int curLine = editBox->linen; int curLine = GetDialogueIndex(GetActiveLine());
if (extendRow != -1) { if (extendRow != -1) {
curLine = extendRow; curLine = extendRow;
extendRow = -1; extendRow = -1;
} }
int next = MID(0,curLine+dir*step,GetRows()-1); int next = MID(0,curLine+dir*step,GetRows()-1);
editBox->SetToLine(next); SetActiveLine(GetDialogue(next));
SelectRow(next); SelectRow(next);
MakeCellVisible(next,0,false); MakeCellVisible(next,0,false);
return; return;
@ -1122,8 +1129,8 @@ void BaseGrid::OnKeyPress(wxKeyEvent &event) {
// Move active only // Move active only
if (alt && !shift && !ctrl) { if (alt && !shift && !ctrl) {
extendRow = -1; extendRow = -1;
int next = MID(0,editBox->linen+dir*step,GetRows()-1); int next = MID(0,GetDialogueIndex(GetActiveLine())+dir*step,GetRows()-1);
editBox->SetToLine(next); SetActiveLine(GetDialogue(next));
Refresh(false); Refresh(false);
MakeCellVisible(next,0,false); MakeCellVisible(next,0,false);
return; return;
@ -1132,23 +1139,22 @@ void BaseGrid::OnKeyPress(wxKeyEvent &event) {
// Shift-selection // Shift-selection
if (shift && !ctrl && !alt) { if (shift && !ctrl && !alt) {
// Find end // Find end
if (extendRow == -1) extendRow = editBox->linen; if (extendRow == -1) GetDialogueIndex(GetActiveLine());
extendRow = MID(0,extendRow+dir*step,GetRows()-1); extendRow = MID(0,extendRow+dir*step,GetRows()-1);
// Set range // Set range
int i1 = editBox->linen; int i1 = GetDialogueIndex(GetActiveLine());
int i2 = extendRow; int i2 = extendRow;
if (i2 < i1) { if (i2 < i1) {
int aux = i1; std::swap(i1, i2);
i1 = i2;
i2 = aux;
} }
// Select range // Select range
ClearSelection(); Selection newsel;
for (int i=i1;i<=i2;i++) { for (int i=i1;i<=i2;i++) {
SelectRow(i,true); newsel.insert(GetDialogue(i));
} }
SetSelectedSet(newsel);
MakeCellVisible(extendRow,0,false); MakeCellVisible(extendRow,0,false);
return; return;
@ -1203,14 +1209,45 @@ wxArrayInt BaseGrid::GetRangeArray(int n1,int n2) const {
// SelectionController // SelectionController
void BaseGrid::GetSelectedSet(Selection &os) const {
os.insert(selection.begin(), selection.end());
}
void BaseGrid::SetSelectedSet(const Selection &new_selection) { void BaseGrid::SetSelectedSet(const Selection &new_selection) {
Selection old_selection(selection); Selection old_selection(selection);
selection = new_selection; selection = new_selection;
AnnounceSelectedSetChanged(new_selection, old_selection); AnnounceSelectedSetChanged(new_selection, old_selection);
Refresh(false);
}
void BaseGrid::SetActiveLine(AssDialogue *new_line) {
if (new_line != active_line) {
assert(new_line == 0 || line_index_map.find(new_line) != line_index_map.end());
active_line = new_line;
AnnounceActiveLineChanged(active_line);
Refresh(false);
}
}
void BaseGrid::PrevLine() {
int cur_line_i = GetDialogueIndex(GetActiveLine());
AssDialogue *prev_line = GetDialogue(cur_line_i-1);
if (prev_line) {
SetActiveLine(prev_line);
Selection newsel;
newsel.insert(prev_line);
SetSelectedSet(newsel);
MakeCellVisible(cur_line_i-1, 0, false);
}
}
void BaseGrid::NextLine() {
int cur_line_i = GetDialogueIndex(GetActiveLine());
AssDialogue *next_line = GetDialogue(cur_line_i+1);
if (next_line) {
SetActiveLine(next_line);
Selection newsel;
newsel.insert(next_line);
SetSelectedSet(newsel);
MakeCellVisible(cur_line_i+1, 0, false);
}
} }

View file

@ -106,6 +106,7 @@ private:
void DrawImage(wxDC &dc); void DrawImage(wxDC &dc);
Selection selection; Selection selection;
AssDialogue *active_line;
std::vector<AssDialogue*> index_line_map; std::vector<AssDialogue*> index_line_map;
std::map<AssDialogue*,int> line_index_map; std::map<AssDialogue*,int> line_index_map;
@ -130,12 +131,12 @@ protected:
public: public:
// SelectionController implementation // SelectionController implementation
virtual void SetActiveLine(AssDialogue *new_line) { } virtual void SetActiveLine(AssDialogue *new_line);
virtual AssDialogue * GetActiveLine() const { return 0; } virtual AssDialogue * GetActiveLine() const { return active_line; }
virtual void SetSelectedSet(const Selection &new_selection); virtual void SetSelectedSet(const Selection &new_selection);
virtual void GetSelectedSet(Selection &selection) const; virtual void GetSelectedSet(Selection &res) const { res.insert(selection.begin(), selection.end()); }
virtual void NextLine() { } virtual void NextLine();
virtual void PrevLine() { } virtual void PrevLine();
public: public:

View file

@ -449,7 +449,7 @@ void SearchReplaceEngine::ReplaceNext(bool DoReplace) {
grid->SelectRow(curLine,false); grid->SelectRow(curLine,false);
grid->MakeCellVisible(curLine,0); grid->MakeCellVisible(curLine,0);
if (field == 0) { if (field == 0) {
grid->editBox->SetToLine(curLine); grid->SetActiveLine(grid->GetDialogue(curLine));
grid->editBox->TextEdit->SetSelectionU(pos,pos+replaceLen); grid->editBox->TextEdit->SetSelectionU(pos,pos+replaceLen);
} }
grid->EndBatch(); grid->EndBatch();

View file

@ -269,17 +269,19 @@ void DialogSelection::Process() {
// Select for modes 2 and 3 // Select for modes 2 and 3
if (action == 2 || action == 3) { if (action == 2 || action == 3) {
SubtitleSelectionController::Selection newsel;
grid->ClearSelection(); grid->ClearSelection();
int count = sels.Count(); int count = sels.Count();
if (count) {
grid->editBox->SetToLine(sels[0], true);
}
for (int i=0;i<count;i++) { for (int i=0;i<count;i++) {
grid->SelectRow(sels[i],true); newsel.insert(grid->GetDialogue(sels[i]));
}
grid->SetSelectedSet(newsel);
if (count) {
grid->SetActiveLine(grid->GetDialogue(sels[0]));
} }
} }
else if (firstSel > -1) { else if (firstSel > -1) {
grid->editBox->SetToLine(firstSel, true); grid->SetActiveLine(grid->GetDialogue(firstSel));
} }
// Message saying number selected // Message saying number selected

View file

@ -273,7 +273,7 @@ void DialogSpellChecker::SetWord(wxString word) {
int line = lastLine % grid->GetRows(); int line = lastLine % grid->GetRows();
grid->SelectRow(line,false); grid->SelectRow(line,false);
grid->MakeCellVisible(line,0); grid->MakeCellVisible(line,0);
grid->editBox->SetToLine(line); grid->SetActiveLine(grid->GetDialogue(line));
grid->editBox->TextEdit->SetSelectionU(wordStart,wordEnd); grid->editBox->TextEdit->SetSelectionU(wordStart,wordEnd);
grid->EndBatch(); grid->EndBatch();

View file

@ -210,7 +210,7 @@ void DialogStyling::JumpToLine(int n) {
// Update grid // Update grid
grid->SelectRow(linen,false); grid->SelectRow(linen,false);
grid->MakeCellVisible(linen,0); grid->MakeCellVisible(linen,0);
grid->editBox->SetToLine(linen); grid->SetActiveLine(grid->GetDialogue(linen));
// Update display // Update display
if (PreviewCheck->IsChecked()) VideoContext::Get()->JumpToTime(line->Start.GetMS()); if (PreviewCheck->IsChecked()) VideoContext::Get()->JumpToTime(line->Start.GetMS());

View file

@ -218,7 +218,7 @@ bool DialogTranslation::JumpToLine(int n,int block) {
grid->BeginBatch(); grid->BeginBatch();
grid->SelectRow(curline); grid->SelectRow(curline);
grid->MakeCellVisible(curline,0); grid->MakeCellVisible(curline,0);
grid->editBox->SetToLine(curline); grid->SetActiveLine(current);
grid->EndBatch(); grid->EndBatch();
// Adds blocks // Adds blocks

View file

@ -1459,21 +1459,12 @@ void FrameMain::OnFocusSeek(wxCommandEvent &) {
/// @brief Previous line hotkey /// @brief Previous line hotkey
void FrameMain::OnPrevLine(wxCommandEvent &) { void FrameMain::OnPrevLine(wxCommandEvent &) {
int next = EditBox->linen-1; SubsGrid->PrevLine();
if (next < 0) return;
SubsGrid->SelectRow(next);
SubsGrid->MakeCellVisible(next,0);
EditBox->SetToLine(next);
} }
/// @brief Next line hotkey /// @brief Next line hotkey
void FrameMain::OnNextLine(wxCommandEvent &) { void FrameMain::OnNextLine(wxCommandEvent &) {
int nrows = SubsGrid->GetRows(); SubsGrid->NextLine();
int next = EditBox->linen+1;
if (next >= nrows) return;
SubsGrid->SelectRow(next);
SubsGrid->MakeCellVisible(next,0);
EditBox->SetToLine(next);
} }
/// @brief Cycle through tag hiding modes /// @brief Cycle through tag hiding modes

View file

@ -34,6 +34,10 @@
/// @brief Interface declaration for the SubtitleSelectionController /// @brief Interface declaration for the SubtitleSelectionController
#ifndef AGI_SELECTION_CONTROLLER_H
#define AGI_SELECTION_CONTROLLER_H
#include <set> #include <set>
@ -103,6 +107,8 @@ public:
/// ///
/// Calling this method should only cause a change notification to be sent if /// Calling this method should only cause a change notification to be sent if
/// the active line was actually changed. /// the active line was actually changed.
///
/// This method must not affect the selected set.
virtual void SetActiveLine(ItemDataType *new_line) = 0; virtual void SetActiveLine(ItemDataType *new_line) = 0;
/// @brief Obtain the active line /// @brief Obtain the active line
@ -211,3 +217,7 @@ public:
virtual void AddSelectionListener(SelectionListener *listener) { } virtual void AddSelectionListener(SelectionListener *listener) { }
virtual void RemoveSelectionListener(SelectionListener *listener) { } virtual void RemoveSelectionListener(SelectionListener *listener) { }
}; };
#endif // include guard

View file

@ -81,7 +81,6 @@ SubsEditBox::SubsEditBox (wxWindow *parent,SubtitlesGrid *gridp) : wxPanel(paren
textEditReady = true; textEditReady = true;
controlState = true; controlState = true;
setupDone = false; setupDone = false;
linen = -2;
// Top controls // Top controls
wxArrayString styles; wxArrayString styles;
@ -210,6 +209,8 @@ SubsEditBox::SubsEditBox (wxWindow *parent,SubtitlesGrid *gridp) : wxPanel(paren
setupDone = true; setupDone = true;
SetSplitLineMode(); SetSplitLineMode();
Update(); Update();
grid->AddSelectionListener(this);
} }
@ -217,6 +218,7 @@ SubsEditBox::SubsEditBox (wxWindow *parent,SubtitlesGrid *gridp) : wxPanel(paren
/// @brief Destructor /// @brief Destructor
/// ///
SubsEditBox::~SubsEditBox() { SubsEditBox::~SubsEditBox() {
grid->RemoveSelectionListener(this);
ActorBox->PopEventHandler(true); ActorBox->PopEventHandler(true);
Effect->PopEventHandler(true); Effect->PopEventHandler(true);
TextEdit->PopEventHandler(true); TextEdit->PopEventHandler(true);
@ -265,7 +267,7 @@ void SubsEditBox::SetSplitLineMode(wxSize newSize) {
/// ///
void SubsEditBox::Update (bool timeOnly,bool weak,bool video) { void SubsEditBox::Update (bool timeOnly,bool weak,bool video) {
if (enabled) { if (enabled) {
AssDialogue *curdiag = grid->GetDialogue(linen); AssDialogue *curdiag = grid->GetActiveLine();
if (curdiag) { if (curdiag) {
// Controls // Controls
SetControlsState(true); SetControlsState(true);
@ -295,7 +297,7 @@ void SubsEditBox::Update (bool timeOnly,bool weak,bool video) {
} }
// Audio // Audio
if (!weak) audio->SetDialogue(grid,curdiag,linen); if (!weak) audio->SetDialogue(grid,curdiag,grid->GetDialogueIndex(curdiag));
// Video // Video
VideoContext::Get()->curLine = curdiag; VideoContext::Get()->curLine = curdiag;
@ -336,54 +338,12 @@ void SubsEditBox::UpdateGlobals () {
ActorBox->Thaw(); ActorBox->Thaw();
// Set subs update // Set subs update
linen = -2;
TextEdit->SetSelection(0,0); TextEdit->SetSelection(0,0);
SetToLine(grid->GetFirstSelRow()); grid->SetActiveLine(grid->GetDialogue(grid->GetFirstSelRow()));
} }
/// @brief Jump to a line
/// @param n
/// @param weak
///
void SubsEditBox::SetToLine(int n,bool weak) {
// Set to nothing
if (n == -1) {
enabled = false;
}
// Set line
else if (grid->GetDialogue(n)) {
enabled = true;
if (n != linen) {
linen = n;
StartTime->Update();
EndTime->Update();
Duration->Update();
}
}
// Update controls
Update();
// Set video
if (VideoContext::Get()->IsLoaded() && !weak) {
bool sync;
if (Search.hasFocus) sync = OPT_GET("Tool/Search Replace/Video Update")->GetBool();
else sync = OPT_GET("Video/Subtitle Sync")->GetBool();
if (sync) {
VideoContext::Get()->Stop();
AssDialogue *cur = grid->GetDialogue(n);
if (cur) VideoContext::Get()->JumpToTime(cur->Start.GetMS());
}
}
TextEdit->EmptyUndoBuffer();
}
/////////////// ///////////////
// Event table // Event table
BEGIN_EVENT_TABLE(SubsEditBox, wxPanel) BEGIN_EVENT_TABLE(SubsEditBox, wxPanel)
@ -761,16 +721,16 @@ void SubsEditBox::OnDurationChange(wxCommandEvent &event) {
void SubsEditBox::CommitTimes(bool start,bool end,bool fromStart,bool commit) { void SubsEditBox::CommitTimes(bool start,bool end,bool fromStart,bool commit) {
// Get selection // Get selection
if (!start && !end) return; if (!start && !end) return;
wxArrayInt sel = grid->GetSelection(); Selection sel;
int n = sel.Count(); grid->GetSelectedSet(sel);
if (n == 0) return; if (sel.size() == 0) return;
AssDialogue *cur; AssDialogue *cur;
Duration->SetTime(EndTime->time.GetMS() - StartTime->time.GetMS()); Duration->SetTime(EndTime->time.GetMS() - StartTime->time.GetMS());
// Update lines // Update lines
for (int i=0;i<n;i++) { for (Selection::iterator it = sel.begin(); it != sel.end(); ++it) {
if (grid->IsInSelection(linen)) cur = grid->GetDialogue(sel[i]); if (sel.find(grid->GetActiveLine()) != sel.end()) cur = *it;
else cur = grid->GetDialogue(linen); else cur = grid->GetActiveLine();
if (cur) { if (cur) {
// Set times // Set times
if (start) cur->Start = StartTime->time; if (start) cur->Start = StartTime->time;
@ -781,7 +741,7 @@ void SubsEditBox::CommitTimes(bool start,bool end,bool fromStart,bool commit) {
if (fromStart) cur->End = cur->Start; if (fromStart) cur->End = cur->Start;
else cur->Start = cur->End; else cur->Start = cur->End;
} }
if (!grid->IsInSelection(linen)) break; if (sel.find(grid->GetActiveLine()) == sel.end()) break;
} }
} }
@ -792,7 +752,8 @@ void SubsEditBox::CommitTimes(bool start,bool end,bool fromStart,bool commit) {
Duration->Update(); Duration->Update();
grid->ass->FlagAsModified(_("modify times")); grid->ass->FlagAsModified(_("modify times"));
grid->CommitChanges(); grid->CommitChanges();
audio->SetDialogue(grid,grid->GetDialogue(sel[0]),sel[0]); int sel0 = grid->GetFirstSelRow();
audio->SetDialogue(grid,grid->GetDialogue(sel0),sel0);
VideoContext::Get()->UpdateDisplays(false); VideoContext::Get()->UpdateDisplays(false);
} }
} }
@ -962,54 +923,57 @@ void SubsEditBox::DoKeyPress(wxKeyEvent &event) {
/// ///
void SubsEditBox::Commit(bool stay) { void SubsEditBox::Commit(bool stay) {
// Record pre-commit data // Record pre-commit data
wxString oldText = grid->GetDialogue(linen)->Text; AssDialogue *old_line = grid->GetActiveLine();
int oldStart = grid->GetDialogue(linen)->Start.GetMS(); wxString oldText = old_line->Text;
int oldEnd = grid->GetDialogue(linen)->End.GetMS(); int oldStart = old_line->Start.GetMS();
int oldEnd = old_line->End.GetMS();
// Update line // Update line
CommitText(); CommitText();
// Change text/time if needed for all selected lines // Change text/time if needed for all selected lines
bool updated = false; bool textNeedsCommit = old_line->Text != oldText;
bool textNeedsCommit = grid->GetDialogue(linen)->Text != oldText; bool timeNeedsCommit = old_line->Start.GetMS() != oldStart || old_line->End.GetMS() != oldEnd;
bool timeNeedsCommit = grid->GetDialogue(linen)->Start.GetMS() != oldStart || grid->GetDialogue(linen)->End.GetMS() != oldEnd; Selection sel;
int nrows = grid->GetRows(); grid->GetSelectedSet(sel);
wxArrayInt sel = grid->GetSelection(); if (sel.find(old_line) != sel.end()) {
if (grid->IsInSelection(linen)) { for (Selection::iterator it = sel.begin(); it != sel.end(); ++it) {
for (size_t i=0;i<sel.GetCount();i++) { if (textNeedsCommit) {
if (textNeedsCommit) grid->GetDialogue(sel[i])->Text = TextEdit->GetText(); (*it)->Text = TextEdit->GetText();
}
if (timeNeedsCommit) { if (timeNeedsCommit) {
grid->GetDialogue(sel[i])->Start.SetMS(StartTime->time.GetMS()); (*it)->Start.SetMS(StartTime->time.GetMS());
grid->GetDialogue(sel[i])->End.SetMS(EndTime->time.GetMS()); (*it)->End.SetMS(EndTime->time.GetMS());
} }
} }
} }
// Update file // Update file
if (!updated && textNeedsCommit) { if (textNeedsCommit) {
grid->ass->FlagAsModified(_("editing")); grid->ass->FlagAsModified(_("editing"));
grid->CommitChanges(); grid->CommitChanges();
} }
else if (!updated && (StartTime->HasBeenModified() || EndTime->HasBeenModified())) else if (StartTime->HasBeenModified() || EndTime->HasBeenModified()) {
CommitTimes(StartTime->HasBeenModified(),EndTime->HasBeenModified(),StartTime->HasBeenModified(),true); CommitTimes(StartTime->HasBeenModified(),EndTime->HasBeenModified(),StartTime->HasBeenModified(),true);
}
// Get next line if ctrl was not held down // Get next line if ctrl was not held down
if (!stay) { if (!stay) {
int next; int next;
if (!grid->IsInSelection(linen)) next = linen+1; if (sel.find(old_line) == sel.end())
else next = grid->GetLastSelRow()+1; next = grid->GetDialogueIndex(old_line)+1;
else
next = grid->GetLastSelRow()+1;
AssDialogue *cur = grid->GetDialogue(next-1); AssDialogue *cur = grid->GetDialogue(next-1);
if (next >= nrows) { if (next >= grid->GetRows()) {
AssDialogue *newline = new AssDialogue; AssDialogue *newline = new AssDialogue;
newline->Start = cur->End; newline->Start = cur->End;
newline->End.SetMS(cur->End.GetMS()+OPT_GET("Timing/Default Duration")->GetInt()); newline->End.SetMS(cur->End.GetMS()+OPT_GET("Timing/Default Duration")->GetInt());
newline->Style = cur->Style; newline->Style = cur->Style;
grid->InsertLine(newline,next-1,true,true); grid->InsertLine(newline,next-1,true,true);
updated = true;
} }
grid->SelectRow(next); grid->SelectRow(next);
grid->MakeCellVisible(next,0); grid->MakeCellVisible(next,0);
SetToLine(next); grid->SetActiveLine(grid->GetDialogue(next));
if (next >= nrows) return;
} }
} }
@ -1019,7 +983,7 @@ void SubsEditBox::Commit(bool stay) {
/// @param weak /// @param weak
/// ///
void SubsEditBox::CommitText(bool weak) { void SubsEditBox::CommitText(bool weak) {
AssDialogue *cur = grid->GetDialogue(linen); AssDialogue *cur = grid->GetActiveLine();
// Update line // Update line
if (cur) { if (cur) {
@ -1027,7 +991,7 @@ void SubsEditBox::CommitText(bool weak) {
cur->Text = TextEdit->GetText(); cur->Text = TextEdit->GetText();
// Update times // Update times
if (grid->IsInSelection(linen)) { if (grid->IsInSelection(grid->GetDialogueIndex(cur))) {
cur->Start = StartTime->time; cur->Start = StartTime->time;
cur->End = EndTime->time; cur->End = EndTime->time;
if (cur->Start > cur->End) { if (cur->Start > cur->End) {
@ -1039,7 +1003,7 @@ void SubsEditBox::CommitText(bool weak) {
// Update audio // Update audio
if (!weak) { if (!weak) {
grid->Refresh(false); grid->Refresh(false);
audio->SetDialogue(grid,cur,linen); audio->SetDialogue(grid,cur,grid->GetDialogueIndex(cur));
} }
} }
} }
@ -1115,7 +1079,7 @@ void SubsEditBox::SetOverride (wxString tagname,wxString preValue,int forcePos,b
bool isGeneric = false; bool isGeneric = false;
bool isFlag = false; bool isFlag = false;
bool state = false; bool state = false;
AssStyle *style = grid->ass->GetStyle(grid->GetDialogue(linen)->Style); AssStyle *style = grid->ass->GetStyle(grid->GetActiveLine()->Style);
AssStyle defStyle; AssStyle defStyle;
if (style == NULL) style = &defStyle; if (style == NULL) style = &defStyle;
if (tagname == _T("\\b")) { if (tagname == _T("\\b")) {
@ -1447,4 +1411,37 @@ void SubsEditBox::OnButtonCommit(wxCommandEvent &event) {
void SubsEditBox::OnActiveLineChanged(AssDialogue *new_line) {
// Set to nothing
enabled = (new_line != 0);
// Set line
if (enabled) {
StartTime->Update();
EndTime->Update();
Duration->Update();
}
// Update controls
Update();
// Set video
if (VideoContext::Get()->IsLoaded()) {
bool sync;
if (Search.hasFocus) sync = OPT_GET("Tool/Search Replace/Video Update")->GetBool();
else sync = OPT_GET("Video/Subtitle Sync")->GetBool();
if (sync) {
VideoContext::Get()->Stop();
if (new_line) VideoContext::Get()->JumpToTime(new_line->Start.GetMS());
}
}
TextEdit->EmptyUndoBuffer();
}
void SubsEditBox::OnSelectedSetChanged(const Selection &lines_added, const Selection &lines_removed) {
}

View file

@ -50,11 +50,13 @@
#include <wx/spinctrl.h> #include <wx/spinctrl.h>
#endif #endif
#include "selection_controller.h"
#include "subs_edit_ctrl.h" #include "subs_edit_ctrl.h"
////////////// //////////////
// Prototypes // Prototypes
class AssDialogue;
class SubtitlesGrid; class SubtitlesGrid;
class TimeEdit; class TimeEdit;
class SubsEditBox; class SubsEditBox;
@ -69,7 +71,7 @@ class wxStyledTextCtrl;
/// @brief DOCME /// @brief DOCME
/// ///
/// DOCME /// DOCME
class SubsEditBox : public wxPanel { class SubsEditBox : public wxPanel, protected SelectionListener<AssDialogue> {
friend class SubsTextEditHandler; friend class SubsTextEditHandler;
friend class SubsTextEditCtrl; friend class SubsTextEditCtrl;
friend class AudioDisplay; friend class AudioDisplay;
@ -232,10 +234,12 @@ private:
void OnEffectChange(wxCommandEvent &event); void OnEffectChange(wxCommandEvent &event);
void OnSize(wxSizeEvent &event); void OnSize(wxSizeEvent &event);
public: protected:
// SubtitleSelectionListener implementation
virtual void OnActiveLineChanged(AssDialogue *new_line);
virtual void OnSelectedSetChanged(const Selection &lines_added, const Selection &lines_removed);
/// DOCME public:
int linen;
/// DOCME /// DOCME
AudioDisplay *audio; AudioDisplay *audio;
@ -253,7 +257,6 @@ public:
void CommitText(bool weak=false); void CommitText(bool weak=false);
void Update(bool timeOnly=false,bool weak=false,bool video=true); void Update(bool timeOnly=false,bool weak=false,bool video=true);
void UpdateGlobals(); void UpdateGlobals();
void SetToLine(int n,bool weak=false);
void UpdateFrameTiming(); void UpdateFrameTiming();
void DoKeyPress(wxKeyEvent &event); void DoKeyPress(wxKeyEvent &event);
void Commit(bool stay); void Commit(bool stay);

View file

@ -269,7 +269,7 @@ void SubsTextEditCtrl::UpdateStyle(int start, int _length) {
if (OPT_GET("Subtitle/Highlight/Syntax")->GetBool() == 0) return; if (OPT_GET("Subtitle/Highlight/Syntax")->GetBool() == 0) return;
// Check if it's a template line // Check if it's a template line
AssDialogue *diag = control->grid->GetDialogue(control->linen); AssDialogue *diag = control->grid->GetActiveLine();
bool templateLine = diag && diag->Comment && diag->Effect.Lower().StartsWith(_T("template")); bool templateLine = diag && diag->Comment && diag->Effect.Lower().StartsWith(_T("template"));
//bool templateCodeLine = diag && diag->Comment && diag->Effect.Lower().StartsWith(_T("code")); //bool templateCodeLine = diag && diag->Comment && diag->Effect.Lower().StartsWith(_T("code"));
@ -781,7 +781,7 @@ void SubsTextEditCtrl::SetTextTo(const wxString _text) {
void SubsTextEditCtrl::OnMouseEvent(wxMouseEvent &event) { void SubsTextEditCtrl::OnMouseEvent(wxMouseEvent &event) {
// Right click // Right click
if (event.ButtonUp(wxMOUSE_BTN_RIGHT)) { if (event.ButtonUp(wxMOUSE_BTN_RIGHT)) {
if (control->linen >= 0) { if (control->grid->GetActiveLine() != 0) {
int pos = PositionFromPoint(event.GetPosition()); int pos = PositionFromPoint(event.GetPosition());
ShowPopupMenu(pos); ShowPopupMenu(pos);
return; return;
@ -1007,7 +1007,7 @@ void SubsTextEditCtrl::OnSplitLinePreserve (wxCommandEvent &event) {
to = GetReverseUnicodePosition(to); to = GetReverseUnicodePosition(to);
// Call SplitLine() with the text currently in the editbox. // Call SplitLine() with the text currently in the editbox.
// This makes sure we split what the user sees, not the committed line. // This makes sure we split what the user sees, not the committed line.
control->grid->SplitLine(control->linen,from,0,GetText()); control->grid->SplitLine(control->grid->GetDialogueIndex(control->grid->GetActiveLine()),from,0,GetText());
} }
@ -1022,7 +1022,7 @@ void SubsTextEditCtrl::OnSplitLineEstimate (wxCommandEvent &event) {
to = GetReverseUnicodePosition(to); to = GetReverseUnicodePosition(to);
// Call SplitLine() with the text currently in the editbox. // Call SplitLine() with the text currently in the editbox.
// This makes sure we split what the user sees, not the committed line. // This makes sure we split what the user sees, not the committed line.
control->grid->SplitLine(control->linen,from,1,GetText()); control->grid->SplitLine(control->grid->GetDialogueIndex(control->grid->GetActiveLine()),from,1,GetText());
} }

View file

@ -269,7 +269,7 @@ void SubtitlesGrid::OnKeyDown(wxKeyEvent &event) {
if (n < nrows-1) { if (n < nrows-1) {
SwapLines(n,n+1); SwapLines(n,n+1);
SelectRow(n+1); SelectRow(n+1);
editBox->SetToLine(n+1); //editBox->SetToLine(n+1);
} }
return; return;
} }
@ -279,7 +279,7 @@ void SubtitlesGrid::OnKeyDown(wxKeyEvent &event) {
if (n > 0) { if (n > 0) {
SwapLines(n-1,n); SwapLines(n-1,n);
SelectRow(n-1); SelectRow(n-1);
editBox->SetToLine(n-1); //editBox->SetToLine(n-1);
} }
return; return;
} }
@ -470,7 +470,7 @@ void SubtitlesGrid::OnInsertBefore (wxCommandEvent &event) {
// Insert it // Insert it
InsertLine(def,n,false); InsertLine(def,n,false);
SelectRow(n); SelectRow(n);
editBox->SetToLine(n); SetActiveLine(def);
EndBatch(); EndBatch();
} }
@ -502,7 +502,7 @@ void SubtitlesGrid::OnInsertAfter (wxCommandEvent &event) {
// Insert it // Insert it
InsertLine(def,n,true); InsertLine(def,n,true);
SelectRow(n+1); SelectRow(n+1);
editBox->SetToLine(n+1); SetActiveLine(def);
EndBatch(); EndBatch();
} }
@ -526,7 +526,7 @@ void SubtitlesGrid::OnInsertBeforeVideo (wxCommandEvent &event) {
// Insert it // Insert it
InsertLine(def,n,false); InsertLine(def,n,false);
SelectRow(n); SelectRow(n);
editBox->SetToLine(n); SetActiveLine(def);
EndBatch(); EndBatch();
} }
@ -550,7 +550,7 @@ void SubtitlesGrid::OnInsertAfterVideo (wxCommandEvent &event) {
// Insert it // Insert it
InsertLine(def,n,true); InsertLine(def,n,true);
SelectRow(n+1); SelectRow(n+1);
editBox->SetToLine(n+1); SetActiveLine(def);
EndBatch(); EndBatch();
} }
@ -828,11 +828,8 @@ void SubtitlesGrid::UpdateMaps() {
if (dlg) line_iter_map.insert(std::pair<AssDialogue*,entryIter>(dlg, it)); if (dlg) line_iter_map.insert(std::pair<AssDialogue*,entryIter>(dlg, it));
} }
// Set edit box
if (editBox) { if (editBox) {
int firstsel = GetFirstSelRow();
editBox->UpdateGlobals(); editBox->UpdateGlobals();
if (ass) editBox->SetToLine(firstsel);
} }
// Finish setting layout // Finish setting layout
@ -868,8 +865,10 @@ void SubtitlesGrid::SwapLines(int n1,int n2) {
/// @param update /// @param update
/// ///
void SubtitlesGrid::InsertLine(AssDialogue *line,int n,bool after,bool update) { void SubtitlesGrid::InsertLine(AssDialogue *line,int n,bool after,bool update) {
AssDialogue *rel_line = GetDialogue(n) + (after?1:0); AssDialogue *rel_line = GetDialogue(n + (after?1:0));
entryIter pos = line_iter_map[rel_line]; entryIter pos;
if (rel_line) pos = line_iter_map[rel_line];
else pos = ass->Line.end();
entryIter newIter = ass->Line.insert(pos,line); entryIter newIter = ass->Line.insert(pos,line);
UpdateMaps(); UpdateMaps();
@ -1014,11 +1013,12 @@ void SubtitlesGrid::PasteLines(int n,bool pasteOver) {
// Set selection // Set selection
if (!pasteOver) { if (!pasteOver) {
SelectRow(n); Selection newsel;
for (int i=n+1;i<n+inserted;i++) { for (int i=n;i<n+inserted;i++) {
SelectRow(i,true); newsel.insert(GetDialogue(i));
} }
editBox->SetToLine(n); SetSelectedSet(newsel);
SetActiveLine(GetDialogue(GetFirstSelRow()));
} }
} }
} }
@ -1037,6 +1037,7 @@ void SubtitlesGrid::DeleteLines(wxArrayInt target, bool flagModified) {
// Check if it's wiping file // Check if it's wiping file
int deleted = 0; int deleted = 0;
entryIter before_first = line_iter_map[GetDialogue(0)]; --before_first; entryIter before_first = line_iter_map[GetDialogue(0)]; --before_first;
int old_active_line_index = GetDialogueIndex(GetActiveLine());
// Delete lines // Delete lines
int size = target.Count(); int size = target.Count();
@ -1050,6 +1051,7 @@ void SubtitlesGrid::DeleteLines(wxArrayInt target, bool flagModified) {
AssDialogue *def = new AssDialogue; AssDialogue *def = new AssDialogue;
++before_first; ++before_first;
ass->Line.insert(before_first, def); ass->Line.insert(before_first, def);
old_active_line_index = 0;
} }
// Update // Update
@ -1061,9 +1063,8 @@ void SubtitlesGrid::DeleteLines(wxArrayInt target, bool flagModified) {
} }
// Update selected line // Update selected line
int newSelected = ClampSignedInteger32(editBox->linen, 0, GetRows()-1); SelectRow(old_active_line_index);
editBox->SetToLine(newSelected); SetActiveLine(GetDialogue(old_active_line_index));
SelectRow(newSelected);
} }
@ -1118,10 +1119,13 @@ void SubtitlesGrid::JoinLines(int n1,int n2,bool concat) {
cur->Text = finalText; cur->Text = finalText;
// Delete remaining lines (this will auto commit) // Delete remaining lines (this will auto commit)
DeleteLines(GetRangeArray(n1+1,n2)); DeleteLines(GetRangeArray(n1+1,n2), false);
ass->FlagAsModified(_("join lines"));
CommitChanges();
// Select new line // Select new line
editBox->SetToLine(n1); SetActiveLine(cur);
SelectRow(n1); SelectRow(n1);
} }
@ -1207,10 +1211,13 @@ void SubtitlesGrid::JoinAsKaraoke(int n1,int n2) {
cur->Text = finalText; cur->Text = finalText;
// Delete remaining lines (this will auto commit) // Delete remaining lines (this will auto commit)
DeleteLines(GetRangeArray(n1+1,n2)); DeleteLines(GetRangeArray(n1+1,n2), false);
ass->FlagAsModified(_("join as karaoke"));
CommitChanges();
// Select new line // Select new line
editBox->SetToLine(n1); SetActiveLine(cur);
SelectRow(n1); SelectRow(n1);
} }
@ -1243,11 +1250,12 @@ void SubtitlesGrid::DuplicateLines(int n1,int n2,bool nextFrame) {
} }
// Select new lines // Select new lines
SelectRow(n1+step,false); Selection newsel;
for (int i=n1+1;i<=n2;i++) { for (int i=n1;i<=n2;i++) {
SelectRow(i+step,true); newsel.insert(GetDialogue(i+step));
} }
editBox->SetToLine(n1+step); SetSelectedSet(newsel);
SetActiveLine(GetDialogue(n1+step));
} }
@ -1322,7 +1330,7 @@ void SubtitlesGrid::SplitLine(int n,int pos,int mode,wxString textIn) {
} }
// Update editbox and audio // Update editbox and audio
editBox->SetToLine(n); //editBox->SetToLine(n);
// Commit // Commit
ass->FlagAsModified(_("split")); ass->FlagAsModified(_("split"));

View file

@ -545,7 +545,7 @@ void VideoContext::Play() {
/// ///
void VideoContext::PlayLine() { void VideoContext::PlayLine() {
// Get line // Get line
AssDialogue *curline = grid->GetDialogue(grid->editBox->linen); AssDialogue *curline = grid->GetActiveLine();
if (!curline) return; if (!curline) return;
// Start playing audio // Start playing audio

View file

@ -323,7 +323,7 @@ void VideoSlider::OnKeyDown(wxKeyEvent &event) {
int cur; int cur;
if (sel.Count() > 0) cur = sel[0]; if (sel.Count() > 0) cur = sel[0];
else { else {
grid->editBox->SetToLine(0); grid->SetActiveLine(grid->GetDialogue(0));
grid->SelectRow(0); grid->SelectRow(0);
cur = 0; cur = 0;
} }
@ -342,7 +342,7 @@ void VideoSlider::OnKeyDown(wxKeyEvent &event) {
else if (VideoContext::Get()->GetFrameN() < target2) VideoContext::Get()->JumpToFrame(target2); else if (VideoContext::Get()->GetFrameN() < target2) VideoContext::Get()->JumpToFrame(target2);
else { else {
if (cur+1 >= grid->GetRows()) return; if (cur+1 >= grid->GetRows()) return;
grid->editBox->SetToLine(cur+1); grid->SetActiveLine(grid->GetDialogue(cur+1));
grid->SelectRow(cur+1); grid->SelectRow(cur+1);
grid->MakeCellVisible(cur+1,0); grid->MakeCellVisible(cur+1,0);
grid->SetVideoToSubs(true); grid->SetVideoToSubs(true);
@ -358,7 +358,7 @@ void VideoSlider::OnKeyDown(wxKeyEvent &event) {
else if (VideoContext::Get()->GetFrameN() > target1) VideoContext::Get()->JumpToFrame(target1); else if (VideoContext::Get()->GetFrameN() > target1) VideoContext::Get()->JumpToFrame(target1);
else { else {
if (cur-1 < 0) return; if (cur-1 < 0) return;
grid->editBox->SetToLine(cur-1); grid->SetActiveLine(grid->GetDialogue(cur-1));
grid->SelectRow(cur-1); grid->SelectRow(cur-1);
grid->MakeCellVisible(cur-1,0); grid->MakeCellVisible(cur-1,0);
grid->SetVideoToSubs(false); grid->SetVideoToSubs(false);

View file

@ -290,7 +290,7 @@ void VisualTool<FeatureType>::Commit(bool full, wxString message) {
template<class FeatureType> template<class FeatureType>
AssDialogue* VisualTool<FeatureType>::GetActiveDialogueLine() { AssDialogue* VisualTool<FeatureType>::GetActiveDialogueLine() {
SubtitlesGrid *grid = VideoContext::Get()->grid; SubtitlesGrid *grid = VideoContext::Get()->grid;
AssDialogue *diag = grid->GetDialogue(grid->editBox->linen); AssDialogue *diag = grid->GetActiveLine();
if (grid->IsDisplayed(diag)) if (grid->IsDisplayed(diag))
return diag; return diag;
return NULL; return NULL;
@ -392,20 +392,21 @@ template<class FeatureType>
void VisualTool<FeatureType>::SetEditbox(int lineN) { void VisualTool<FeatureType>::SetEditbox(int lineN) {
VideoContext* con = VideoContext::Get(); VideoContext* con = VideoContext::Get();
if (lineN > -1) { if (lineN > -1) {
con->grid->editBox->SetToLine(lineN); con->grid->SetActiveLine(con->grid->GetDialogue(lineN));
con->grid->SelectRow(lineN, true); con->grid->SelectRow(lineN, true);
} }
else { else {
wxArrayInt sel = GetSelection(); Selection sel;
con->grid->GetSelectedSet(sel);
// If there is a selection and the edit box's line is in it, do nothing // If there is a selection and the edit box's line is in it, do nothing
// Otherwise set the edit box if there is a selection or the selection // Otherwise set the edit box if there is a selection or the selection
// to the edit box if there is no selection // to the edit box if there is no selection
if (sel.empty()) { if (sel.empty()) {
con->grid->SelectRow(con->grid->editBox->linen, true); sel.insert(con->grid->GetActiveLine());
return; con->grid->SetSelectedSet(sel);
} }
else if (!std::binary_search(sel.begin(), sel.end(), con->grid->editBox->linen)) { else if (sel.find(con->grid->GetActiveLine()) == sel.end()) {
con->grid->editBox->SetToLine(sel[0]); con->grid->SetActiveLine(con->grid->GetDialogue(con->grid->GetFirstSelRow()));
} }
} }
} }