Support instant-replacement with a custom emoji.
This commit is contained in:
parent
1d34c64da8
commit
0daf3d4ac7
2 changed files with 56 additions and 17 deletions
|
|
@ -35,7 +35,6 @@ constexpr auto kInstantReplaceWhatId = QTextFormat::UserProperty + 1;
|
|||
constexpr auto kInstantReplaceWithId = QTextFormat::UserProperty + 2;
|
||||
constexpr auto kReplaceTagId = QTextFormat::UserProperty + 3;
|
||||
constexpr auto kTagProperty = QTextFormat::UserProperty + 4;
|
||||
constexpr auto kCustomEmojiFormat = QTextFormat::UserObject + 1;
|
||||
constexpr auto kCustomEmojiText = QTextFormat::UserProperty + 5;
|
||||
constexpr auto kCustomEmojiLink = QTextFormat::UserProperty + 6;
|
||||
constexpr auto kCustomEmojiId = QTextFormat::UserProperty + 7;
|
||||
|
|
@ -50,6 +49,7 @@ const auto &kTagStrikeOut = InputField::kTagStrikeOut;
|
|||
const auto &kTagCode = InputField::kTagCode;
|
||||
const auto &kTagPre = InputField::kTagPre;
|
||||
const auto &kTagSpoiler = InputField::kTagSpoiler;
|
||||
const auto &kCustomEmojiFormat = InputField::kCustomEmojiFormat;
|
||||
const auto kTagCheckLinkMeta = u"^:/:/:^"_q;
|
||||
const auto kNewlineChars = QString("\r\n")
|
||||
+ QChar(0xfdd0) // QTextBeginningOfFrame
|
||||
|
|
@ -942,6 +942,8 @@ const QString InputField::kTagCode = QStringLiteral("`");
|
|||
const QString InputField::kTagPre = QStringLiteral("```");
|
||||
const QString InputField::kTagSpoiler = QStringLiteral("||");
|
||||
const QString InputField::kCustomEmojiTagStart = u"custom-emoji://"_q;
|
||||
const int InputField::kCustomEmojiFormat
|
||||
= QTextFormat::UserObject + 1;
|
||||
|
||||
class InputField::Inner final : public QTextEdit {
|
||||
public:
|
||||
|
|
@ -1012,12 +1014,9 @@ void InsertCustomEmojiAtCursor(
|
|||
format.setProperty(kCustomEmojiId, CustomEmojiIdFromLink(link));
|
||||
format.setVerticalAlignment(QTextCharFormat::AlignBottom);
|
||||
ApplyTagFormat(format, currentFormat);
|
||||
auto existingTag = format.property(kTagProperty).toString();
|
||||
auto existingTags = existingTag.isEmpty()
|
||||
? QList<QStringView>()
|
||||
: TextUtilities::SplitTags(existingTag);
|
||||
existingTags.push_back(unique);
|
||||
format.setProperty(kTagProperty, TextUtilities::JoinTag(existingTags));
|
||||
format.setProperty(kTagProperty, TextUtilities::TagWithAdded(
|
||||
format.property(kTagProperty).toString(),
|
||||
unique));
|
||||
cursor.insertText(kObjectReplacement, format);
|
||||
}
|
||||
|
||||
|
|
@ -3352,20 +3351,34 @@ void InputField::applyInstantReplace(
|
|||
} else if (position < length) {
|
||||
return;
|
||||
}
|
||||
commitInstantReplacement(position - length, position, with, what, true);
|
||||
}
|
||||
|
||||
void InputField::commitInstantReplacement(
|
||||
int from,
|
||||
int till,
|
||||
const QString &with) {
|
||||
commitInstantReplacement(from, till, with, std::nullopt, false);
|
||||
commitInstantReplacement(
|
||||
position - length,
|
||||
position,
|
||||
with,
|
||||
QString(),
|
||||
what,
|
||||
true);
|
||||
}
|
||||
|
||||
void InputField::commitInstantReplacement(
|
||||
int from,
|
||||
int till,
|
||||
const QString &with,
|
||||
const QString &customEmojiData) {
|
||||
commitInstantReplacement(
|
||||
from,
|
||||
till,
|
||||
with,
|
||||
customEmojiData,
|
||||
std::nullopt,
|
||||
false);
|
||||
}
|
||||
|
||||
void InputField::commitInstantReplacement(
|
||||
int from,
|
||||
int till,
|
||||
const QString &with,
|
||||
const QString &customEmojiData,
|
||||
std::optional<QString> checkOriginal,
|
||||
bool checkIfInMonospace) {
|
||||
const auto original = getTextWithTagsPart(from, till).text;
|
||||
|
|
@ -3388,17 +3401,32 @@ void InputField::commitInstantReplacement(
|
|||
cursor.setPosition(from);
|
||||
cursor.setPosition(till, QTextCursor::KeepAnchor);
|
||||
|
||||
const auto link = customEmojiData.isEmpty()
|
||||
? QString()
|
||||
: CustomEmojiLink(customEmojiData);
|
||||
const auto unique = link.isEmpty()
|
||||
? QString()
|
||||
: MakeUniqueCustomEmojiLink(link);
|
||||
auto format = [&]() -> QTextCharFormat {
|
||||
auto emojiLength = 0;
|
||||
const auto emoji = Emoji::Find(with, &emojiLength);
|
||||
if (!emoji || with.size() != emojiLength) {
|
||||
return _defaultCharFormat;
|
||||
} else if (!customEmojiData.isEmpty()) {
|
||||
auto result = QTextCharFormat();
|
||||
result.setObjectType(kCustomEmojiFormat);
|
||||
result.setProperty(kCustomEmojiText, with);
|
||||
result.setProperty(kCustomEmojiLink, unique);
|
||||
result.setProperty(kCustomEmojiId, CustomEmojiIdFromLink(link));
|
||||
result.setVerticalAlignment(QTextCharFormat::AlignBottom);
|
||||
return result;
|
||||
}
|
||||
const auto use = Integration::Instance().defaultEmojiVariant(
|
||||
emoji);
|
||||
return PrepareEmojiFormat(use, _st.font);
|
||||
}();
|
||||
const auto replacement = format.isImageFormat()
|
||||
const auto replacement = (format.isImageFormat()
|
||||
|| format.objectType() == kCustomEmojiFormat)
|
||||
? kObjectReplacement
|
||||
: with;
|
||||
format.setProperty(kInstantReplaceWhatId, original);
|
||||
|
|
@ -3407,6 +3435,11 @@ void InputField::commitInstantReplacement(
|
|||
kInstantReplaceRandomId,
|
||||
base::RandomValue<uint32>());
|
||||
ApplyTagFormat(format, cursor.charFormat());
|
||||
if (!unique.isEmpty()) {
|
||||
format.setProperty(kTagProperty, TextUtilities::TagWithAdded(
|
||||
format.property(kTagProperty).toString(),
|
||||
unique));
|
||||
}
|
||||
cursor.insertText(replacement, format);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -220,6 +220,7 @@ public:
|
|||
static const QString kTagPre;
|
||||
static const QString kTagSpoiler;
|
||||
static const QString kCustomEmojiTagStart;
|
||||
static const int kCustomEmojiFormat;
|
||||
|
||||
InputField(
|
||||
QWidget *parent,
|
||||
|
|
@ -301,7 +302,11 @@ public:
|
|||
void setInstantReplacesEnabled(rpl::producer<bool> enabled);
|
||||
void setMarkdownReplacesEnabled(rpl::producer<bool> enabled);
|
||||
void setExtendedContextMenu(rpl::producer<ExtendedContextMenu> value);
|
||||
void commitInstantReplacement(int from, int till, const QString &with);
|
||||
void commitInstantReplacement(
|
||||
int from,
|
||||
int till,
|
||||
const QString &with,
|
||||
const QString &customEmojiData);
|
||||
void commitMarkdownLinkEdit(
|
||||
EditLinkSelection selection,
|
||||
const QString &text,
|
||||
|
|
@ -497,6 +502,7 @@ private:
|
|||
int from,
|
||||
int till,
|
||||
const QString &with,
|
||||
const QString &customEmojiData,
|
||||
std::optional<QString> checkOriginal,
|
||||
bool checkIfInMonospace);
|
||||
bool commitMarkdownReplacement(
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue