From 31aed4c1a7bf0a72f6706f31722d1b13c6f7ca22 Mon Sep 17 00:00:00 2001 From: Karl Blomster Date: Sun, 26 Apr 2009 01:02:23 +0000 Subject: [PATCH] Fix a number of odd quirks regarding how grid selection is moved after committing multiple lines, and how audio selection moves after committing. See #794 for full details. Patch by Harukalover. closes #64, #420, #794 Originally committed to SVN as r2859. --- aegisub/src/audio_display.cpp | 48 ++++++++++++++--------- aegisub/src/audio_display.h | 2 +- aegisub/src/base_grid.cpp | 14 +++++++ aegisub/src/base_grid.h | 1 + aegisub/src/frame_main_events.cpp | 4 +- aegisub/src/subs_edit_box.cpp | 65 ++++++++++++++++++++++--------- 6 files changed, 93 insertions(+), 41 deletions(-) diff --git a/aegisub/src/audio_display.cpp b/aegisub/src/audio_display.cpp index f2c622936..eb022908a 100644 --- a/aegisub/src/audio_display.cpp +++ b/aegisub/src/audio_display.cpp @@ -1197,6 +1197,9 @@ void AudioDisplay::CommitChanges (bool nextLine) { if (!loaded) return; // 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; bool wasKaraSplitting = false; bool validCommit = true; if (!karaoke->enabled && !karaoke->splitting) { @@ -1220,6 +1223,9 @@ void AudioDisplay::CommitChanges (bool nextLine) { wxLogDebug(_T("AudioDisplay::CommitChanges: karaSelStart=%d karaSelEnd=%d"), karaSelStart, karaSelEnd); } + // Get selected rows + wxArrayInt sel = grid->GetSelection(); + // Commit ok? if (validCommit) { wxLogDebug(_T("AudioDisplay::CommitChanges: valid commit")); @@ -1229,25 +1235,21 @@ void AudioDisplay::CommitChanges (bool nextLine) { // Update dialogues blockUpdate = true; - wxArrayInt sel = grid->GetSelection(); - int sels = (int)sel.Count(); - bool textNeedsCommit = grid->GetDialogue(sel[0])->Text != grid->editBox->TextEdit->GetText(); AssDialogue *curDiag; - for (int i=-1;iGetDialogue(sel[i]); - if (curDiag == dialogue) continue; + for (size_t i=0;iIsInSelection(line_n)) curDiag = grid->GetDialogue(sel[i]); + else curDiag = grid->GetDialogue(line_n); + if (timeNeedsCommit) { + curDiag->Start.SetMS(curStartMS); + curDiag->End.SetMS(curEndMS); } - - curDiag->Start.SetMS(curStartMS); - curDiag->End.SetMS(curEndMS); if (!karaoke->enabled && textNeedsCommit) { // 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(); } curDiag->UpdateData(); + if (!grid->IsInSelection(line_n)) break; } // Update edit box @@ -1278,15 +1280,22 @@ void AudioDisplay::CommitChanges (bool nextLine) { def->End.SetMS(def->End.GetMS()+Options.AsInt(_T("Timing Default Duration"))); def->Style = grid->GetDialogue(line_n)->Style; grid->InsertLine(def,line_n,true); + curStartMS = curEndMS; + curEndMS = curStartMS + Options.AsInt(_T("Timing Default Duration")); } - + else if (grid->GetDialogue(line_n+1)->Start.GetMS() == 0 && grid->GetDialogue(line_n+1)->End.GetMS() == 0) { + curStartMS = curEndMS; + curEndMS = curStartMS + Options.AsInt(_T("Timing Default Duration")); + } + else { + curStartMS = grid->GetDialogue(line_n+1)->Start.GetMS(); + curEndMS = grid->GetDialogue(line_n+1)->End.GetMS(); + } + // Go to next dontReadTimes = true; - Next(); + ChangeLine(1,sel.GetCount() > 1 ? true : false); dontReadTimes = false; - curStartMS = curEndMS; - curEndMS = curStartMS + Options.AsInt(_T("Timing Default Duration")); - NeedCommit = true; } Update(); @@ -2208,12 +2217,15 @@ void AudioDisplay::OnKeyDown(wxKeyEvent &event) { /////////////// // Change line -void AudioDisplay::ChangeLine(int delta) { +void AudioDisplay::ChangeLine(int delta, bool block) { wxLogDebug(_T("AudioDisplay::ChangeLine(delta=%d)"), delta); if (dialogue) { wxLogDebug(_T("AudioDisplay::ChangeLine: has dialogue")); // Get next line number and make sure it's within bounds - int next = line_n+delta; + int next; + if (block && grid->IsInSelection(line_n)) next = grid->GetLastSelRow()+delta; + else next = line_n+delta; + if (next == -1) next = 0; if (next == grid->GetRows()) next = grid->GetRows() - 1; wxLogDebug(_T("AudioDisplay::ChangeLine: next=%i"), next); diff --git a/aegisub/src/audio_display.h b/aegisub/src/audio_display.h index 1bb9bc113..220bec3d1 100644 --- a/aegisub/src/audio_display.h +++ b/aegisub/src/audio_display.h @@ -161,7 +161,7 @@ public: void UpdateScrollbar(); void SetDialogue(SubtitlesGrid *_grid=NULL,AssDialogue *diag=NULL,int n=-1); void MakeDialogueVisible(bool force=false); - void ChangeLine(int delta); + void ChangeLine(int delta, bool block=false); void Next(bool play=true); void Prev(bool play=true); diff --git a/aegisub/src/base_grid.cpp b/aegisub/src/base_grid.cpp index b78d3b444..5b13947c4 100644 --- a/aegisub/src/base_grid.cpp +++ b/aegisub/src/base_grid.cpp @@ -140,6 +140,9 @@ void BaseGrid::EndBatch() { ////////////////////// // Makes cell visible void BaseGrid::MakeCellVisible(int row, int col,bool center) { + // Update last row selection + lastRow = row; + // Get size int w = 0; int h = 0; @@ -256,6 +259,17 @@ int BaseGrid::GetFirstSelRow() { } +///////////////////////////////////////////////////// +// Gets last selected row from first block selection +int BaseGrid::GetLastSelRow() { + int frow = GetFirstSelRow(); + while (IsInSelection(frow)) { + frow++; + } + return frow-1; +} + + ////////////////////////// // Gets all selected rows wxArrayInt BaseGrid::GetSelection(bool *cont) { diff --git a/aegisub/src/base_grid.h b/aegisub/src/base_grid.h index f935f9f6f..c7a840a92 100644 --- a/aegisub/src/base_grid.h +++ b/aegisub/src/base_grid.h @@ -103,6 +103,7 @@ public: bool IsDisplayed(AssDialogue *line); int GetNumberSelection(); int GetFirstSelRow(); + int GetLastSelRow(); void SelectVisible(); wxArrayInt GetSelection(bool *continuous=NULL); diff --git a/aegisub/src/frame_main_events.cpp b/aegisub/src/frame_main_events.cpp index 2049f4153..3be5f9a1c 100644 --- a/aegisub/src/frame_main_events.cpp +++ b/aegisub/src/frame_main_events.cpp @@ -1638,9 +1638,7 @@ void FrameMain::OnEditBoxCommit(wxCommandEvent &event) { // Is the text edit if (focus == EditBox->TextEdit) { - EditBox->CommitText(); - SubsBox->ass->FlagAsModified(_("editing")); - SubsBox->CommitChanges(); + EditBox->Commit(true); } // Other window diff --git a/aegisub/src/subs_edit_box.cpp b/aegisub/src/subs_edit_box.cpp index 199a15e37..23c28ca32 100644 --- a/aegisub/src/subs_edit_box.cpp +++ b/aegisub/src/subs_edit_box.cpp @@ -342,8 +342,6 @@ void SubsEditBox::SetToLine(int n,bool weak) { enabled = true; if (n != linen) { linen = n; - StartTime->Update(); - EndTime->Update(); Duration->Update(); } } @@ -714,7 +712,8 @@ void SubsEditBox::CommitTimes(bool start,bool end,bool fromStart,bool commit) { // Update lines for (int i=0;iGetDialogue(sel[i]); + if (grid->IsInSelection(linen)) cur = grid->GetDialogue(sel[i]); + else cur = grid->GetDialogue(linen); if (cur) { // Set times if (start) cur->Start = StartTime->time; @@ -725,11 +724,15 @@ 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; } } // Commit if (commit) { + StartTime->Update(); + EndTime->Update(); + Duration->Update(); grid->ass->FlagAsModified(_("modify times")); grid->CommitChanges(); audio->SetDialogue(grid,grid->GetDialogue(sel[0]),sel[0]); @@ -884,15 +887,43 @@ void SubsEditBox::DoKeyPress(wxKeyEvent &event) { ////////// // Commit 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(); // Update line CommitText(); - // Next line if control is not held down + // 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(); + if (timeNeedsCommit) { + grid->GetDialogue(sel[i])->Start.SetMS(StartTime->time.GetMS()); + grid->GetDialogue(sel[i])->End.SetMS(EndTime->time.GetMS()); + } + } + } + + // Update file + if (!updated && textNeedsCommit) { + grid->ass->FlagAsModified(_("editing")); + grid->CommitChanges(); + } + else if (!updated && (StartTime->HasBeenModified() || EndTime->HasBeenModified())) + CommitTimes(StartTime->HasBeenModified(),EndTime->HasBeenModified(),StartTime->HasBeenModified(),true); + + // Get next line if ctrl was not held down if (!stay) { - AssDialogue *cur = grid->GetDialogue(linen); - int nrows = grid->GetRows(); - int next = linen+1; + int next; + if (!grid->IsInSelection(linen)) next = linen+1; + else next = grid->GetLastSelRow()+1; + AssDialogue *cur = grid->GetDialogue(next-1); if (next >= nrows) { AssDialogue *newline = new AssDialogue; newline->Start = cur->End; @@ -907,12 +938,6 @@ void SubsEditBox::Commit(bool stay) { SetToLine(next); if (next >= nrows) return; } - - // Update file - if (!updated) { - grid->ass->FlagAsModified(_("editing")); - grid->CommitChanges(); - } } @@ -927,12 +952,14 @@ void SubsEditBox::CommitText(bool weak) { cur->Text = TextEdit->GetText(); // Update times - cur->Start = StartTime->time; - cur->End = EndTime->time; - if (cur->Start > cur->End) cur->End = cur->Start; - StartTime->Update(); - EndTime->Update(); - Duration->Update(); + if (grid->IsInSelection(linen)) { + cur->Start = StartTime->time; + cur->End = EndTime->time; + if (cur->Start > cur->End) { + cur->End = cur->Start; + EndTime->SetTime(cur->End.GetMS()); + } + } // Update audio if (!weak) {