Fix #278 (desync between audio and karaoke selection after splitting karaoke)

Originally committed to SVN as r1287.
This commit is contained in:
Niels Martin Hansen 2007-06-22 22:50:02 +00:00
parent 9122cdf74a
commit cee5c46ab7
2 changed files with 44 additions and 31 deletions

View file

@ -1106,18 +1106,26 @@ void AudioDisplay::CommitChanges (bool nextLine) {
// Check validity // Check validity
bool wasKaraSplitting = false; bool wasKaraSplitting = false;
bool validCommit = true; bool validCommit = true;
if (!box->audioKaraoke->splitting) { if (!karaoke->enabled && !karaoke->splitting) {
wxLogDebug(_T("AudioDisplay::CommitChanges: was splitting karaoke")); wxLogDebug(_T("AudioDisplay::CommitChanges: was not splitting karaoke"));
if (!NeedCommit || curEndMS < curStartMS) validCommit = false; if (!NeedCommit || curEndMS < curStartMS) validCommit = false;
} }
// Update karaoke // Update karaoke
int karSyl = 0; int karaSelStart = 0, karaSelEnd = -1;
if (karaoke->enabled) { if (karaoke->enabled) {
wxLogDebug(_T("AudioDisplay::CommitChanges: karaoke enabled, committing it")); wxLogDebug(_T("AudioDisplay::CommitChanges: karaoke enabled, committing it"));
wasKaraSplitting = box->audioKaraoke->splitting; wasKaraSplitting = karaoke->splitting;
karaoke->Commit(); karaoke->Commit();
karSyl = karaoke->curSyllable; // Get karaoke selection
karaSelStart = karaoke->syllables.size();
for (size_t k = 0; k < karaoke->syllables.size(); ++k) {
if (karaoke->syllables[k].selected) {
if ((signed)k < karaSelStart) karaSelStart = k;
if ((signed)k > karaSelEnd) karaSelEnd = k;
}
}
wxLogDebug(_T("AudioDisplay::CommitChanges: karaSelStart=%d karaSelEnd=%d"), karaSelStart, karaSelEnd);
} }
// Commit ok? // Commit ok?
@ -1143,7 +1151,7 @@ void AudioDisplay::CommitChanges (bool nextLine) {
curDiag->End.SetMS(curEndMS); curDiag->End.SetMS(curEndMS);
if (!karaoke->enabled) { if (!karaoke->enabled) {
// If user was editing karaoke stuff, that should take precedence of manual changes in the editbox, // If user was editing karaoke stuff, that should take precedence of manual changes in the editbox,
// so only updated from editbox when not in kara mode // so only update from editbox when not in kara mode
curDiag->Text = grid->editBox->TextEdit->GetText(); curDiag->Text = grid->editBox->TextEdit->GetText();
} }
curDiag->UpdateData(); curDiag->UpdateData();
@ -1160,7 +1168,7 @@ void AudioDisplay::CommitChanges (bool nextLine) {
grid->editBox->Update(!karaoke->enabled); grid->editBox->Update(!karaoke->enabled);
grid->ass->FlagAsModified(_T("")); grid->ass->FlagAsModified(_T(""));
grid->CommitChanges(); grid->CommitChanges();
karaoke->curSyllable = karSyl; karaoke->SetSelection(karaSelStart, karaSelEnd);
blockUpdate = false; blockUpdate = false;
} }
@ -2232,7 +2240,6 @@ int AudioDisplay::GetSyllableAtX(int x) {
//////////////// ////////////////
// Focus events // Focus events
void AudioDisplay::OnGetFocus(wxFocusEvent &event) { void AudioDisplay::OnGetFocus(wxFocusEvent &event) {
wxLogDebug(_T("AudioDisplay::OnGetFocus"));
if (!hasFocus) { if (!hasFocus) {
hasFocus = true; hasFocus = true;
UpdateImage(true); UpdateImage(true);
@ -2240,7 +2247,6 @@ void AudioDisplay::OnGetFocus(wxFocusEvent &event) {
} }
void AudioDisplay::OnLoseFocus(wxFocusEvent &event) { void AudioDisplay::OnLoseFocus(wxFocusEvent &event) {
wxLogDebug(_T("AudioDisplay::OnLoseFocus"));
if (hasFocus && loaded) { if (hasFocus && loaded) {
hasFocus = false; hasFocus = false;
UpdateImage(true); UpdateImage(true);

View file

@ -606,6 +606,7 @@ void AudioKaraoke::SetSelection(int start,int end) {
syllables.at(i).selected = state; syllables.at(i).selected = state;
if (state) sels++; if (state) sels++;
} }
curSyllable = min;
// Set box buttons // Set box buttons
box->SetKaraokeButtons(sels > 1,sels > 0); box->SetKaraokeButtons(sels > 1,sels > 0);
@ -680,8 +681,6 @@ void AudioKaraoke::EndSplit(bool commit) {
} }
} }
SetSelection(0);
// Update // Update
if (hasSplit) { if (hasSplit) {
wxLogDebug(_T("AudioKaraoke::EndSplit: hasSplit")); wxLogDebug(_T("AudioKaraoke::EndSplit: hasSplit"));
@ -700,41 +699,49 @@ void AudioKaraoke::EndSplit(bool commit) {
// Split a syllable using the pending_slits data // Split a syllable using the pending_slits data
int AudioKaraoke::SplitSyl (unsigned int n) { int AudioKaraoke::SplitSyl (unsigned int n) {
wxLogDebug(_T("AudioKaraoke::SplitSyl(n=%u)"), n); wxLogDebug(_T("AudioKaraoke::SplitSyl(n=%u)"), n);
// Avoid multiple vector resizes (this must be first)
syllables.reserve(syllables.size() + syllables[n].pending_splits.size()); syllables.reserve(syllables.size() + syllables[n].pending_splits.size());
// Start by sorting the split points // The syllable we're splitting
std::sort(syllables[n].pending_splits.begin(),syllables[n].pending_splits.end()); KaraokeSyllable &basesyl = syllables[n];
wxLogDebug(_T("AudioKaraoke::SplitSyl: basesyl. contents='%s' selected=%d"), basesyl.contents.c_str(), basesyl.selected?1:0);
wxString originalText = syllables[n].contents; // Start by sorting the split points
int originalDuration = syllables[n].length; std::sort(basesyl.pending_splits.begin(), basesyl.pending_splits.end());
wxString originalText = basesyl.contents;
int originalDuration = basesyl.length;
// Fixup the first syllable // Fixup the first syllable
syllables[n].contents = originalText.Mid(0, syllables[n].pending_splits[0] + 1); basesyl.contents = originalText.Mid(0, basesyl.pending_splits[0] + 1);
syllables[n].length = originalDuration * syllables[n].contents.Length() / originalText.Length(); syllables[n].length = originalDuration * basesyl.contents.Length() / originalText.Length();
int curpos = syllables[n].position + syllables[n].length; int curpos = basesyl.position + basesyl.length;
// For each split, make a new syllable // For each split, make a new syllable
for (unsigned int i = 0; i < syllables[n].pending_splits.size(); i++) { for (unsigned int i = 0; i < basesyl.pending_splits.size(); i++) {
KaraokeSyllable temp; KaraokeSyllable newsyl;
if (i < syllables[n].pending_splits.size()-1) { if (i < basesyl.pending_splits.size()-1) {
// in the middle // in the middle
temp.contents = originalText.Mid(syllables[n].pending_splits[i]+1, syllables[n].pending_splits[i+1] - syllables[n].pending_splits[i]); newsyl.contents = originalText.Mid(basesyl.pending_splits[i]+1, basesyl.pending_splits[i+1] - basesyl.pending_splits[i]);
} else { } else {
// the last one (take the rest) // the last one (take the rest)
temp.contents = originalText.Mid(syllables[n].pending_splits[i]+1); newsyl.contents = originalText.Mid(basesyl.pending_splits[i]+1);
} }
temp.length = originalDuration * temp.contents.Length() / originalText.Length(); newsyl.length = originalDuration * newsyl.contents.Length() / originalText.Length();
temp.position = curpos; newsyl.position = curpos;
temp.tag = syllables[n].tag; newsyl.tag = basesyl.tag;
curpos += temp.length; newsyl.selected = basesyl.selected;
syllables.insert(syllables.begin()+n+i+1, temp); wxLogDebug(_T("AudioKaraoke::SplitSyl: newsyl. contents='%s' selected=%d"), newsyl.contents.c_str(), newsyl.selected?1:0);
curpos += newsyl.length;
syllables.insert(syllables.begin()+n+i+1, newsyl);
} }
// The total duration of the new syllables will be equal to or less than the original duration // The total duration of the new syllables will be equal to or less than the original duration
// Fix this, so they'll always add up // Fix this, so they'll always add up
// Use an unfair method, just adding 1 to each syllable one after another, until it's correct // Use an unfair method, just adding 1 to each syllable one after another, until it's correct
int newDuration = 0; int newDuration = 0;
for (unsigned int j = n; j < syllables[n].pending_splits.size()+n+1; j++) { for (unsigned int j = n; j < basesyl.pending_splits.size()+n+1; j++) {
newDuration += syllables[j].length; newDuration += syllables[j].length;
} }
unsigned int k = n; unsigned int k = n;
@ -748,8 +755,8 @@ int AudioKaraoke::SplitSyl (unsigned int n) {
} }
// Prepare for return and clear pending splits // Prepare for return and clear pending splits
int numsplits = syllables[n].pending_splits.size(); int numsplits = basesyl.pending_splits.size();
syllables[n].pending_splits.clear(); basesyl.pending_splits.clear();
return numsplits; return numsplits;
} }