SL-20463 Rename outfit dialog box accepts emoji characters
parent
fdc47e9a16
commit
ddb2c93818
|
|
@ -600,6 +600,7 @@ std::string mbcsstring_makeASCII(const std::string& wstr)
|
|||
}
|
||||
return out_str;
|
||||
}
|
||||
|
||||
std::string utf8str_removeCRLF(const std::string& utf8str)
|
||||
{
|
||||
if (0 == utf8str.length())
|
||||
|
|
@ -621,6 +622,43 @@ std::string utf8str_removeCRLF(const std::string& utf8str)
|
|||
return out;
|
||||
}
|
||||
|
||||
// Search for any emoji symbol, return true if found
|
||||
bool wstring_has_emoji(const LLWString& wstr)
|
||||
{
|
||||
for (const llwchar& wch : wstr)
|
||||
{
|
||||
if (LLStringOps::isEmoji(wch))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Cut emoji symbols if exist
|
||||
bool wstring_remove_emojis(LLWString& wstr)
|
||||
{
|
||||
bool found = false;
|
||||
for (size_t i = 0; i < wstr.size(); ++i)
|
||||
{
|
||||
if (LLStringOps::isEmoji(wstr[i]))
|
||||
{
|
||||
wstr.erase(i--, 1);
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
// Cut emoji symbols if exist
|
||||
bool utf8str_remove_emojis(std::string& utf8str)
|
||||
{
|
||||
LLWString wstr = utf8str_to_wstring(utf8str);
|
||||
if (!wstring_remove_emojis(wstr))
|
||||
return false;
|
||||
utf8str = wstring_to_utf8str(wstr);
|
||||
return true;
|
||||
}
|
||||
|
||||
#if LL_WINDOWS
|
||||
unsigned int ll_wstring_default_code_page()
|
||||
{
|
||||
|
|
@ -833,6 +871,66 @@ std::string LLStringOps::sDayFormat;
|
|||
std::string LLStringOps::sAM;
|
||||
std::string LLStringOps::sPM;
|
||||
|
||||
// static
|
||||
bool LLStringOps::isEmoji(llwchar wch)
|
||||
{
|
||||
// Most of the following symbols are not actually emoticons, but rather small pictures
|
||||
|
||||
// 0x1F000 .. 0x1F02F - mahjong tiles
|
||||
// https://symbl.cc/en/unicode/table/#mahjong-tiles
|
||||
|
||||
// 0x1F030 .. 0x1F09F - domino tiles
|
||||
// https://symbl.cc/en/unicode/table/#domino-tiles
|
||||
|
||||
// 0x1F0A0 .. 0x1F0FF - playing cards
|
||||
// https://symbl.cc/en/unicode/table/#playing-cards
|
||||
|
||||
// 0x1F100 .. 0x1F1FF - enclosed alphanumeric supplement
|
||||
// https://symbl.cc/en/unicode/table/#enclosed-alphanumeric-supplement
|
||||
|
||||
// 0x1F200 .. 0x1F2FF - enclosed ideographic supplement
|
||||
// https://symbl.cc/en/unicode/table/#enclosed-ideographic-supplement
|
||||
|
||||
// 0x1F300 .. 0x1F5FF - miscellaneous symbols and pictographs
|
||||
// https://symbl.cc/en/unicode/table/#miscellaneous-symbols-and-pictographs
|
||||
|
||||
// 0x1F600 .. 0x1F64F - emoticons
|
||||
// https://symbl.cc/en/unicode/table/#emoticons
|
||||
|
||||
// 0x1F650 .. 0x1F67F - ornamental dingbats
|
||||
// https://symbl.cc/en/unicode/table/#ornamental-dingbats
|
||||
|
||||
// 0x1F680 .. 0x1F6FF - transport and map symbols
|
||||
// https://symbl.cc/en/unicode/table/#transport-and-map-symbols
|
||||
|
||||
// 0x1F700 .. 0x1F77F - alchemical symbols
|
||||
// https://symbl.cc/en/unicode/table/#alchemical-symbols
|
||||
|
||||
// 0x1F780 .. 0x1F7FF - geometric shapes extended
|
||||
// https://symbl.cc/en/unicode/table/#geometric-shapes-extended
|
||||
|
||||
// 0x1F800 .. 0x1F8FF - supplemental arrows c
|
||||
// https://symbl.cc/en/unicode/table/#supplemental-arrows-c
|
||||
|
||||
// 0x1F900 .. 0x1F9FF - supplemental symbols and pictographs
|
||||
// https://symbl.cc/en/unicode/table/#supplemental-symbols-and-pictographs
|
||||
|
||||
// 0x1FA00 .. 0x1FA6F - chess symbols
|
||||
// https://symbl.cc/en/unicode/table/#chess-symbols
|
||||
|
||||
// 0x1FA70 .. 0x1FAFF - symbols and pictographs extended a
|
||||
// https://symbl.cc/en/unicode/table/#symbols-and-pictographs-extended-a
|
||||
|
||||
// 0x1FB00 .. 0x1FBFF - symbols for legacy computing
|
||||
// https://symbl.cc/en/unicode/table/#symbols-for-legacy-computing
|
||||
|
||||
// 0x1FC00 .. 0x1FFFF - undefined block 44
|
||||
// These symbols aren't defined yet
|
||||
// https://symbl.cc/en/unicode/table/#undefined-block-44
|
||||
|
||||
return wch >= 0x1F000 && wch < 0x1FC00;
|
||||
}
|
||||
|
||||
|
||||
S32 LLStringOps::collate(const llwchar* a, const llwchar* b)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -189,6 +189,8 @@ public:
|
|||
static bool isAlnum(char a) { return isalnum((unsigned char)a) != 0; }
|
||||
static bool isAlnum(llwchar a) { return iswalnum(a) != 0; }
|
||||
|
||||
static bool isEmoji(llwchar wch);
|
||||
|
||||
static S32 collate(const char* a, const char* b) { return strcoll(a, b); }
|
||||
static S32 collate(const llwchar* a, const llwchar* b);
|
||||
|
||||
|
|
@ -737,6 +739,11 @@ LL_COMMON_API std::string mbcsstring_makeASCII(const std::string& str);
|
|||
|
||||
LL_COMMON_API std::string utf8str_removeCRLF(const std::string& utf8str);
|
||||
|
||||
LL_COMMON_API bool wstring_has_emoji(const LLWString& wstr);
|
||||
|
||||
LL_COMMON_API bool wstring_remove_emojis(LLWString& wstr);
|
||||
|
||||
LL_COMMON_API bool utf8str_remove_emojis(std::string& utf8str);
|
||||
|
||||
#if LL_WINDOWS
|
||||
/* @name Windows string helpers
|
||||
|
|
|
|||
|
|
@ -95,6 +95,7 @@ LLLineEditor::Params::Params()
|
|||
commit_on_focus_lost("commit_on_focus_lost", true),
|
||||
ignore_tab("ignore_tab", true),
|
||||
is_password("is_password", false),
|
||||
allow_emoji("allow_emoji"),
|
||||
cursor_color("cursor_color"),
|
||||
use_bg_color("use_bg_color", false),
|
||||
bg_color("bg_color"),
|
||||
|
|
@ -141,6 +142,7 @@ LLLineEditor::LLLineEditor(const LLLineEditor::Params& p)
|
|||
mIgnoreArrowKeys( FALSE ),
|
||||
mIgnoreTab( p.ignore_tab ),
|
||||
mDrawAsterixes( p.is_password ),
|
||||
mAllowEmoji( p.allow_emoji ),
|
||||
mSpellCheck( p.spellcheck ),
|
||||
mSpellCheckStart(-1),
|
||||
mSpellCheckEnd(-1),
|
||||
|
|
@ -413,8 +415,13 @@ void LLLineEditor::setText(const LLStringExplicit &new_text, bool use_size_limit
|
|||
all_selected = all_selected || (len == 0 && hasFocus() && mSelectAllonFocusReceived);
|
||||
|
||||
std::string truncated_utf8 = new_text;
|
||||
if (!mAllowEmoji)
|
||||
{
|
||||
// Cut emoji symbols if exist
|
||||
utf8str_remove_emojis(truncated_utf8);
|
||||
}
|
||||
if (use_size_limit && truncated_utf8.size() > (U32)mMaxLengthBytes)
|
||||
{
|
||||
{
|
||||
truncated_utf8 = utf8str_truncate(new_text, mMaxLengthBytes);
|
||||
}
|
||||
mText.assign(truncated_utf8);
|
||||
|
|
@ -586,13 +593,21 @@ void LLLineEditor::replaceWithSuggestion(U32 index)
|
|||
{
|
||||
if ( (it->first <= (U32)mCursorPos) && (it->second >= (U32)mCursorPos) )
|
||||
{
|
||||
LLWString suggestion = utf8str_to_wstring(mSuggestionList[index]);
|
||||
if (!mAllowEmoji)
|
||||
{
|
||||
// Cut emoji symbols if exist
|
||||
wstring_remove_emojis(suggestion);
|
||||
}
|
||||
if (suggestion.empty())
|
||||
return;
|
||||
|
||||
deselect();
|
||||
|
||||
// Delete the misspelled word
|
||||
mText.erase(it->first, it->second - it->first);
|
||||
|
||||
// Insert the suggestion in its place
|
||||
LLWString suggestion = utf8str_to_wstring(mSuggestionList[index]);
|
||||
mText.insert(it->first, suggestion);
|
||||
setCursor(it->first + (S32)suggestion.length());
|
||||
|
||||
|
|
@ -955,9 +970,11 @@ void LLLineEditor::removeChar()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void LLLineEditor::addChar(const llwchar uni_char)
|
||||
{
|
||||
if (!mAllowEmoji && LLStringOps::isEmoji(uni_char))
|
||||
return;
|
||||
|
||||
llwchar new_c = uni_char;
|
||||
if (hasSelection())
|
||||
{
|
||||
|
|
@ -1257,6 +1274,11 @@ void LLLineEditor::pasteHelper(bool is_primary)
|
|||
|
||||
if (!paste.empty())
|
||||
{
|
||||
if (!mAllowEmoji)
|
||||
{
|
||||
wstring_remove_emojis(paste);
|
||||
}
|
||||
|
||||
if (!prevalidateInput(paste))
|
||||
return;
|
||||
|
||||
|
|
|
|||
|
|
@ -92,6 +92,7 @@ public:
|
|||
ignore_tab,
|
||||
bg_image_always_focused,
|
||||
is_password,
|
||||
allow_emoji,
|
||||
use_bg_color;
|
||||
|
||||
// colors
|
||||
|
|
@ -238,6 +239,7 @@ public:
|
|||
void setIgnoreArrowKeys(BOOL b) { mIgnoreArrowKeys = b; }
|
||||
void setIgnoreTab(BOOL b) { mIgnoreTab = b; }
|
||||
void setPassDelete(BOOL b) { mPassDelete = b; }
|
||||
void setAllowEmoji(BOOL b) { mAllowEmoji = b; }
|
||||
void setDrawAsterixes(BOOL b);
|
||||
|
||||
// get the cursor position of the beginning/end of the prev/next word in the text
|
||||
|
|
@ -396,6 +398,7 @@ protected:
|
|||
|
||||
BOOL mShowImageFocused;
|
||||
|
||||
bool mAllowEmoji;
|
||||
bool mUseBgColor;
|
||||
|
||||
LLWString mPreeditWString;
|
||||
|
|
|
|||
|
|
@ -88,6 +88,7 @@ LLNotificationForm::FormInput::FormInput()
|
|||
: type("type"),
|
||||
text("text"),
|
||||
max_length_chars("max_length_chars"),
|
||||
allow_emoji("allow_emoji"),
|
||||
width("width", 0),
|
||||
value("value")
|
||||
{}
|
||||
|
|
|
|||
|
|
@ -201,6 +201,7 @@ public:
|
|||
Mandatory<std::string> type;
|
||||
Optional<S32> width;
|
||||
Optional<S32> max_length_chars;
|
||||
Optional<bool> allow_emoji;
|
||||
Optional<std::string> text;
|
||||
|
||||
Optional<std::string> value;
|
||||
|
|
|
|||
|
|
@ -90,6 +90,7 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal
|
|||
std::string edit_text_contents;
|
||||
S32 edit_text_max_chars = 0;
|
||||
bool is_password = false;
|
||||
bool allow_emoji = false;
|
||||
|
||||
LLToastPanel::setBackgroundVisible(FALSE);
|
||||
LLToastPanel::setBackgroundOpaque(TRUE);
|
||||
|
|
@ -134,6 +135,7 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal
|
|||
edit_text_contents = (*it)["value"].asString();
|
||||
edit_text_name = (*it)["name"].asString();
|
||||
edit_text_max_chars = (*it)["max_length_chars"].asInteger();
|
||||
allow_emoji = (*it)["allow_emoji"].asBoolean();
|
||||
}
|
||||
else if (type == "password")
|
||||
{
|
||||
|
|
@ -292,6 +294,7 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal
|
|||
mLineEditor->reshape(leditor_rect.getWidth(), leditor_rect.getHeight());
|
||||
mLineEditor->setRect(leditor_rect);
|
||||
mLineEditor->setMaxTextChars(edit_text_max_chars);
|
||||
mLineEditor->setAllowEmoji(allow_emoji);
|
||||
mLineEditor->setText(edit_text_contents);
|
||||
|
||||
std::string notif_name = mNotification->getName();
|
||||
|
|
|
|||
Loading…
Reference in New Issue