From 8741266819b47b7fa9d133012ade6dc7e27b718a Mon Sep 17 00:00:00 2001 From: John Preston Date: Sun, 23 Jun 2019 15:40:59 +0200 Subject: [PATCH] Add support for Underline and Strike-through text. --- Telegram/Resources/langs/lang.strings | 2 + .../SourceFiles/boxes/confirm_phone_box.cpp | 17 ++-- .../chat_helpers/message_field.cpp | 14 +++- .../SourceFiles/ui/style/style_core_font.cpp | 5 ++ .../SourceFiles/ui/style/style_core_font.h | 4 +- Telegram/SourceFiles/ui/text/text.cpp | 28 ++++++- Telegram/SourceFiles/ui/text/text.h | 10 ++- Telegram/SourceFiles/ui/text/text_block.cpp | 1 + Telegram/SourceFiles/ui/text/text_block.h | 9 +- Telegram/SourceFiles/ui/text/text_entity.cpp | 26 +++++- Telegram/SourceFiles/ui/text/text_entity.h | 4 + .../SourceFiles/ui/widgets/input_fields.cpp | 83 +++++++++++++++---- .../SourceFiles/ui/widgets/input_fields.h | 2 + 13 files changed, 166 insertions(+), 39 deletions(-) diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index e37bce6ff8..b88ee91b46 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -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"; diff --git a/Telegram/SourceFiles/boxes/confirm_phone_box.cpp b/Telegram/SourceFiles/boxes/confirm_phone_box.cpp index d557fd81dc..642910fd9a 100644 --- a/Telegram/SourceFiles/boxes/confirm_phone_box.cpp +++ b/Telegram/SourceFiles/boxes/confirm_phone_box.cpp @@ -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(); }); diff --git a/Telegram/SourceFiles/chat_helpers/message_field.cpp b/Telegram/SourceFiles/chat_helpers/message_field.cpp index af60a8f9e0..c10a4f6fc2 100644 --- a/Telegram/SourceFiles/chat_helpers/message_field.cpp +++ b/Telegram/SourceFiles/chat_helpers/message_field.cpp @@ -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; } } diff --git a/Telegram/SourceFiles/ui/style/style_core_font.cpp b/Telegram/SourceFiles/ui/style/style_core_font.cpp index d268a71e16..060b0abda0 100644 --- a/Telegram/SourceFiles/ui/style/style_core_font.cpp +++ b/Telegram/SourceFiles/ui/style/style_core_font.cpp @@ -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; } diff --git a/Telegram/SourceFiles/ui/style/style_core_font.h b/Telegram/SourceFiles/ui/style/style_core_font.h index 829069434b..566a4fe63b 100644 --- a/Telegram/SourceFiles/ui/style/style_core_font.h +++ b/Telegram/SourceFiles/ui/style/style_core_font.h @@ -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; diff --git a/Telegram/SourceFiles/ui/text/text.cpp b/Telegram/SourceFiles/ui/text/text.cpp index 7ac4bea212..ae0bea6b53 100644 --- a/Telegram/SourceFiles/ui/text/text.cpp +++ b/Telegram/SourceFiles/ui/text/text.cpp @@ -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{ { TextBlockFItalic, EntityType::Italic }, { TextBlockFSemibold, EntityType::Bold }, + { TextBlockFUnderline, EntityType::Underline }, + { TextBlockFStrikeOut, EntityType::StrikeOut }, { TextBlockFCode, EntityType::Code }, // #TODO entities { TextBlockFPre, EntityType::Pre } } : std::vector(); diff --git a/Telegram/SourceFiles/ui/text/text.h b/Telegram/SourceFiles/ui/text/text.h index 7f50bb6d6f..83634bc814 100644 --- a/Telegram/SourceFiles/ui/text/text.h +++ b/Telegram/SourceFiles/ui/text/text.h @@ -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, diff --git a/Telegram/SourceFiles/ui/text/text_block.cpp b/Telegram/SourceFiles/ui/text/text_block.cpp index 9c758a3b5e..9637a2e07b 100644 --- a/Telegram/SourceFiles/ui/text/text_block.cpp +++ b/Telegram/SourceFiles/ui/text/text_block.cpp @@ -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; } diff --git a/Telegram/SourceFiles/ui/text/text_block.h b/Telegram/SourceFiles/ui/text/text_block.h index 853851030b..ea0aa10909 100644 --- a/Telegram/SourceFiles/ui/text/text_block.h +++ b/Telegram/SourceFiles/ui/text/text_block.h @@ -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 { diff --git a/Telegram/SourceFiles/ui/text/text_entity.cpp b/Telegram/SourceFiles/ui/text/text_entity.cpp index 800bafc079..2c2f4e9831 100644 --- a/Telegram/SourceFiles/ui/text/text_entity.cpp +++ b/Telegram/SourceFiles/ui/text/text_entity.cpp @@ -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 &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 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 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; } diff --git a/Telegram/SourceFiles/ui/text/text_entity.h b/Telegram/SourceFiles/ui/text/text_entity.h index a7de22c7ed..d227204a43 100644 --- a/Telegram/SourceFiles/ui/text/text_entity.h +++ b/Telegram/SourceFiles/ui/text/text_entity.h @@ -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(); diff --git a/Telegram/SourceFiles/ui/widgets/input_fields.cpp b/Telegram/SourceFiles/ui/widgets/input_fields.cpp index bfaf520edb..3e6bb1702f 100644 --- a/Telegram/SourceFiles/ui/widgets/input_fields.cpp +++ b/Telegram/SourceFiles/ui/widgets/input_fields.cpp @@ -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::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 &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 &TagIndices() { static auto cached = std::map { { 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) { diff --git a/Telegram/SourceFiles/ui/widgets/input_fields.h b/Telegram/SourceFiles/ui/widgets/input_fields.h index 622d17db7e..850d7fd4e6 100644 --- a/Telegram/SourceFiles/ui/widgets/input_fields.h +++ b/Telegram/SourceFiles/ui/widgets/input_fields.h @@ -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;