message_field.h 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. /*
  2. This file is part of Telegram Desktop,
  3. the official desktop application for the Telegram messaging service.
  4. For license and copyright information please follow this link:
  5. https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
  6. */
  7. #pragma once
  8. #include "base/qt/qt_compare.h"
  9. #include "base/timer.h"
  10. #include "chat_helpers/compose/compose_features.h"
  11. #include "ui/widgets/fields/input_field.h"
  12. #ifndef TDESKTOP_DISABLE_SPELLCHECK
  13. #include "boxes/dictionaries_manager.h"
  14. #include "spellcheck/spelling_highlighter.h"
  15. #endif // TDESKTOP_DISABLE_SPELLCHECK
  16. #include <QtGui/QClipboard>
  17. namespace tr {
  18. struct now_t;
  19. } // namespace tr
  20. namespace Main {
  21. class Session;
  22. class SessionShow;
  23. } // namespace Main
  24. namespace Window {
  25. class SessionController;
  26. } // namespace Window
  27. namespace ChatHelpers {
  28. enum class PauseReason;
  29. class Show;
  30. } // namespace ChatHelpers
  31. namespace Ui {
  32. class PopupMenu;
  33. class Show;
  34. } // namespace Ui
  35. [[nodiscard]] QString PrepareMentionTag(not_null<UserData*> user);
  36. [[nodiscard]] TextWithTags PrepareEditText(not_null<HistoryItem*> item);
  37. [[nodiscard]] bool EditTextChanged(
  38. not_null<HistoryItem*> item,
  39. TextWithTags updated);
  40. Fn<bool(
  41. Ui::InputField::EditLinkSelection selection,
  42. TextWithTags text,
  43. QString link,
  44. Ui::InputField::EditLinkAction action)> DefaultEditLinkCallback(
  45. std::shared_ptr<Main::SessionShow> show,
  46. not_null<Ui::InputField*> field,
  47. const style::InputField *fieldStyle = nullptr);
  48. Fn<void(QString now, Fn<void(QString)> save)> DefaultEditLanguageCallback(
  49. std::shared_ptr<Ui::Show> show);
  50. struct MessageFieldHandlersArgs {
  51. not_null<Main::Session*> session;
  52. std::shared_ptr<Main::SessionShow> show; // may be null
  53. not_null<Ui::InputField*> field;
  54. Fn<bool()> customEmojiPaused;
  55. Fn<bool(not_null<DocumentData*>)> allowPremiumEmoji;
  56. const style::InputField *fieldStyle = nullptr;
  57. base::flat_set<QString> allowMarkdownTags;
  58. };
  59. void InitMessageFieldHandlers(MessageFieldHandlersArgs &&args);
  60. void InitMessageFieldHandlers(
  61. not_null<Window::SessionController*> controller,
  62. not_null<Ui::InputField*> field,
  63. ChatHelpers::PauseReason pauseReasonLevel,
  64. Fn<bool(not_null<DocumentData*>)> allowPremiumEmoji = nullptr);
  65. void InitMessageField(
  66. std::shared_ptr<ChatHelpers::Show> show,
  67. not_null<Ui::InputField*> field,
  68. Fn<bool(not_null<DocumentData*>)> allowPremiumEmoji);
  69. void InitMessageField(
  70. not_null<Window::SessionController*> controller,
  71. not_null<Ui::InputField*> field,
  72. Fn<bool(not_null<DocumentData*>)> allowPremiumEmoji);
  73. void InitSpellchecker(
  74. std::shared_ptr<Main::SessionShow> show,
  75. not_null<Ui::InputField*> field,
  76. bool skipDictionariesManager = false);
  77. [[nodiscard]] Fn<void(not_null<Ui::InputField*>)> FactcheckFieldIniter(
  78. std::shared_ptr<Main::SessionShow> show);
  79. bool HasSendText(not_null<const Ui::InputField*> field);
  80. void InitMessageFieldFade(
  81. not_null<Ui::InputField*> field,
  82. const style::color &bg);
  83. struct InlineBotQuery {
  84. QString query;
  85. QString username;
  86. UserData *bot = nullptr;
  87. bool lookingUpBot = false;
  88. };
  89. InlineBotQuery ParseInlineBotQuery(
  90. not_null<Main::Session*> session,
  91. not_null<const Ui::InputField*> field);
  92. struct AutocompleteQuery {
  93. QString query;
  94. bool fromStart = false;
  95. };
  96. AutocompleteQuery ParseMentionHashtagBotCommandQuery(
  97. not_null<const Ui::InputField*> field,
  98. ChatHelpers::ComposeFeatures features);
  99. struct MessageLinkRange {
  100. int start = 0;
  101. int length = 0;
  102. QString custom;
  103. friend inline auto operator<=>(
  104. const MessageLinkRange&,
  105. const MessageLinkRange&) = default;
  106. friend inline bool operator==(
  107. const MessageLinkRange&,
  108. const MessageLinkRange&) = default;
  109. };
  110. class MessageLinksParser final : private QObject {
  111. public:
  112. MessageLinksParser(not_null<Ui::InputField*> field);
  113. void parseNow();
  114. void setDisabled(bool disabled);
  115. [[nodiscard]] const rpl::variable<QStringList> &list() const {
  116. return _list;
  117. }
  118. [[nodiscard]] const std::vector<MessageLinkRange> &ranges() const {
  119. return _ranges;
  120. }
  121. private:
  122. bool eventFilter(QObject *object, QEvent *event) override;
  123. void parse();
  124. void applyRanges(const QString &text);
  125. not_null<Ui::InputField*> _field;
  126. rpl::variable<QStringList> _list;
  127. std::vector<MessageLinkRange> _ranges;
  128. int _lastLength = 0;
  129. bool _disabled = false;
  130. base::Timer _timer;
  131. rpl::lifetime _lifetime;
  132. };
  133. [[nodiscard]] base::unique_qptr<Ui::RpWidget> CreateDisabledFieldView(
  134. QWidget *parent,
  135. not_null<PeerData*> peer);
  136. [[nodiscard]] base::unique_qptr<Ui::RpWidget> TextErrorSendRestriction(
  137. QWidget *parent,
  138. const QString &text);
  139. [[nodiscard]] base::unique_qptr<Ui::RpWidget> PremiumRequiredSendRestriction(
  140. QWidget *parent,
  141. not_null<UserData*> user,
  142. not_null<Window::SessionController*> controller);
  143. void SelectTextInFieldWithMargins(
  144. not_null<Ui::InputField*> field,
  145. const TextSelection &selection);
  146. [[nodiscard]] TextWithEntities PaidSendButtonText(tr::now_t, int stars);
  147. [[nodiscard]] rpl::producer<TextWithEntities> PaidSendButtonText(
  148. rpl::producer<int> stars,
  149. rpl::producer<QString> fallback = nullptr);