From c9c2fa640495e078de299db78d271047a6bb410c Mon Sep 17 00:00:00 2001 From: Niels Martin Hansen Date: Sat, 26 Jun 2010 11:32:16 +0000 Subject: [PATCH] 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. --- aegisub/src/audio_display.cpp | 6 +- aegisub/src/base_grid.cpp | 105 ++++++++++----- aegisub/src/base_grid.h | 11 +- aegisub/src/dialog_search_replace.cpp | 2 +- aegisub/src/dialog_selection.cpp | 12 +- aegisub/src/dialog_spellchecker.cpp | 2 +- aegisub/src/dialog_styling_assistant.cpp | 2 +- aegisub/src/dialog_translation.cpp | 2 +- aegisub/src/frame_main_events.cpp | 13 +- aegisub/src/selection_controller.h | 10 ++ aegisub/src/subs_edit_box.cpp | 155 +++++++++++------------ aegisub/src/subs_edit_box.h | 13 +- aegisub/src/subs_edit_ctrl.cpp | 8 +- aegisub/src/subs_grid.cpp | 62 +++++---- aegisub/src/video_context.cpp | 2 +- aegisub/src/video_slider.cpp | 6 +- aegisub/src/visual_tool.cpp | 15 ++- 17 files changed, 238 insertions(+), 188 deletions(-) diff --git a/aegisub/src/audio_display.cpp b/aegisub/src/audio_display.cpp index 01763aad2..ac3024a84 100644 --- a/aegisub/src/audio_display.cpp +++ b/aegisub/src/audio_display.cpp @@ -942,8 +942,8 @@ void AudioDisplay::SetFile(wxString file) { assert(loaded == (provider != NULL)); // Set default selection - int n = grid->editBox->linen; - SetDialogue(grid,grid->GetDialogue(n),n); + AssDialogue *dlg = grid->GetActiveLine(); + SetDialogue(grid,dlg,grid->GetDialogueIndex(dlg)); } /// @brief Load from video @@ -2181,7 +2181,7 @@ void AudioDisplay::ChangeLine(int delta, bool block) { // Set stuff NeedCommit = false; dialogue = NULL; - grid->editBox->SetToLine(next); + grid->SetActiveLine(grid->GetDialogue(next)); grid->SelectRow(next); grid->MakeCellVisible(next,0,true); if (!dialogue) UpdateImage(true); diff --git a/aegisub/src/base_grid.cpp b/aegisub/src/base_grid.cpp index b861d86a2..04416890f 100644 --- a/aegisub/src/base_grid.cpp +++ b/aegisub/src/base_grid.cpp @@ -80,6 +80,7 @@ BaseGrid::BaseGrid(wxWindow* parent, wxWindowID id, const wxPoint& pos, const wx holding = false; byFrame = false; lineHeight = 1; // non-zero to avoid div by 0 + active_line = 0; // Set scrollbar scrollBar = new wxScrollBar(this,GRID_SCROLLBAR,wxDefaultPosition,wxDefaultSize,wxSB_VERTICAL); @@ -492,7 +493,7 @@ void BaseGrid::DrawImage(wxDC &dc) { // Check for collisions bool collides = false; if (curDiag) { - AssDialogue *sel = GetDialogue(editBox->linen); + AssDialogue *sel = GetActiveLine(); if (sel && sel != curDiag) { if (curDiag->CollidesWith(sel)) collides = true; } @@ -636,10 +637,12 @@ void BaseGrid::DrawImage(wxDC &dc) { } // Draw currently active line border - dc.SetPen(wxPen(lagi_wxColour(OPT_GET("Colour/Subtitle Grid/Active Border")->GetColour()))); - dc.SetBrush(*wxTRANSPARENT_BRUSH); - dy = (editBox->linen+1-yPos) * lineHeight; - dc.DrawRectangle(0,dy,w,lineHeight+1); + if (GetActiveLine()) { + dc.SetPen(wxPen(lagi_wxColour(OPT_GET("Colour/Subtitle Grid/Active Border")->GetColour()))); + dc.SetBrush(*wxTRANSPARENT_BRUSH); + 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) { row = MID(0,row,GetRows()-1); } - bool validRow = row >= 0 && row < GetRows(); - if (!validRow) row = -1; + AssDialogue *dlg = GetDialogue(row); + if (!dlg) row = 0; // Get focus if (event.ButtonDown()) { @@ -706,7 +709,7 @@ void BaseGrid::OnMouseEvent(wxMouseEvent &event) { // Click type bool startedHolding = false; - if (click && !holding && validRow) { + if (click && !holding && dlg!=0) { holding = true; startedHolding = true; CaptureMouse(); @@ -736,7 +739,7 @@ void BaseGrid::OnMouseEvent(wxMouseEvent &event) { } // Click - if ((click || holding || dclick) && validRow) { + if ((click || holding || dclick) && dlg!=0) { // Disable extending extendRow = -1; @@ -749,8 +752,8 @@ void BaseGrid::OnMouseEvent(wxMouseEvent &event) { // Normal click if ((click || dclick) && !shift && !ctrl && !alt) { - editBox->SetToLine(row); - if (dclick) VideoContext::Get()->JumpToTime(GetDialogue(row)->Start.GetMS()); + SetActiveLine(dlg); + if (dclick) VideoContext::Get()->JumpToTime(dlg->Start.GetMS()); SelectRow(row,false); parentFrame->UpdateToolbar(); lastRow = row; @@ -759,7 +762,7 @@ void BaseGrid::OnMouseEvent(wxMouseEvent &event) { // Keep selection if (click && !shift && !ctrl && alt) { - editBox->SetToLine(row); + SetActiveLine(dlg); return; } @@ -770,17 +773,16 @@ void BaseGrid::OnMouseEvent(wxMouseEvent &event) { int i1 = row; int i2 = lastRow; if (i1 > i2) { - int aux = i1; - i1 = i2; - i2 = aux; + std::swap(i1, i2); } // Toggle each - bool notFirst = false; + Selection newsel; for (int i=i1;i<=i2;i++) { - SelectRow(i,notFirst,true); - notFirst = true; + newsel.insert(GetDialogue(i)); } + SetSelectedSet(newsel); + parentFrame->UpdateToolbar(); } 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); } @@ -1106,14 +1113,14 @@ void BaseGrid::OnKeyPress(wxKeyEvent &event) { // Move selection if (!ctrl && !shift && !alt) { // Move to extent first - int curLine = editBox->linen; + int curLine = GetDialogueIndex(GetActiveLine()); if (extendRow != -1) { curLine = extendRow; extendRow = -1; } int next = MID(0,curLine+dir*step,GetRows()-1); - editBox->SetToLine(next); + SetActiveLine(GetDialogue(next)); SelectRow(next); MakeCellVisible(next,0,false); return; @@ -1122,8 +1129,8 @@ void BaseGrid::OnKeyPress(wxKeyEvent &event) { // Move active only if (alt && !shift && !ctrl) { extendRow = -1; - int next = MID(0,editBox->linen+dir*step,GetRows()-1); - editBox->SetToLine(next); + int next = MID(0,GetDialogueIndex(GetActiveLine())+dir*step,GetRows()-1); + SetActiveLine(GetDialogue(next)); Refresh(false); MakeCellVisible(next,0,false); return; @@ -1132,23 +1139,22 @@ void BaseGrid::OnKeyPress(wxKeyEvent &event) { // Shift-selection if (shift && !ctrl && !alt) { // Find end - if (extendRow == -1) extendRow = editBox->linen; + if (extendRow == -1) GetDialogueIndex(GetActiveLine()); extendRow = MID(0,extendRow+dir*step,GetRows()-1); // Set range - int i1 = editBox->linen; + int i1 = GetDialogueIndex(GetActiveLine()); int i2 = extendRow; if (i2 < i1) { - int aux = i1; - i1 = i2; - i2 = aux; + std::swap(i1, i2); } // Select range - ClearSelection(); + Selection newsel; for (int i=i1;i<=i2;i++) { - SelectRow(i,true); + newsel.insert(GetDialogue(i)); } + SetSelectedSet(newsel); MakeCellVisible(extendRow,0,false); return; @@ -1203,14 +1209,45 @@ wxArrayInt BaseGrid::GetRangeArray(int n1,int n2) const { // SelectionController -void BaseGrid::GetSelectedSet(Selection &os) const { - os.insert(selection.begin(), selection.end()); -} - - void BaseGrid::SetSelectedSet(const Selection &new_selection) { Selection old_selection(selection); selection = new_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); + } } diff --git a/aegisub/src/base_grid.h b/aegisub/src/base_grid.h index 1158a8df0..5bcf08bea 100644 --- a/aegisub/src/base_grid.h +++ b/aegisub/src/base_grid.h @@ -106,6 +106,7 @@ private: void DrawImage(wxDC &dc); Selection selection; + AssDialogue *active_line; std::vector index_line_map; std::map line_index_map; @@ -130,12 +131,12 @@ protected: public: // SelectionController implementation - virtual void SetActiveLine(AssDialogue *new_line) { } - virtual AssDialogue * GetActiveLine() const { return 0; } + virtual void SetActiveLine(AssDialogue *new_line); + virtual AssDialogue * GetActiveLine() const { return active_line; } virtual void SetSelectedSet(const Selection &new_selection); - virtual void GetSelectedSet(Selection &selection) const; - virtual void NextLine() { } - virtual void PrevLine() { } + virtual void GetSelectedSet(Selection &res) const { res.insert(selection.begin(), selection.end()); } + virtual void NextLine(); + virtual void PrevLine(); public: diff --git a/aegisub/src/dialog_search_replace.cpp b/aegisub/src/dialog_search_replace.cpp index 14ee8342d..4ce6500dd 100644 --- a/aegisub/src/dialog_search_replace.cpp +++ b/aegisub/src/dialog_search_replace.cpp @@ -449,7 +449,7 @@ void SearchReplaceEngine::ReplaceNext(bool DoReplace) { grid->SelectRow(curLine,false); grid->MakeCellVisible(curLine,0); if (field == 0) { - grid->editBox->SetToLine(curLine); + grid->SetActiveLine(grid->GetDialogue(curLine)); grid->editBox->TextEdit->SetSelectionU(pos,pos+replaceLen); } grid->EndBatch(); diff --git a/aegisub/src/dialog_selection.cpp b/aegisub/src/dialog_selection.cpp index daccbc3b0..61eaac4c4 100644 --- a/aegisub/src/dialog_selection.cpp +++ b/aegisub/src/dialog_selection.cpp @@ -269,17 +269,19 @@ void DialogSelection::Process() { // Select for modes 2 and 3 if (action == 2 || action == 3) { + SubtitleSelectionController::Selection newsel; grid->ClearSelection(); int count = sels.Count(); - if (count) { - grid->editBox->SetToLine(sels[0], true); - } for (int i=0;iSelectRow(sels[i],true); + newsel.insert(grid->GetDialogue(sels[i])); + } + grid->SetSelectedSet(newsel); + if (count) { + grid->SetActiveLine(grid->GetDialogue(sels[0])); } } else if (firstSel > -1) { - grid->editBox->SetToLine(firstSel, true); + grid->SetActiveLine(grid->GetDialogue(firstSel)); } // Message saying number selected diff --git a/aegisub/src/dialog_spellchecker.cpp b/aegisub/src/dialog_spellchecker.cpp index 380104e90..947c757f7 100644 --- a/aegisub/src/dialog_spellchecker.cpp +++ b/aegisub/src/dialog_spellchecker.cpp @@ -273,7 +273,7 @@ void DialogSpellChecker::SetWord(wxString word) { int line = lastLine % grid->GetRows(); grid->SelectRow(line,false); grid->MakeCellVisible(line,0); - grid->editBox->SetToLine(line); + grid->SetActiveLine(grid->GetDialogue(line)); grid->editBox->TextEdit->SetSelectionU(wordStart,wordEnd); grid->EndBatch(); diff --git a/aegisub/src/dialog_styling_assistant.cpp b/aegisub/src/dialog_styling_assistant.cpp index bea4e987e..bbca46811 100644 --- a/aegisub/src/dialog_styling_assistant.cpp +++ b/aegisub/src/dialog_styling_assistant.cpp @@ -210,7 +210,7 @@ void DialogStyling::JumpToLine(int n) { // Update grid grid->SelectRow(linen,false); grid->MakeCellVisible(linen,0); - grid->editBox->SetToLine(linen); + grid->SetActiveLine(grid->GetDialogue(linen)); // Update display if (PreviewCheck->IsChecked()) VideoContext::Get()->JumpToTime(line->Start.GetMS()); diff --git a/aegisub/src/dialog_translation.cpp b/aegisub/src/dialog_translation.cpp index 831795b12..fd0f8afc2 100644 --- a/aegisub/src/dialog_translation.cpp +++ b/aegisub/src/dialog_translation.cpp @@ -218,7 +218,7 @@ bool DialogTranslation::JumpToLine(int n,int block) { grid->BeginBatch(); grid->SelectRow(curline); grid->MakeCellVisible(curline,0); - grid->editBox->SetToLine(curline); + grid->SetActiveLine(current); grid->EndBatch(); // Adds blocks diff --git a/aegisub/src/frame_main_events.cpp b/aegisub/src/frame_main_events.cpp index f7795cd61..71cfad2fd 100644 --- a/aegisub/src/frame_main_events.cpp +++ b/aegisub/src/frame_main_events.cpp @@ -1459,21 +1459,12 @@ void FrameMain::OnFocusSeek(wxCommandEvent &) { /// @brief Previous line hotkey void FrameMain::OnPrevLine(wxCommandEvent &) { - int next = EditBox->linen-1; - if (next < 0) return; - SubsGrid->SelectRow(next); - SubsGrid->MakeCellVisible(next,0); - EditBox->SetToLine(next); + SubsGrid->PrevLine(); } /// @brief Next line hotkey void FrameMain::OnNextLine(wxCommandEvent &) { - int nrows = SubsGrid->GetRows(); - int next = EditBox->linen+1; - if (next >= nrows) return; - SubsGrid->SelectRow(next); - SubsGrid->MakeCellVisible(next,0); - EditBox->SetToLine(next); + SubsGrid->NextLine(); } /// @brief Cycle through tag hiding modes diff --git a/aegisub/src/selection_controller.h b/aegisub/src/selection_controller.h index dffdd18ce..d33b8ae36 100644 --- a/aegisub/src/selection_controller.h +++ b/aegisub/src/selection_controller.h @@ -34,6 +34,10 @@ /// @brief Interface declaration for the SubtitleSelectionController +#ifndef AGI_SELECTION_CONTROLLER_H +#define AGI_SELECTION_CONTROLLER_H + + #include @@ -103,6 +107,8 @@ public: /// /// Calling this method should only cause a change notification to be sent if /// the active line was actually changed. + /// + /// This method must not affect the selected set. virtual void SetActiveLine(ItemDataType *new_line) = 0; /// @brief Obtain the active line @@ -211,3 +217,7 @@ public: virtual void AddSelectionListener(SelectionListener *listener) { } virtual void RemoveSelectionListener(SelectionListener *listener) { } }; + + + +#endif // include guard diff --git a/aegisub/src/subs_edit_box.cpp b/aegisub/src/subs_edit_box.cpp index b3c2b3d6a..2daec5800 100644 --- a/aegisub/src/subs_edit_box.cpp +++ b/aegisub/src/subs_edit_box.cpp @@ -81,7 +81,6 @@ SubsEditBox::SubsEditBox (wxWindow *parent,SubtitlesGrid *gridp) : wxPanel(paren textEditReady = true; controlState = true; setupDone = false; - linen = -2; // Top controls wxArrayString styles; @@ -210,6 +209,8 @@ SubsEditBox::SubsEditBox (wxWindow *parent,SubtitlesGrid *gridp) : wxPanel(paren setupDone = true; SetSplitLineMode(); Update(); + + grid->AddSelectionListener(this); } @@ -217,6 +218,7 @@ SubsEditBox::SubsEditBox (wxWindow *parent,SubtitlesGrid *gridp) : wxPanel(paren /// @brief Destructor /// SubsEditBox::~SubsEditBox() { + grid->RemoveSelectionListener(this); ActorBox->PopEventHandler(true); Effect->PopEventHandler(true); TextEdit->PopEventHandler(true); @@ -265,7 +267,7 @@ void SubsEditBox::SetSplitLineMode(wxSize newSize) { /// void SubsEditBox::Update (bool timeOnly,bool weak,bool video) { if (enabled) { - AssDialogue *curdiag = grid->GetDialogue(linen); + AssDialogue *curdiag = grid->GetActiveLine(); if (curdiag) { // Controls SetControlsState(true); @@ -295,7 +297,7 @@ void SubsEditBox::Update (bool timeOnly,bool weak,bool video) { } // Audio - if (!weak) audio->SetDialogue(grid,curdiag,linen); + if (!weak) audio->SetDialogue(grid,curdiag,grid->GetDialogueIndex(curdiag)); // Video VideoContext::Get()->curLine = curdiag; @@ -336,54 +338,12 @@ void SubsEditBox::UpdateGlobals () { ActorBox->Thaw(); // Set subs update - linen = -2; 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 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) { // Get selection if (!start && !end) return; - wxArrayInt sel = grid->GetSelection(); - int n = sel.Count(); - if (n == 0) return; + Selection sel; + grid->GetSelectedSet(sel); + if (sel.size() == 0) return; AssDialogue *cur; Duration->SetTime(EndTime->time.GetMS() - StartTime->time.GetMS()); // Update lines - for (int i=0;iIsInSelection(linen)) cur = grid->GetDialogue(sel[i]); - else cur = grid->GetDialogue(linen); + for (Selection::iterator it = sel.begin(); it != sel.end(); ++it) { + if (sel.find(grid->GetActiveLine()) != sel.end()) cur = *it; + else cur = grid->GetActiveLine(); if (cur) { // Set times 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; 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(); grid->ass->FlagAsModified(_("modify times")); 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); } } @@ -962,54 +923,57 @@ void SubsEditBox::DoKeyPress(wxKeyEvent &event) { /// void SubsEditBox::Commit(bool stay) { // Record pre-commit data - wxString oldText = grid->GetDialogue(linen)->Text; - int oldStart = grid->GetDialogue(linen)->Start.GetMS(); - int oldEnd = grid->GetDialogue(linen)->End.GetMS(); + AssDialogue *old_line = grid->GetActiveLine(); + wxString oldText = old_line->Text; + int oldStart = old_line->Start.GetMS(); + int oldEnd = old_line->End.GetMS(); // Update line CommitText(); // Change text/time if needed for all selected lines - bool updated = false; - bool textNeedsCommit = grid->GetDialogue(linen)->Text != oldText; - bool timeNeedsCommit = grid->GetDialogue(linen)->Start.GetMS() != oldStart || grid->GetDialogue(linen)->End.GetMS() != oldEnd; - int nrows = grid->GetRows(); - wxArrayInt sel = grid->GetSelection(); - if (grid->IsInSelection(linen)) { - for (size_t i=0;iGetDialogue(sel[i])->Text = TextEdit->GetText(); + bool textNeedsCommit = old_line->Text != oldText; + bool timeNeedsCommit = old_line->Start.GetMS() != oldStart || old_line->End.GetMS() != oldEnd; + Selection sel; + grid->GetSelectedSet(sel); + if (sel.find(old_line) != sel.end()) { + for (Selection::iterator it = sel.begin(); it != sel.end(); ++it) { + if (textNeedsCommit) { + (*it)->Text = TextEdit->GetText(); + } if (timeNeedsCommit) { - grid->GetDialogue(sel[i])->Start.SetMS(StartTime->time.GetMS()); - grid->GetDialogue(sel[i])->End.SetMS(EndTime->time.GetMS()); + (*it)->Start.SetMS(StartTime->time.GetMS()); + (*it)->End.SetMS(EndTime->time.GetMS()); } } } // Update file - if (!updated && textNeedsCommit) { + if (textNeedsCommit) { grid->ass->FlagAsModified(_("editing")); grid->CommitChanges(); } - else if (!updated && (StartTime->HasBeenModified() || EndTime->HasBeenModified())) + else if (StartTime->HasBeenModified() || EndTime->HasBeenModified()) { CommitTimes(StartTime->HasBeenModified(),EndTime->HasBeenModified(),StartTime->HasBeenModified(),true); + } // Get next line if ctrl was not held down if (!stay) { int next; - if (!grid->IsInSelection(linen)) next = linen+1; - else next = grid->GetLastSelRow()+1; + if (sel.find(old_line) == sel.end()) + next = grid->GetDialogueIndex(old_line)+1; + else + next = grid->GetLastSelRow()+1; AssDialogue *cur = grid->GetDialogue(next-1); - if (next >= nrows) { + if (next >= grid->GetRows()) { AssDialogue *newline = new AssDialogue; newline->Start = cur->End; newline->End.SetMS(cur->End.GetMS()+OPT_GET("Timing/Default Duration")->GetInt()); newline->Style = cur->Style; grid->InsertLine(newline,next-1,true,true); - updated = true; } grid->SelectRow(next); grid->MakeCellVisible(next,0); - SetToLine(next); - if (next >= nrows) return; + grid->SetActiveLine(grid->GetDialogue(next)); } } @@ -1019,7 +983,7 @@ void SubsEditBox::Commit(bool stay) { /// @param weak /// void SubsEditBox::CommitText(bool weak) { - AssDialogue *cur = grid->GetDialogue(linen); + AssDialogue *cur = grid->GetActiveLine(); // Update line if (cur) { @@ -1027,7 +991,7 @@ void SubsEditBox::CommitText(bool weak) { cur->Text = TextEdit->GetText(); // Update times - if (grid->IsInSelection(linen)) { + if (grid->IsInSelection(grid->GetDialogueIndex(cur))) { cur->Start = StartTime->time; cur->End = EndTime->time; if (cur->Start > cur->End) { @@ -1039,7 +1003,7 @@ void SubsEditBox::CommitText(bool weak) { // Update audio if (!weak) { 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 isFlag = false; bool state = false; - AssStyle *style = grid->ass->GetStyle(grid->GetDialogue(linen)->Style); + AssStyle *style = grid->ass->GetStyle(grid->GetActiveLine()->Style); AssStyle defStyle; if (style == NULL) style = &defStyle; 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) { +} diff --git a/aegisub/src/subs_edit_box.h b/aegisub/src/subs_edit_box.h index 96e62a6a5..15a0f5ffd 100644 --- a/aegisub/src/subs_edit_box.h +++ b/aegisub/src/subs_edit_box.h @@ -50,11 +50,13 @@ #include #endif +#include "selection_controller.h" #include "subs_edit_ctrl.h" ////////////// // Prototypes +class AssDialogue; class SubtitlesGrid; class TimeEdit; class SubsEditBox; @@ -69,7 +71,7 @@ class wxStyledTextCtrl; /// @brief DOCME /// /// DOCME -class SubsEditBox : public wxPanel { +class SubsEditBox : public wxPanel, protected SelectionListener { friend class SubsTextEditHandler; friend class SubsTextEditCtrl; friend class AudioDisplay; @@ -232,10 +234,12 @@ private: void OnEffectChange(wxCommandEvent &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 - int linen; +public: /// DOCME AudioDisplay *audio; @@ -253,7 +257,6 @@ public: void CommitText(bool weak=false); void Update(bool timeOnly=false,bool weak=false,bool video=true); void UpdateGlobals(); - void SetToLine(int n,bool weak=false); void UpdateFrameTiming(); void DoKeyPress(wxKeyEvent &event); void Commit(bool stay); diff --git a/aegisub/src/subs_edit_ctrl.cpp b/aegisub/src/subs_edit_ctrl.cpp index 1215db372..3a77de639 100644 --- a/aegisub/src/subs_edit_ctrl.cpp +++ b/aegisub/src/subs_edit_ctrl.cpp @@ -269,7 +269,7 @@ void SubsTextEditCtrl::UpdateStyle(int start, int _length) { if (OPT_GET("Subtitle/Highlight/Syntax")->GetBool() == 0) return; // 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 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) { // Right click if (event.ButtonUp(wxMOUSE_BTN_RIGHT)) { - if (control->linen >= 0) { + if (control->grid->GetActiveLine() != 0) { int pos = PositionFromPoint(event.GetPosition()); ShowPopupMenu(pos); return; @@ -1007,7 +1007,7 @@ void SubsTextEditCtrl::OnSplitLinePreserve (wxCommandEvent &event) { to = GetReverseUnicodePosition(to); // Call SplitLine() with the text currently in the editbox. // 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); // Call SplitLine() with the text currently in the editbox. // 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()); } diff --git a/aegisub/src/subs_grid.cpp b/aegisub/src/subs_grid.cpp index 60ca2ce40..83a1f8ea4 100644 --- a/aegisub/src/subs_grid.cpp +++ b/aegisub/src/subs_grid.cpp @@ -269,7 +269,7 @@ void SubtitlesGrid::OnKeyDown(wxKeyEvent &event) { if (n < nrows-1) { SwapLines(n,n+1); SelectRow(n+1); - editBox->SetToLine(n+1); + //editBox->SetToLine(n+1); } return; } @@ -279,7 +279,7 @@ void SubtitlesGrid::OnKeyDown(wxKeyEvent &event) { if (n > 0) { SwapLines(n-1,n); SelectRow(n-1); - editBox->SetToLine(n-1); + //editBox->SetToLine(n-1); } return; } @@ -470,7 +470,7 @@ void SubtitlesGrid::OnInsertBefore (wxCommandEvent &event) { // Insert it InsertLine(def,n,false); SelectRow(n); - editBox->SetToLine(n); + SetActiveLine(def); EndBatch(); } @@ -502,7 +502,7 @@ void SubtitlesGrid::OnInsertAfter (wxCommandEvent &event) { // Insert it InsertLine(def,n,true); SelectRow(n+1); - editBox->SetToLine(n+1); + SetActiveLine(def); EndBatch(); } @@ -526,7 +526,7 @@ void SubtitlesGrid::OnInsertBeforeVideo (wxCommandEvent &event) { // Insert it InsertLine(def,n,false); SelectRow(n); - editBox->SetToLine(n); + SetActiveLine(def); EndBatch(); } @@ -550,7 +550,7 @@ void SubtitlesGrid::OnInsertAfterVideo (wxCommandEvent &event) { // Insert it InsertLine(def,n,true); SelectRow(n+1); - editBox->SetToLine(n+1); + SetActiveLine(def); EndBatch(); } @@ -828,11 +828,8 @@ void SubtitlesGrid::UpdateMaps() { if (dlg) line_iter_map.insert(std::pair(dlg, it)); } - // Set edit box if (editBox) { - int firstsel = GetFirstSelRow(); editBox->UpdateGlobals(); - if (ass) editBox->SetToLine(firstsel); } // Finish setting layout @@ -868,8 +865,10 @@ void SubtitlesGrid::SwapLines(int n1,int n2) { /// @param update /// void SubtitlesGrid::InsertLine(AssDialogue *line,int n,bool after,bool update) { - AssDialogue *rel_line = GetDialogue(n) + (after?1:0); - entryIter pos = line_iter_map[rel_line]; + AssDialogue *rel_line = GetDialogue(n + (after?1:0)); + entryIter pos; + if (rel_line) pos = line_iter_map[rel_line]; + else pos = ass->Line.end(); entryIter newIter = ass->Line.insert(pos,line); UpdateMaps(); @@ -1014,11 +1013,12 @@ void SubtitlesGrid::PasteLines(int n,bool pasteOver) { // Set selection if (!pasteOver) { - SelectRow(n); - for (int i=n+1;iSetToLine(n); + SetSelectedSet(newsel); + SetActiveLine(GetDialogue(GetFirstSelRow())); } } } @@ -1037,6 +1037,7 @@ void SubtitlesGrid::DeleteLines(wxArrayInt target, bool flagModified) { // Check if it's wiping file int deleted = 0; entryIter before_first = line_iter_map[GetDialogue(0)]; --before_first; + int old_active_line_index = GetDialogueIndex(GetActiveLine()); // Delete lines int size = target.Count(); @@ -1050,6 +1051,7 @@ void SubtitlesGrid::DeleteLines(wxArrayInt target, bool flagModified) { AssDialogue *def = new AssDialogue; ++before_first; ass->Line.insert(before_first, def); + old_active_line_index = 0; } // Update @@ -1061,9 +1063,8 @@ void SubtitlesGrid::DeleteLines(wxArrayInt target, bool flagModified) { } // Update selected line - int newSelected = ClampSignedInteger32(editBox->linen, 0, GetRows()-1); - editBox->SetToLine(newSelected); - SelectRow(newSelected); + SelectRow(old_active_line_index); + SetActiveLine(GetDialogue(old_active_line_index)); } @@ -1118,10 +1119,13 @@ void SubtitlesGrid::JoinLines(int n1,int n2,bool concat) { cur->Text = finalText; // 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 - editBox->SetToLine(n1); + SetActiveLine(cur); SelectRow(n1); } @@ -1207,10 +1211,13 @@ void SubtitlesGrid::JoinAsKaraoke(int n1,int n2) { cur->Text = finalText; // 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 - editBox->SetToLine(n1); + SetActiveLine(cur); SelectRow(n1); } @@ -1243,11 +1250,12 @@ void SubtitlesGrid::DuplicateLines(int n1,int n2,bool nextFrame) { } // Select new lines - SelectRow(n1+step,false); - for (int i=n1+1;i<=n2;i++) { - SelectRow(i+step,true); + Selection newsel; + for (int i=n1;i<=n2;i++) { + 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 - editBox->SetToLine(n); + //editBox->SetToLine(n); // Commit ass->FlagAsModified(_("split")); diff --git a/aegisub/src/video_context.cpp b/aegisub/src/video_context.cpp index 8a78c530d..c1ebeb50a 100644 --- a/aegisub/src/video_context.cpp +++ b/aegisub/src/video_context.cpp @@ -545,7 +545,7 @@ void VideoContext::Play() { /// void VideoContext::PlayLine() { // Get line - AssDialogue *curline = grid->GetDialogue(grid->editBox->linen); + AssDialogue *curline = grid->GetActiveLine(); if (!curline) return; // Start playing audio diff --git a/aegisub/src/video_slider.cpp b/aegisub/src/video_slider.cpp index c5da60382..9725a8a85 100644 --- a/aegisub/src/video_slider.cpp +++ b/aegisub/src/video_slider.cpp @@ -323,7 +323,7 @@ void VideoSlider::OnKeyDown(wxKeyEvent &event) { int cur; if (sel.Count() > 0) cur = sel[0]; else { - grid->editBox->SetToLine(0); + grid->SetActiveLine(grid->GetDialogue(0)); grid->SelectRow(0); cur = 0; } @@ -342,7 +342,7 @@ void VideoSlider::OnKeyDown(wxKeyEvent &event) { else if (VideoContext::Get()->GetFrameN() < target2) VideoContext::Get()->JumpToFrame(target2); else { if (cur+1 >= grid->GetRows()) return; - grid->editBox->SetToLine(cur+1); + grid->SetActiveLine(grid->GetDialogue(cur+1)); grid->SelectRow(cur+1); grid->MakeCellVisible(cur+1,0); grid->SetVideoToSubs(true); @@ -358,7 +358,7 @@ void VideoSlider::OnKeyDown(wxKeyEvent &event) { else if (VideoContext::Get()->GetFrameN() > target1) VideoContext::Get()->JumpToFrame(target1); else { if (cur-1 < 0) return; - grid->editBox->SetToLine(cur-1); + grid->SetActiveLine(grid->GetDialogue(cur-1)); grid->SelectRow(cur-1); grid->MakeCellVisible(cur-1,0); grid->SetVideoToSubs(false); diff --git a/aegisub/src/visual_tool.cpp b/aegisub/src/visual_tool.cpp index 2c51ebbaa..3b40d8f5c 100644 --- a/aegisub/src/visual_tool.cpp +++ b/aegisub/src/visual_tool.cpp @@ -290,7 +290,7 @@ void VisualTool::Commit(bool full, wxString message) { template AssDialogue* VisualTool::GetActiveDialogueLine() { SubtitlesGrid *grid = VideoContext::Get()->grid; - AssDialogue *diag = grid->GetDialogue(grid->editBox->linen); + AssDialogue *diag = grid->GetActiveLine(); if (grid->IsDisplayed(diag)) return diag; return NULL; @@ -392,20 +392,21 @@ template void VisualTool::SetEditbox(int lineN) { VideoContext* con = VideoContext::Get(); if (lineN > -1) { - con->grid->editBox->SetToLine(lineN); + con->grid->SetActiveLine(con->grid->GetDialogue(lineN)); con->grid->SelectRow(lineN, true); } 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 // Otherwise set the edit box if there is a selection or the selection // to the edit box if there is no selection if (sel.empty()) { - con->grid->SelectRow(con->grid->editBox->linen, true); - return; + sel.insert(con->grid->GetActiveLine()); + con->grid->SetSelectedSet(sel); } - else if (!std::binary_search(sel.begin(), sel.end(), con->grid->editBox->linen)) { - con->grid->editBox->SetToLine(sel[0]); + else if (sel.find(con->grid->GetActiveLine()) == sel.end()) { + con->grid->SetActiveLine(con->grid->GetDialogue(con->grid->GetFirstSelRow())); } } }