mirror of
https://github.com/vale981/tdesktop
synced 2025-03-05 17:51:41 -05:00
Add support for Underline and Strike-through text.
This commit is contained in:
parent
d864ebd695
commit
8741266819
13 changed files with 166 additions and 39 deletions
|
@ -1536,6 +1536,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
"lng_menu_formatting" = "Formatting";
|
||||
"lng_menu_formatting_bold" = "Bold";
|
||||
"lng_menu_formatting_italic" = "Italic";
|
||||
"lng_menu_formatting_underline" = "Underline";
|
||||
"lng_menu_formatting_strike_out" = "Strike-through";
|
||||
"lng_menu_formatting_monospace" = "Monospace";
|
||||
"lng_menu_formatting_link_create" = "Create link";
|
||||
"lng_menu_formatting_link_edit" = "Edit link";
|
||||
|
|
|
@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/widgets/input_fields.h"
|
||||
#include "ui/widgets/labels.h"
|
||||
#include "ui/text/text_utilities.h"
|
||||
#include "core/click_handler_types.h" // UrlClickHandler
|
||||
#include "base/qthelp_url.h" // qthelp::url_encode
|
||||
#include "platform/platform_info.h" // Platform::SystemVersionPretty
|
||||
|
@ -268,15 +269,13 @@ void ConfirmPhoneBox::launch() {
|
|||
}
|
||||
|
||||
void ConfirmPhoneBox::prepare() {
|
||||
_about.create(this, st::confirmPhoneAboutLabel);
|
||||
TextWithEntities aboutText;
|
||||
auto formattedPhone = App::formatPhone(_phone);
|
||||
aboutText.text = tr::lng_confirm_phone_about(tr::now, lt_phone, formattedPhone);
|
||||
auto phonePosition = aboutText.text.indexOf(formattedPhone);
|
||||
if (phonePosition >= 0) {
|
||||
aboutText.entities.push_back({ EntityType::Bold, phonePosition, formattedPhone.size() });
|
||||
}
|
||||
_about->setMarkedText(aboutText);
|
||||
_about.create(
|
||||
this,
|
||||
tr::lng_confirm_phone_about(
|
||||
lt_phone,
|
||||
rpl::single(Ui::Text::Bold(App::formatPhone(_phone))),
|
||||
Ui::Text::WithEntities),
|
||||
st::confirmPhoneAboutLabel);
|
||||
|
||||
_code.create(this, st::confirmPhoneCodeField, tr::lng_code_ph());
|
||||
_code->setAutoSubmit(_sentCodeLength, [=] { sendCode(); });
|
||||
|
|
|
@ -237,6 +237,10 @@ EntitiesInText ConvertTextTagsToEntities(const TextWithTags::Tags &tags) {
|
|||
push(EntityType::Bold);
|
||||
} else if (tag.id == Ui::InputField::kTagItalic) {
|
||||
push(EntityType::Italic);
|
||||
} else if (tag.id == Ui::InputField::kTagUnderline) {
|
||||
push(EntityType::Underline);
|
||||
} else if (tag.id == Ui::InputField::kTagStrikeOut) {
|
||||
push(EntityType::StrikeOut);
|
||||
} else if (tag.id == Ui::InputField::kTagCode) {
|
||||
push(EntityType::Code);
|
||||
} else if (tag.id == Ui::InputField::kTagPre) { // #TODO entities
|
||||
|
@ -274,8 +278,14 @@ TextWithTags::Tags ConvertEntitiesToTextTags(const EntitiesInText &entities) {
|
|||
}
|
||||
} break;
|
||||
case EntityType::Bold: push(Ui::InputField::kTagBold); break;
|
||||
case EntityType::Italic: push(Ui::InputField::kTagItalic); break; // #TODO entities
|
||||
case EntityType::Code: push(Ui::InputField::kTagCode); break;
|
||||
case EntityType::Italic: push(Ui::InputField::kTagItalic); break;
|
||||
case EntityType::Underline:
|
||||
push(Ui::InputField::kTagUnderline);
|
||||
break;
|
||||
case EntityType::StrikeOut:
|
||||
push(Ui::InputField::kTagStrikeOut);
|
||||
break;
|
||||
case EntityType::Code: push(Ui::InputField::kTagCode); break; // #TODO entities
|
||||
case EntityType::Pre: push(Ui::InputField::kTagPre); break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -64,6 +64,7 @@ FontData::FontData(int size, uint32 flags, int family, Font *other)
|
|||
}
|
||||
f.setItalic(_flags & FontItalic);
|
||||
f.setUnderline(_flags & FontUnderline);
|
||||
f.setStrikeOut(_flags & FontStrikeOut);
|
||||
f.setStyleStrategy(QFont::PreferQuality);
|
||||
|
||||
m = QFontMetrics(f);
|
||||
|
@ -86,6 +87,10 @@ Font FontData::underline(bool set) const {
|
|||
return otherFlagsFont(FontUnderline, set);
|
||||
}
|
||||
|
||||
Font FontData::strikeout(bool set) const {
|
||||
return otherFlagsFont(FontStrikeOut, set);
|
||||
}
|
||||
|
||||
int FontData::size() const {
|
||||
return _size;
|
||||
}
|
||||
|
|
|
@ -56,8 +56,9 @@ enum FontFlags {
|
|||
FontBold = 0x01,
|
||||
FontItalic = 0x02,
|
||||
FontUnderline = 0x04,
|
||||
FontStrikeOut = 0x08,
|
||||
|
||||
FontDifferentFlags = 0x08,
|
||||
FontDifferentFlags = 0x10,
|
||||
};
|
||||
|
||||
class FontData {
|
||||
|
@ -79,6 +80,7 @@ public:
|
|||
Font bold(bool set = true) const;
|
||||
Font italic(bool set = true) const;
|
||||
Font underline(bool set = true) const;
|
||||
Font strikeout(bool set = true) const;
|
||||
|
||||
int size() const;
|
||||
uint32 flags() const;
|
||||
|
|
|
@ -84,7 +84,12 @@ TextWithEntities PrepareRichFromRich(
|
|||
(type == EntityType::Hashtag && !parseHashtags) ||
|
||||
(type == EntityType::Cashtag && !parseHashtags) ||
|
||||
(type == EntityType::BotCommand && !parseBotCommands) || // #TODO entities
|
||||
((type == EntityType::Bold || type == EntityType::Italic || type == EntityType::Code || type == EntityType::Pre) && !parseMarkdown)) {
|
||||
(!parseMarkdown && (type == EntityType::Bold
|
||||
|| type == EntityType::Italic
|
||||
|| type == EntityType::Underline
|
||||
|| type == EntityType::StrikeOut
|
||||
|| type == EntityType::Code
|
||||
|| type == EntityType::Pre))) {
|
||||
continue;
|
||||
}
|
||||
result.entities.push_back(preparsed.at(i));
|
||||
|
@ -545,6 +550,10 @@ bool Parser::checkEntities() {
|
|||
flags = TextBlockFSemibold;
|
||||
} else if (entityType == EntityType::Italic) {
|
||||
flags = TextBlockFItalic;
|
||||
} else if (entityType == EntityType::Underline) {
|
||||
flags = TextBlockFUnderline;
|
||||
} else if (entityType == EntityType::StrikeOut) {
|
||||
flags = TextBlockFStrikeOut;
|
||||
} else if (entityType == EntityType::Code) { // #TODO entities
|
||||
flags = TextBlockFCode;
|
||||
} else if (entityType == EntityType::Pre) {
|
||||
|
@ -699,6 +708,20 @@ bool Parser::readCommand() {
|
|||
}
|
||||
break;
|
||||
|
||||
case TextCommandStrikeOut:
|
||||
if (!(_flags & TextBlockFStrikeOut)) {
|
||||
createBlock();
|
||||
_flags |= TextBlockFStrikeOut;
|
||||
}
|
||||
break;
|
||||
|
||||
case TextCommandNoStrikeOut:
|
||||
if (_flags & TextBlockFStrikeOut) {
|
||||
createBlock();
|
||||
_flags &= ~TextBlockFStrikeOut;
|
||||
}
|
||||
break;
|
||||
|
||||
case TextCommandLinkIndex:
|
||||
if (_ptr->unicode() != _lnkIndex) {
|
||||
createBlock();
|
||||
|
@ -2035,6 +2058,7 @@ private:
|
|||
}
|
||||
if (flags & TextBlockFItalic) result = result->italic();
|
||||
if (flags & TextBlockFUnderline) result = result->underline();
|
||||
if (flags & TextBlockFStrikeOut) result = result->strikeout();
|
||||
if (flags & TextBlockFTilde) { // tilde fix in OpenSans
|
||||
result = st::semiboldFont;
|
||||
}
|
||||
|
@ -3217,6 +3241,8 @@ TextForMimeData String::toText(
|
|||
? std::vector<MarkdownTagTracker>{
|
||||
{ TextBlockFItalic, EntityType::Italic },
|
||||
{ TextBlockFSemibold, EntityType::Bold },
|
||||
{ TextBlockFUnderline, EntityType::Underline },
|
||||
{ TextBlockFStrikeOut, EntityType::StrikeOut },
|
||||
{ TextBlockFCode, EntityType::Code }, // #TODO entities
|
||||
{ TextBlockFPre, EntityType::Pre }
|
||||
} : std::vector<MarkdownTagTracker>();
|
||||
|
|
|
@ -21,10 +21,12 @@ enum TextCommands {
|
|||
TextCommandNoItalic = 0x04,
|
||||
TextCommandUnderline = 0x05,
|
||||
TextCommandNoUnderline = 0x06,
|
||||
TextCommandSemibold = 0x07,
|
||||
TextCommandNoSemibold = 0x08,
|
||||
TextCommandLinkIndex = 0x09, // 0 - NoLink
|
||||
TextCommandLinkText = 0x0A,
|
||||
TextCommandStrikeOut = 0x07,
|
||||
TextCommandNoStrikeOut = 0x08,
|
||||
TextCommandSemibold = 0x09,
|
||||
TextCommandNoSemibold = 0x0A,
|
||||
TextCommandLinkIndex = 0x0B, // 0 - NoLink
|
||||
TextCommandLinkText = 0x0C,
|
||||
TextCommandSkipBlock = 0x0D,
|
||||
|
||||
TextCommandLangTag = 0x20,
|
||||
|
|
|
@ -322,6 +322,7 @@ TextBlock::TextBlock(const style::font &font, const QString &str, QFixed minResi
|
|||
}
|
||||
if (flags & TextBlockFItalic) blockFont = blockFont->italic();
|
||||
if (flags & TextBlockFUnderline) blockFont = blockFont->underline();
|
||||
if (flags & TextBlockFStrikeOut) blockFont = blockFont->strikeout();
|
||||
if (flags & TextBlockFTilde) { // tilde fix in OpenSans
|
||||
blockFont = st::semiboldFont;
|
||||
}
|
||||
|
|
|
@ -23,10 +23,11 @@ enum TextBlockFlags {
|
|||
TextBlockFBold = 0x01,
|
||||
TextBlockFItalic = 0x02,
|
||||
TextBlockFUnderline = 0x04,
|
||||
TextBlockFTilde = 0x08, // tilde fix in OpenSans
|
||||
TextBlockFSemibold = 0x10,
|
||||
TextBlockFCode = 0x20,
|
||||
TextBlockFPre = 0x40,
|
||||
TextBlockFStrikeOut = 0x08,
|
||||
TextBlockFTilde = 0x10, // tilde fix in OpenSans
|
||||
TextBlockFSemibold = 0x20,
|
||||
TextBlockFCode = 0x40,
|
||||
TextBlockFPre = 0x80,
|
||||
};
|
||||
|
||||
class AbstractBlock {
|
||||
|
|
|
@ -36,7 +36,7 @@ QString ExpressionSeparators(const QString &additional) {
|
|||
|
||||
QString Separators(const QString &additional) {
|
||||
static const auto quotes = Quotes();
|
||||
return qsl(" \x10\n\r\t.,:;<>|'\"[]{}~!?%^()-+=")
|
||||
return qsl(" \x10\n\r\t.,:;<>|'\"[]{}!?%^()-+=")
|
||||
+ QChar(0xfdd0) // QTextBeginningOfFrame
|
||||
+ QChar(0xfdd1) // QTextEndOfFrame
|
||||
+ QChar(QChar::ParagraphSeparator)
|
||||
|
@ -46,15 +46,19 @@ QString Separators(const QString &additional) {
|
|||
}
|
||||
|
||||
QString SeparatorsBold() {
|
||||
return Separators(qsl("`/"));
|
||||
return Separators(qsl("`~/"));
|
||||
}
|
||||
|
||||
QString SeparatorsItalic() {
|
||||
return Separators(qsl("`*/"));
|
||||
return Separators(qsl("`*~/"));
|
||||
}
|
||||
|
||||
QString SeparatorsStrikeOut() {
|
||||
return Separators(qsl("`*~/"));
|
||||
}
|
||||
|
||||
QString SeparatorsMono() {
|
||||
return Separators(qsl("*/"));
|
||||
return Separators(qsl("*~/"));
|
||||
}
|
||||
|
||||
QString ExpressionHashtag() {
|
||||
|
@ -1173,6 +1177,14 @@ QString MarkdownItalicBadAfter() {
|
|||
return qsl("_");
|
||||
}
|
||||
|
||||
QString MarkdownStrikeOutGoodBefore() {
|
||||
return SeparatorsStrikeOut();
|
||||
}
|
||||
|
||||
QString MarkdownStrikeOutBadAfter() {
|
||||
return qsl("~");
|
||||
}
|
||||
|
||||
QString MarkdownCodeGoodBefore() {
|
||||
return SeparatorsMono();
|
||||
}
|
||||
|
@ -1500,6 +1512,8 @@ EntitiesInText EntitiesFromMTP(const QVector<MTPMessageEntity> &entities) {
|
|||
case mtpc_messageEntityBotCommand: { auto &d = entity.c_messageEntityBotCommand(); result.push_back({ EntityType::BotCommand, d.voffset.v, d.vlength.v }); } break;
|
||||
case mtpc_messageEntityBold: { auto &d = entity.c_messageEntityBold(); result.push_back({ EntityType::Bold, d.voffset.v, d.vlength.v }); } break;
|
||||
case mtpc_messageEntityItalic: { auto &d = entity.c_messageEntityItalic(); result.push_back({ EntityType::Italic, d.voffset.v, d.vlength.v }); } break;
|
||||
case mtpc_messageEntityUnderline: { auto &d = entity.c_messageEntityUnderline(); result.push_back({ EntityType::Underline, d.voffset.v, d.vlength.v }); } break;
|
||||
case mtpc_messageEntityStrike: { auto &d = entity.c_messageEntityStrike(); result.push_back({ EntityType::StrikeOut, d.voffset.v, d.vlength.v }); } break;
|
||||
case mtpc_messageEntityCode: { auto &d = entity.c_messageEntityCode(); result.push_back({ EntityType::Code, d.voffset.v, d.vlength.v }); } break;
|
||||
case mtpc_messageEntityPre: { auto &d = entity.c_messageEntityPre(); result.push_back({ EntityType::Pre, d.voffset.v, d.vlength.v, Clean(qs(d.vlanguage)) }); } break;
|
||||
// #TODO entities
|
||||
|
@ -1517,6 +1531,8 @@ MTPVector<MTPMessageEntity> EntitiesToMTP(const EntitiesInText &entities, Conver
|
|||
if (option == ConvertOption::SkipLocal
|
||||
&& entity.type() != EntityType::Bold
|
||||
&& entity.type() != EntityType::Italic
|
||||
&& entity.type() != EntityType::Underline
|
||||
&& entity.type() != EntityType::StrikeOut
|
||||
&& entity.type() != EntityType::Code // #TODO entities
|
||||
&& entity.type() != EntityType::Pre
|
||||
&& entity.type() != EntityType::MentionName
|
||||
|
@ -1550,6 +1566,8 @@ MTPVector<MTPMessageEntity> EntitiesToMTP(const EntitiesInText &entities, Conver
|
|||
case EntityType::BotCommand: v.push_back(MTP_messageEntityBotCommand(offset, length)); break;
|
||||
case EntityType::Bold: v.push_back(MTP_messageEntityBold(offset, length)); break;
|
||||
case EntityType::Italic: v.push_back(MTP_messageEntityItalic(offset, length)); break;
|
||||
case EntityType::Underline: v.push_back(MTP_messageEntityUnderline(offset, length)); break;
|
||||
case EntityType::StrikeOut: v.push_back(MTP_messageEntityStrike(offset, length)); break;
|
||||
case EntityType::Code: v.push_back(MTP_messageEntityCode(offset, length)); break; // #TODO entities
|
||||
case EntityType::Pre: v.push_back(MTP_messageEntityPre(offset, length, MTP_string(entity.data()))); break;
|
||||
}
|
||||
|
|
|
@ -21,6 +21,8 @@ enum class EntityType {
|
|||
|
||||
Bold,
|
||||
Italic,
|
||||
Underline,
|
||||
StrikeOut,
|
||||
Code, // inline
|
||||
Pre, // block
|
||||
};
|
||||
|
@ -267,6 +269,8 @@ QString MarkdownBoldGoodBefore();
|
|||
QString MarkdownBoldBadAfter();
|
||||
QString MarkdownItalicGoodBefore();
|
||||
QString MarkdownItalicBadAfter();
|
||||
QString MarkdownStrikeOutGoodBefore();
|
||||
QString MarkdownStrikeOutBadAfter();
|
||||
QString MarkdownCodeGoodBefore();
|
||||
QString MarkdownCodeBadAfter();
|
||||
QString MarkdownPreGoodBefore();
|
||||
|
|
|
@ -38,6 +38,8 @@ const auto kObjectReplacement = QString::fromRawData(
|
|||
1);
|
||||
const auto &kTagBold = InputField::kTagBold;
|
||||
const auto &kTagItalic = InputField::kTagItalic;
|
||||
const auto &kTagUnderline = InputField::kTagUnderline;
|
||||
const auto &kTagStrikeOut = InputField::kTagStrikeOut;
|
||||
const auto &kTagCode = InputField::kTagCode;
|
||||
const auto &kTagPre = InputField::kTagPre;
|
||||
const auto kNewlineChars = QString("\r\n")
|
||||
|
@ -46,6 +48,7 @@ const auto kNewlineChars = QString("\r\n")
|
|||
+ QChar(QChar::ParagraphSeparator)
|
||||
+ QChar(QChar::LineSeparator);
|
||||
const auto kClearFormatSequence = QKeySequence("ctrl+shift+n");
|
||||
const auto kStrikeOutSequence = QKeySequence("ctrl+shift+x");
|
||||
const auto kMonospaceSequence = QKeySequence("ctrl+shift+m");
|
||||
const auto kEditLinkSequence = QKeySequence("ctrl+k");
|
||||
|
||||
|
@ -175,12 +178,16 @@ struct TagStartExpression {
|
|||
QString tag;
|
||||
QString goodBefore;
|
||||
QString badAfter;
|
||||
QString badBefore;
|
||||
QString goodAfter;
|
||||
};
|
||||
|
||||
constexpr auto kTagBoldIndex = 0;
|
||||
constexpr auto kTagItalicIndex = 1;
|
||||
constexpr auto kTagCodeIndex = 2;
|
||||
constexpr auto kTagPreIndex = 3;
|
||||
//constexpr auto kTagUnderlineIndex = 2;
|
||||
constexpr auto kTagStrikeOutIndex = 2;
|
||||
constexpr auto kTagCodeIndex = 3;
|
||||
constexpr auto kTagPreIndex = 4;
|
||||
constexpr auto kInvalidPosition = std::numeric_limits<int>::max() / 2;
|
||||
|
||||
class TagSearchItem {
|
||||
|
@ -208,24 +215,34 @@ public:
|
|||
const auto length = text.size();
|
||||
const auto &tag = expression.tag;
|
||||
const auto tagLength = tag.size();
|
||||
const auto isGood = [&](QChar ch) {
|
||||
return (expression.goodBefore.indexOf(ch) >= 0);
|
||||
const auto isGoodBefore = [&](QChar ch) {
|
||||
return expression.goodBefore.isEmpty()
|
||||
|| (expression.goodBefore.indexOf(ch) >= 0);
|
||||
};
|
||||
const auto isBad = [&](QChar ch) {
|
||||
return (expression.badAfter.indexOf(ch) >= 0);
|
||||
const auto isBadAfter = [&](QChar ch) {
|
||||
return !expression.badAfter.isEmpty()
|
||||
&& (expression.badAfter.indexOf(ch) >= 0);
|
||||
};
|
||||
const auto isBadBefore = [&](QChar ch) {
|
||||
return !expression.badBefore.isEmpty()
|
||||
&& (expression.badBefore.indexOf(ch) >= 0);
|
||||
};
|
||||
const auto isGoodAfter = [&](QChar ch) {
|
||||
return expression.goodAfter.isEmpty()
|
||||
|| (expression.goodAfter.indexOf(ch) >= 0);
|
||||
};
|
||||
const auto check = [&](Edge edge) {
|
||||
if (_position > 0) {
|
||||
const auto before = text[_position - 1];
|
||||
if ((edge == Edge::Open && !isGood(before))
|
||||
|| (edge == Edge::Close && isBad(before))) {
|
||||
if ((edge == Edge::Open && !isGoodBefore(before))
|
||||
|| (edge == Edge::Close && isBadBefore(before))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (_position + tagLength < length) {
|
||||
const auto after = text[_position + tagLength];
|
||||
if ((edge == Edge::Open && isBad(after))
|
||||
|| (edge == Edge::Close && !isGood(after))) {
|
||||
if ((edge == Edge::Open && isBadAfter(after))
|
||||
|| (edge == Edge::Close && !isGoodAfter(after))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -275,22 +292,44 @@ const std::vector<TagStartExpression> &TagStartExpressions() {
|
|||
{
|
||||
kTagBold,
|
||||
TextUtilities::MarkdownBoldGoodBefore(),
|
||||
TextUtilities::MarkdownBoldBadAfter()
|
||||
TextUtilities::MarkdownBoldBadAfter(),
|
||||
TextUtilities::MarkdownBoldBadAfter(),
|
||||
TextUtilities::MarkdownBoldGoodBefore()
|
||||
},
|
||||
{
|
||||
kTagItalic,
|
||||
TextUtilities::MarkdownItalicGoodBefore(),
|
||||
TextUtilities::MarkdownItalicBadAfter()
|
||||
TextUtilities::MarkdownItalicBadAfter(),
|
||||
TextUtilities::MarkdownItalicBadAfter(),
|
||||
TextUtilities::MarkdownItalicGoodBefore()
|
||||
},
|
||||
//{
|
||||
// kTagUnderline,
|
||||
// TextUtilities::MarkdownUnderlineGoodBefore(),
|
||||
// TextUtilities::MarkdownUnderlineBadAfter(),
|
||||
// TextUtilities::MarkdownUnderlineBadAfter(),
|
||||
// TextUtilities::MarkdownUnderlineGoodBefore()
|
||||
//},
|
||||
{
|
||||
kTagStrikeOut,
|
||||
TextUtilities::MarkdownStrikeOutGoodBefore(),
|
||||
TextUtilities::MarkdownStrikeOutBadAfter(),
|
||||
TextUtilities::MarkdownStrikeOutBadAfter(),
|
||||
QString(),
|
||||
},
|
||||
{
|
||||
kTagCode,
|
||||
TextUtilities::MarkdownCodeGoodBefore(),
|
||||
TextUtilities::MarkdownCodeBadAfter()
|
||||
TextUtilities::MarkdownCodeBadAfter(),
|
||||
TextUtilities::MarkdownCodeBadAfter(),
|
||||
TextUtilities::MarkdownCodeGoodBefore()
|
||||
},
|
||||
{
|
||||
kTagPre,
|
||||
TextUtilities::MarkdownPreGoodBefore(),
|
||||
TextUtilities::MarkdownPreBadAfter()
|
||||
TextUtilities::MarkdownPreBadAfter(),
|
||||
TextUtilities::MarkdownPreBadAfter(),
|
||||
TextUtilities::MarkdownPreGoodBefore()
|
||||
},
|
||||
};
|
||||
return cached;
|
||||
|
@ -300,6 +339,8 @@ const std::map<QString, int> &TagIndices() {
|
|||
static auto cached = std::map<QString, int> {
|
||||
{ kTagBold, kTagBoldIndex },
|
||||
{ kTagItalic, kTagItalicIndex },
|
||||
//{ kTagUnderline, kTagUnderlineIndex },
|
||||
{ kTagStrikeOut, kTagStrikeOutIndex },
|
||||
{ kTagCode, kTagCodeIndex },
|
||||
{ kTagPre, kTagPreIndex },
|
||||
};
|
||||
|
@ -646,6 +687,12 @@ QTextCharFormat PrepareTagFormat(
|
|||
} else if (tag == kTagItalic) {
|
||||
result.setForeground(st.textFg);
|
||||
result.setFont(st.font->italic());
|
||||
} else if (tag == kTagUnderline) {
|
||||
result.setForeground(st.textFg);
|
||||
result.setFont(st.font->underline());
|
||||
} else if (tag == kTagStrikeOut) {
|
||||
result.setForeground(st.textFg);
|
||||
result.setFont(st.font->strikeout());
|
||||
} else if (tag == kTagCode || tag == kTagPre) {
|
||||
result.setForeground(st::defaultTextPalette.monoFg);
|
||||
result.setFont(AdjustFont(App::monofont(), st.font));
|
||||
|
@ -794,6 +841,8 @@ QString ExpandCustomLinks(const TextWithTags &text) {
|
|||
|
||||
const QString InputField::kTagBold = qsl("**");
|
||||
const QString InputField::kTagItalic = qsl("__");
|
||||
const QString InputField::kTagUnderline = qsl("^^"); // Not for Markdown.
|
||||
const QString InputField::kTagStrikeOut = qsl("~~");
|
||||
const QString InputField::kTagCode = qsl("`");
|
||||
const QString InputField::kTagPre = qsl("```");
|
||||
|
||||
|
@ -2694,6 +2743,10 @@ bool InputField::handleMarkdownKey(QKeyEvent *e) {
|
|||
toggleSelectionMarkdown(kTagBold);
|
||||
} else if (e == QKeySequence::Italic) {
|
||||
toggleSelectionMarkdown(kTagItalic);
|
||||
} else if (e == QKeySequence::Underline) {
|
||||
toggleSelectionMarkdown(kTagUnderline);
|
||||
} else if (matches(kStrikeOutSequence)) {
|
||||
toggleSelectionMarkdown(kTagStrikeOut);
|
||||
} else if (matches(kMonospaceSequence)) {
|
||||
toggleSelectionMarkdown(kTagCode);
|
||||
} else if (matches(kClearFormatSequence)) {
|
||||
|
@ -3358,6 +3411,8 @@ void InputField::addMarkdownActions(
|
|||
|
||||
addtag(tr::lng_menu_formatting_bold(tr::now), QKeySequence::Bold, kTagBold);
|
||||
addtag(tr::lng_menu_formatting_italic(tr::now), QKeySequence::Italic, kTagItalic);
|
||||
addtag(tr::lng_menu_formatting_underline(tr::now), QKeySequence::Underline, kTagUnderline);
|
||||
addtag(tr::lng_menu_formatting_strike_out(tr::now), kStrikeOutSequence, kTagStrikeOut);
|
||||
addtag(tr::lng_menu_formatting_monospace(tr::now), kMonospaceSequence, kTagCode);
|
||||
|
||||
if (_editLinkCallback) {
|
||||
|
|
|
@ -151,6 +151,8 @@ public:
|
|||
};
|
||||
static const QString kTagBold;
|
||||
static const QString kTagItalic;
|
||||
static const QString kTagUnderline;
|
||||
static const QString kTagStrikeOut;
|
||||
static const QString kTagCode;
|
||||
static const QString kTagPre;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue