Added new entity type for plain non-interactive links.
Increased size of the block flags by two bits. Added a text utility to wrap a simple text with plain links. Added a new flag to specify parsing of plain links.
This commit is contained in:
parent
8e999fe8fb
commit
745ce34dd5
6 changed files with 45 additions and 26 deletions
|
|
@ -77,7 +77,9 @@ TextWithEntities PrepareRichFromRich(
|
|||
const TextParseOptions &options) {
|
||||
auto result = text;
|
||||
const auto &preparsed = text.entities;
|
||||
if ((options.flags & TextParseLinks) && !preparsed.isEmpty()) {
|
||||
const bool parseLinks = (options.flags & TextParseLinks);
|
||||
const bool parsePlainLinks = (options.flags & TextParsePlainLinks);
|
||||
if (!preparsed.isEmpty() && (parseLinks || parsePlainLinks)) {
|
||||
bool parseMentions = (options.flags & TextParseMentions);
|
||||
bool parseHashtags = (options.flags & TextParseHashtags);
|
||||
bool parseBotCommands = (options.flags & TextParseBotCommands);
|
||||
|
|
@ -91,6 +93,12 @@ TextWithEntities PrepareRichFromRich(
|
|||
if (((type == EntityType::Mention || type == EntityType::MentionName) && !parseMentions) ||
|
||||
(type == EntityType::Hashtag && !parseHashtags) ||
|
||||
(type == EntityType::Cashtag && !parseHashtags) ||
|
||||
(type == EntityType::PlainLink
|
||||
&& !parsePlainLinks
|
||||
&& !parseMarkdown) ||
|
||||
(!parseLinks
|
||||
&& (type == EntityType::Url
|
||||
|| type == EntityType::CustomUrl)) ||
|
||||
(type == EntityType::BotCommand && !parseBotCommands) || // #TODO entities
|
||||
(!parseMarkdown && (type == EntityType::Bold
|
||||
|| type == EntityType::Semibold
|
||||
|
|
@ -601,6 +609,8 @@ bool Parser::checkEntities() {
|
|||
flags = TextBlockFItalic;
|
||||
} else if (entityType == EntityType::Underline) {
|
||||
flags = TextBlockFUnderline;
|
||||
} else if (entityType == EntityType::PlainLink) {
|
||||
flags = TextBlockFPlainLink;
|
||||
} else if (entityType == EntityType::StrikeOut) {
|
||||
flags = TextBlockFStrikeOut;
|
||||
} else if (entityType == EntityType::Code) { // #TODO entities
|
||||
|
|
@ -2880,7 +2890,7 @@ private:
|
|||
} else {
|
||||
_background = {};
|
||||
}
|
||||
if (block->lnkIndex()) {
|
||||
if (block->lnkIndex() || (block->flags() & TextBlockFPlainLink)) {
|
||||
_currentPen = &_textPalette->linkFg->p;
|
||||
_currentPenSelected = &_textPalette->selectLinkFg->p;
|
||||
} else if ((block->flags() & TextBlockFCode) || (block->flags() & TextBlockFPre)) {
|
||||
|
|
@ -3576,6 +3586,7 @@ TextForMimeData String::toText(
|
|||
{ TextBlockFBold, EntityType::Bold },
|
||||
{ TextBlockFSemibold, EntityType::Semibold },
|
||||
{ TextBlockFUnderline, EntityType::Underline },
|
||||
{ TextBlockFPlainLink, EntityType::PlainLink },
|
||||
{ TextBlockFStrikeOut, EntityType::StrikeOut },
|
||||
{ TextBlockFCode, EntityType::Code }, // #TODO entities
|
||||
{ TextBlockFPre, EntityType::Pre },
|
||||
|
|
|
|||
|
|
@ -345,11 +345,11 @@ AbstractBlock::AbstractBlock(
|
|||
const QString &str,
|
||||
uint16 from,
|
||||
uint16 length,
|
||||
uchar flags,
|
||||
uint16 flags,
|
||||
uint16 lnkIndex,
|
||||
uint16 spoilerIndex)
|
||||
: _from(from)
|
||||
, _flags((flags & 0xFF) | ((lnkIndex & 0xFFFF) << 12))
|
||||
, _flags((flags & 0b1111111111) | ((lnkIndex & 0xFFFF) << 14))
|
||||
, _spoilerIndex(spoilerIndex) {
|
||||
}
|
||||
|
||||
|
|
@ -374,11 +374,11 @@ QFixed AbstractBlock::f_rpadding() const {
|
|||
}
|
||||
|
||||
uint16 AbstractBlock::lnkIndex() const {
|
||||
return (_flags >> 12) & 0xFFFF;
|
||||
return (_flags >> 14) & 0xFFFF;
|
||||
}
|
||||
|
||||
void AbstractBlock::setLnkIndex(uint16 lnkIndex) {
|
||||
_flags = (_flags & ~(0xFFFF << 12)) | (lnkIndex << 12);
|
||||
_flags = (_flags & ~(0xFFFF << 14)) | (lnkIndex << 14);
|
||||
}
|
||||
|
||||
uint16 AbstractBlock::spoilerIndex() const {
|
||||
|
|
@ -390,11 +390,11 @@ void AbstractBlock::setSpoilerIndex(uint16 spoilerIndex) {
|
|||
}
|
||||
|
||||
TextBlockType AbstractBlock::type() const {
|
||||
return TextBlockType((_flags >> 8) & 0x0F);
|
||||
return TextBlockType((_flags >> 10) & 0x0F);
|
||||
}
|
||||
|
||||
int32 AbstractBlock::flags() const {
|
||||
return (_flags & 0xFFF);
|
||||
return (_flags & 0b1111111111);
|
||||
}
|
||||
|
||||
QFixed AbstractBlock::f_rbearing() const {
|
||||
|
|
@ -409,11 +409,11 @@ TextBlock::TextBlock(
|
|||
QFixed minResizeWidth,
|
||||
uint16 from,
|
||||
uint16 length,
|
||||
uchar flags,
|
||||
uint16 flags,
|
||||
uint16 lnkIndex,
|
||||
uint16 spoilerIndex)
|
||||
: AbstractBlock(font, str, from, length, flags, lnkIndex, spoilerIndex) {
|
||||
_flags |= ((TextBlockTText & 0x0F) << 8);
|
||||
_flags |= ((TextBlockTText & 0x0F) << 10);
|
||||
if (length) {
|
||||
style::font blockFont = font;
|
||||
if (!flags && lnkIndex) {
|
||||
|
|
@ -455,13 +455,13 @@ EmojiBlock::EmojiBlock(
|
|||
const QString &str,
|
||||
uint16 from,
|
||||
uint16 length,
|
||||
uchar flags,
|
||||
uint16 flags,
|
||||
uint16 lnkIndex,
|
||||
uint16 spoilerIndex,
|
||||
EmojiPtr emoji)
|
||||
: AbstractBlock(font, str, from, length, flags, lnkIndex, spoilerIndex)
|
||||
, _emoji(emoji) {
|
||||
_flags |= ((TextBlockTEmoji & 0x0F) << 8);
|
||||
_flags |= ((TextBlockTEmoji & 0x0F) << 10);
|
||||
_width = int(st::emojiSize + 2 * st::emojiPadding);
|
||||
_rpadding = 0;
|
||||
for (auto i = length; i != 0;) {
|
||||
|
|
@ -479,11 +479,11 @@ NewlineBlock::NewlineBlock(
|
|||
const QString &str,
|
||||
uint16 from,
|
||||
uint16 length,
|
||||
uchar flags,
|
||||
uint16 flags,
|
||||
uint16 lnkIndex,
|
||||
uint16 spoilerIndex)
|
||||
: AbstractBlock(font, str, from, length, flags, lnkIndex, spoilerIndex) {
|
||||
_flags |= ((TextBlockTNewline & 0x0F) << 8);
|
||||
_flags |= ((TextBlockTNewline & 0x0F) << 10);
|
||||
}
|
||||
|
||||
Qt::LayoutDirection NewlineBlock::nextDirection() const {
|
||||
|
|
@ -500,7 +500,7 @@ SkipBlock::SkipBlock(
|
|||
uint16 spoilerIndex)
|
||||
: AbstractBlock(font, str, from, 1, 0, lnkIndex, spoilerIndex)
|
||||
, _height(h) {
|
||||
_flags |= ((TextBlockTSkip & 0x0F) << 8);
|
||||
_flags |= ((TextBlockTSkip & 0x0F) << 10);
|
||||
_width = w;
|
||||
}
|
||||
|
||||
|
|
@ -641,7 +641,7 @@ Block Block::Newline(
|
|||
const QString &str,
|
||||
uint16 from,
|
||||
uint16 length,
|
||||
uchar flags,
|
||||
uint16 flags,
|
||||
uint16 lnkIndex,
|
||||
uint16 spoilerIndex) {
|
||||
return New<NewlineBlock>(
|
||||
|
|
@ -660,7 +660,7 @@ Block Block::Text(
|
|||
QFixed minResizeWidth,
|
||||
uint16 from,
|
||||
uint16 length,
|
||||
uchar flags,
|
||||
uint16 flags,
|
||||
uint16 lnkIndex,
|
||||
uint16 spoilerIndex) {
|
||||
return New<TextBlock>(
|
||||
|
|
@ -679,7 +679,7 @@ Block Block::Emoji(
|
|||
const QString &str,
|
||||
uint16 from,
|
||||
uint16 length,
|
||||
uchar flags,
|
||||
uint16 flags,
|
||||
uint16 lnkIndex,
|
||||
uint16 spoilerIndex,
|
||||
EmojiPtr emoji) {
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ enum TextBlockFlags {
|
|||
TextBlockFSemibold = 0x20,
|
||||
TextBlockFCode = 0x40,
|
||||
TextBlockFPre = 0x80,
|
||||
TextBlockFPlainLink = 0x100,
|
||||
};
|
||||
|
||||
class AbstractBlock {
|
||||
|
|
@ -58,13 +59,13 @@ protected:
|
|||
const QString &str,
|
||||
uint16 from,
|
||||
uint16 length,
|
||||
uchar flags,
|
||||
uint16 flags,
|
||||
uint16 lnkIndex,
|
||||
uint16 spoilerIndex);
|
||||
|
||||
uint16 _from = 0;
|
||||
|
||||
uint32 _flags = 0; // 4 bits empty, 16 bits lnkIndex, 4 bits type, 8 bits flags
|
||||
uint32 _flags = 0; // 2 bits empty, 16 bits lnkIndex, 4 bits type, 10 bits flags
|
||||
|
||||
uint16 _spoilerIndex = 0;
|
||||
|
||||
|
|
@ -86,7 +87,7 @@ public:
|
|||
const QString &str,
|
||||
uint16 from,
|
||||
uint16 length,
|
||||
uchar flags,
|
||||
uint16 flags,
|
||||
uint16 lnkIndex,
|
||||
uint16 spoilerIndex);
|
||||
|
||||
|
|
@ -126,7 +127,7 @@ public:
|
|||
QFixed minResizeWidth,
|
||||
uint16 from,
|
||||
uint16 length,
|
||||
uchar flags,
|
||||
uint16 flags,
|
||||
uint16 lnkIndex,
|
||||
uint16 spoilerIndex);
|
||||
|
||||
|
|
@ -150,7 +151,7 @@ public:
|
|||
const QString &str,
|
||||
uint16 from,
|
||||
uint16 length,
|
||||
uchar flags,
|
||||
uint16 flags,
|
||||
uint16 lnkIndex,
|
||||
uint16 spoilerIndex,
|
||||
EmojiPtr emoji);
|
||||
|
|
@ -200,7 +201,7 @@ public:
|
|||
const QString &str,
|
||||
uint16 from,
|
||||
uint16 length,
|
||||
uchar flags,
|
||||
uint16 flags,
|
||||
uint16 lnkIndex,
|
||||
uint16 spoilerIndex);
|
||||
|
||||
|
|
@ -210,7 +211,7 @@ public:
|
|||
QFixed minResizeWidth,
|
||||
uint16 from,
|
||||
uint16 length,
|
||||
uchar flags,
|
||||
uint16 flags,
|
||||
uint16 lnkIndex,
|
||||
uint16 spoilerIndex);
|
||||
|
||||
|
|
@ -219,7 +220,7 @@ public:
|
|||
const QString &str,
|
||||
uint16 from,
|
||||
uint16 length,
|
||||
uchar flags,
|
||||
uint16 flags,
|
||||
uint16 lnkIndex,
|
||||
uint16 spoilerIndex,
|
||||
EmojiPtr emoji);
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ enum class EntityType : uchar {
|
|||
MentionName,
|
||||
BotCommand,
|
||||
MediaTimestamp,
|
||||
PlainLink, // Senders in chat list, attachements in chat list, etc.
|
||||
|
||||
Bold,
|
||||
Semibold,
|
||||
|
|
@ -241,6 +242,7 @@ enum {
|
|||
TextParseHashtags = 0x010,
|
||||
TextParseBotCommands = 0x020,
|
||||
TextParseMarkdown = 0x040,
|
||||
TextParsePlainLinks = 0x080,
|
||||
};
|
||||
|
||||
struct TextWithTags {
|
||||
|
|
|
|||
|
|
@ -42,6 +42,10 @@ TextWithEntities Link(const QString &text, const QString &url) {
|
|||
return WithSingleEntity(text, EntityType::CustomUrl, url);
|
||||
}
|
||||
|
||||
TextWithEntities PlainLink(const QString &text) {
|
||||
return WithSingleEntity(text, EntityType::PlainLink);
|
||||
}
|
||||
|
||||
TextWithEntities RichLangValue(const QString &text) {
|
||||
static const auto kStart = QRegularExpression("(\\*\\*|__)");
|
||||
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ inline constexpr auto Upper = details::ToUpperType{};
|
|||
[[nodiscard]] TextWithEntities Link(
|
||||
const QString &text,
|
||||
const QString &url = "internal:action");
|
||||
[[nodiscard]] TextWithEntities PlainLink(const QString &text);
|
||||
[[nodiscard]] TextWithEntities RichLangValue(const QString &text);
|
||||
[[nodiscard]] inline TextWithEntities WithEntities(const QString &text) {
|
||||
return { text };
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue