diff --git a/src/kits/interface/Menu.cpp b/src/kits/interface/Menu.cpp index 8a36f77ce0..83d6d7e597 100644 --- a/src/kits/interface/Menu.cpp +++ b/src/kits/interface/Menu.cpp @@ -1,10 +1,11 @@ /* - * Copyright 2001-2015 Haiku, Inc. All rights reserved. + * Copyright 2001-2018 Haiku, Inc. All rights reserved. * Distributed under the terms of the MIT license. * * Authors: * Stephan Aßmus, superstippi@gmx.de * Stefano Ceccherini, stefano.ceccherini@gmail.com + * Adrien Destugues, pulkomandy@pulkomandy.tk * Marc Flerackers, mflerackers@androme.be * Rene Gollent, anevilyak@gmail.com * John Scipione, jscipione@gmail.com @@ -15,6 +16,7 @@ #include #include +#include #include #include @@ -35,6 +37,7 @@ #include #include #include +#include #include #include @@ -69,15 +72,17 @@ public: TriggerList() {} ~TriggerList() {} - // TODO: make this work with Unicode characters! - bool HasTrigger(uint32 c) - { return fList.HasItem((void*)(addr_t)tolower(c)); } + { return fList.find(BUnicodeChar::ToLower(c)) != fList.end(); } + bool AddTrigger(uint32 c) - { return fList.AddItem((void*)(addr_t)tolower(c)); } + { + fList.insert(BUnicodeChar::ToLower(c)); + return true; + } private: - BList fList; + std::set fList; }; @@ -583,7 +588,7 @@ BMenu::KeyDown(const char* bytes, int32 numBytes) default: { - uint32 trigger = UTF8ToCharCode(&bytes); + uint32 trigger = BUnicodeChar::FromUTF8(&bytes); for (uint32 i = CountItems(); i-- > 0;) { BMenuItem* item = ItemAt(i); @@ -2870,27 +2875,34 @@ BMenu::_ChooseTrigger(const char* title, int32& index, uint32& trigger, if (title == NULL) return false; + index = 0; uint32 c; + const char* nextCharacter, *character; // two runs: first we look out for uppercase letters - // TODO: support Unicode characters correctly! - for (uint32 i = 0; (c = title[i]) != '\0'; i++) { - if (!IsInsideGlyph(c) && isupper(c) && !triggers.HasTrigger(c)) { - index = i; - trigger = tolower(c); - return triggers.AddTrigger(c); + nextCharacter = title; + character = nextCharacter; + while ((c = BUnicodeChar::FromUTF8(&nextCharacter)) != 0) { + if (!BUnicodeChar::IsUpper(c) || triggers.HasTrigger(c)) { + character = nextCharacter; + continue; } + trigger = BUnicodeChar::ToLower(c); + index = (int32)(character - title); + return triggers.AddTrigger(c); } // then, if we still haven't found anything, we accept them all - index = 0; - while ((c = UTF8ToCharCode(&title)) != 0) { - if (!isspace(c) && !triggers.HasTrigger(c)) { - trigger = tolower(c); - return triggers.AddTrigger(c); + nextCharacter = title; + character = nextCharacter; + while ((c = BUnicodeChar::FromUTF8(&nextCharacter)) != 0) { + if (BUnicodeChar::IsSpace(c) || triggers.HasTrigger(c)) { + character = nextCharacter; + continue; } - - index++; + trigger = BUnicodeChar::ToLower(c); + index = (int32)(character - title); + return triggers.AddTrigger(c); } return false;