Added storage of proper text size with emoji to input field.
This commit is contained in:
parent
3c8cf5f5db
commit
1587f9f1b9
2 changed files with 31 additions and 13 deletions
|
|
@ -1927,7 +1927,7 @@ bool InputField::hasText() const {
|
|||
return (from.next() != till);
|
||||
}
|
||||
|
||||
QString InputField::getTextPart(
|
||||
InputField::TextPart InputField::getTextPart(
|
||||
int start,
|
||||
int end,
|
||||
TagList &outTagsList,
|
||||
|
|
@ -1938,7 +1938,7 @@ QString InputField::getTextPart(
|
|||
if (end >= 0 && end <= start) {
|
||||
outTagsChanged = !outTagsList.isEmpty();
|
||||
outTagsList.clear();
|
||||
return QString();
|
||||
return { QString(), 0 };
|
||||
}
|
||||
|
||||
if (start < 0) {
|
||||
|
|
@ -1967,6 +1967,7 @@ QString InputField::getTextPart(
|
|||
if (!full && end < 0) {
|
||||
end = possibleLength;
|
||||
}
|
||||
auto textSizeWithoutSurrogatePairsCount = document->characterCount() - 1;
|
||||
|
||||
for (auto block = from; block != till;) {
|
||||
for (auto item = block.begin(); !item.atEnd(); ++item) {
|
||||
|
|
@ -1993,14 +1994,19 @@ QString InputField::getTextPart(
|
|||
}
|
||||
}
|
||||
|
||||
const auto emojiText = [&] {
|
||||
struct EmojiEntry final {
|
||||
QString text;
|
||||
uint8 surrogatePairs = 0;
|
||||
};
|
||||
|
||||
const auto emojiEntry = [&]() -> EmojiEntry {
|
||||
if (format.isImageFormat()) {
|
||||
const auto imageName = format.toImageFormat().name();
|
||||
if (const auto emoji = Emoji::FromUrl(imageName)) {
|
||||
return emoji->text();
|
||||
return { emoji->text(), emoji->surrogatePairs() };
|
||||
}
|
||||
}
|
||||
return format.property(kCustomEmojiText).toString();
|
||||
return { format.property(kCustomEmojiText).toString(), 0 };
|
||||
}();
|
||||
auto text = [&] {
|
||||
const auto result = fragment.text();
|
||||
|
|
@ -2030,9 +2036,12 @@ QString InputField::getTextPart(
|
|||
if (ch > begin) {
|
||||
result.append(begin, ch - begin);
|
||||
}
|
||||
adjustedLength += (emojiText.size() - 1);
|
||||
if (!emojiText.isEmpty()) {
|
||||
result.append(emojiText);
|
||||
const auto size = emojiEntry.text.size() - 1;
|
||||
adjustedLength += size;
|
||||
if (!emojiEntry.text.isEmpty()) {
|
||||
result.append(emojiEntry.text);
|
||||
textSizeWithoutSurrogatePairsCount += size
|
||||
- emojiEntry.surrogatePairs;
|
||||
}
|
||||
begin = ch + 1;
|
||||
} break;
|
||||
|
|
@ -2063,7 +2072,7 @@ QString InputField::getTextPart(
|
|||
markdownTagAccumulator.finish();
|
||||
|
||||
outTagsChanged = tagAccumulator.changed();
|
||||
return result;
|
||||
return { result, textSizeWithoutSurrogatePairsCount };
|
||||
}
|
||||
|
||||
bool InputField::isUndoAvailable() const {
|
||||
|
|
@ -2457,7 +2466,7 @@ void InputField::handleContentsChanged() {
|
|||
setErrorShown(false);
|
||||
|
||||
auto tagsChanged = false;
|
||||
const auto currentText = getTextPart(
|
||||
const auto [currentText, currentTextSize] = getTextPart(
|
||||
0,
|
||||
-1,
|
||||
_lastTextWithTags.tags,
|
||||
|
|
@ -2466,6 +2475,7 @@ void InputField::handleContentsChanged() {
|
|||
|
||||
//highlightMarkdown();
|
||||
|
||||
_lastTextSizeWithoutSurrogatePairsCount = currentTextSize;
|
||||
if (tagsChanged || (_lastTextWithTags.text != currentText)) {
|
||||
_lastTextWithTags.text = currentText;
|
||||
const auto weak = MakeWeak(this);
|
||||
|
|
@ -2640,7 +2650,7 @@ void InputField::setTextWithTags(
|
|||
TextWithTags InputField::getTextWithTagsPart(int start, int end) const {
|
||||
auto changed = false;
|
||||
auto result = TextWithTags();
|
||||
result.text = getTextPart(start, end, result.tags, changed);
|
||||
result.text = getTextPart(start, end, result.tags, changed).text;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -3988,7 +3998,7 @@ void PrepareFormattingOptimization(not_null<QTextDocument*> document) {
|
|||
|
||||
int FieldCharacterCount(not_null<InputField*> field) {
|
||||
// This method counts emoji properly.
|
||||
return field->document()->characterCount() - 1;
|
||||
return field->lastTextSizeWithoutSurrogatePairsCount();
|
||||
}
|
||||
|
||||
} // namespace Ui
|
||||
|
|
|
|||
|
|
@ -241,6 +241,9 @@ public:
|
|||
const QString &getLastText() const {
|
||||
return _lastTextWithTags.text;
|
||||
}
|
||||
[[nodiscard]] int lastTextSizeWithoutSurrogatePairsCount() const {
|
||||
return _lastTextSizeWithoutSurrogatePairsCount;
|
||||
}
|
||||
void setPlaceholder(
|
||||
rpl::producer<QString> placeholder,
|
||||
int afterSymbols = 0);
|
||||
|
|
@ -380,7 +383,11 @@ private:
|
|||
|
||||
// "start" and "end" are in coordinates of text where emoji are replaced
|
||||
// by ObjectReplacementCharacter. If "end" = -1 means get text till the end.
|
||||
QString getTextPart(
|
||||
struct TextPart final {
|
||||
QString text;
|
||||
int textSizeWithoutSurrogatePairsCount = 0;
|
||||
};
|
||||
TextPart getTextPart(
|
||||
int start,
|
||||
int end,
|
||||
TagList &outTagsList,
|
||||
|
|
@ -484,6 +491,7 @@ private:
|
|||
TextWithTags _lastTextWithTags;
|
||||
std::vector<MarkdownTag> _lastMarkdownTags;
|
||||
QString _lastPreEditText;
|
||||
int _lastTextSizeWithoutSurrogatePairsCount = 0;
|
||||
std::optional<QString> _inputMethodCommit;
|
||||
|
||||
QMargins _additionalMargins;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue