Fix an off-by-1 bug in wxControl::FindAccelIndex() after "&&"

This resulted in wrong letter being underlined in wxGenericStaticText
when the mnemonic occurred after "&&" (i.e. an actual ampersand) in the
label.

Add unit test which passes now, but would fail before on the last check.
This commit is contained in:
Vadim Zeitlin
2019-06-19 19:40:05 +02:00
parent ee15a4c9e4
commit 672847772d
2 changed files with 24 additions and 2 deletions

View File

@@ -194,20 +194,24 @@ int wxControlBase::FindAccelIndex(const wxString& label, wxString *labelOnly)
labelOnly->Alloc(label.length());
}
// When computing the offset below, we need to ignore the characters that
// are not actually displayed, i.e. the ampersands themselves.
int numSkipped = 0;
int indexAccel = -1;
for ( wxString::const_iterator pc = label.begin(); pc != label.end(); ++pc )
{
if ( *pc == MNEMONIC_PREFIX )
{
++pc; // skip it
++numSkipped;
if ( pc == label.end() )
break;
else if ( *pc != MNEMONIC_PREFIX )
{
if ( indexAccel == -1 )
{
// remember it (-1 is for MNEMONIC_PREFIX itself
indexAccel = pc - label.begin() - 1;
indexAccel = pc - label.begin() - numSkipped;
}
else
{

View File

@@ -67,14 +67,23 @@ void DoTestLabel(wxControl* c)
CHECK( l == wxControl::RemoveMnemonics(c->GetLabel()) );
}
// Check that both "&" and "&" work in markup.
#if wxUSE_MARKUP
c->SetLabelMarkup("mnemonic in &markup");
CHECK( c->GetLabel() == "mnemonic in &markup" );
CHECK( c->GetLabelText() == "mnemonic in markup" );
c->SetLabelMarkup("mnemonic in &markup");
CHECK( c->GetLabel() == "mnemonic in &markup" );
CHECK( c->GetLabelText() == "mnemonic in markup" );
c->SetLabelMarkup("&& finally");
CHECK( c->GetLabel() == "&& finally" );
CHECK( c->GetLabelText() == "& finally" );
c->SetLabelMarkup("&& finally");
CHECK( c->GetLabel() == "&& finally" );
CHECK( c->GetLabelText() == "& finally" );
#endif // wxUSE_MARKUP
}
@@ -110,3 +119,12 @@ TEST_CASE("wxControl::RemoveMnemonics", "[wxControl][label][mnemonics]")
CHECK( "&mnemonic" == wxControl::RemoveMnemonics("&&mnemonic") );
CHECK( "&mnemonic" == wxControl::RemoveMnemonics("&&&mnemonic") );
}
TEST_CASE("wxControl::FindAccelIndex", "[wxControl][label][mnemonics]")
{
CHECK( wxControl::FindAccelIndex("foo") == wxNOT_FOUND );
CHECK( wxControl::FindAccelIndex("&foo") == 0 );
CHECK( wxControl::FindAccelIndex("f&oo") == 1 );
CHECK( wxControl::FindAccelIndex("foo && bar") == wxNOT_FOUND );
CHECK( wxControl::FindAccelIndex("foo && &bar") == 6 );
}