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