diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index e4c35a957..48bb9e8a7 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -1195,13 +1195,17 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_delete_all_from" = "Delete all from this user"; "lng_report_spam" = "Report Spam"; "lng_report_spam_and_leave" = "Report spam and leave"; +"lng_report_spam_done" = "Thank you for your report."; "lng_report_spam_sure_group" = "Are you sure you want to report spam in this group?"; "lng_report_spam_sure_channel" = "Are you sure you want to report spam in this channel?"; "lng_report_spam_ok" = "Report"; "lng_new_contact_block" = "Block user"; +"lng_new_contact_block_done" = "{user} is now blocked."; "lng_new_contact_add" = "Add contact"; "lng_new_contact_share" = "Share my phone number"; +"lng_new_contact_share_done" = "{user} can now see your phone number."; "lng_new_contact_add_name" = "Add {user} to contacts"; +"lng_new_contact_add_done" = "{user} is now in your contact list."; "lng_cant_send_to_not_contact" = "Sorry, you can only send messages to\nmutual contacts at the moment.\n{more_info}"; "lng_cant_invite_not_contact" = "Sorry, you can only add mutual contacts\nto groups at the moment.\n{more_info}"; "lng_cant_more_info" = "More info ยป"; diff --git a/Telegram/SourceFiles/boxes/add_contact_box.cpp b/Telegram/SourceFiles/boxes/add_contact_box.cpp index 901e09220..22d288c90 100644 --- a/Telegram/SourceFiles/boxes/add_contact_box.cpp +++ b/Telegram/SourceFiles/boxes/add_contact_box.cpp @@ -168,7 +168,7 @@ private: } not_null peer; - Text name, status; + Ui::Text::String name, status; }; void paintChat(Painter &p, const ChatRow &row, bool selected) const; void updateSelected(); diff --git a/Telegram/SourceFiles/boxes/add_contact_box.h b/Telegram/SourceFiles/boxes/add_contact_box.h index 2a96be2a6..10aec92c6 100644 --- a/Telegram/SourceFiles/boxes/add_contact_box.h +++ b/Telegram/SourceFiles/boxes/add_contact_box.h @@ -169,7 +169,7 @@ private: object_ptr> _public; object_ptr> _private; int32 _aboutPublicWidth, _aboutPublicHeight; - Text _aboutPublic, _aboutPrivate; + Ui::Text::String _aboutPublic, _aboutPrivate; object_ptr _link; diff --git a/Telegram/SourceFiles/boxes/confirm_box.h b/Telegram/SourceFiles/boxes/confirm_box.h index d7905fe77..1d9e09e60 100644 --- a/Telegram/SourceFiles/boxes/confirm_box.h +++ b/Telegram/SourceFiles/boxes/confirm_box.h @@ -67,7 +67,7 @@ private: const style::RoundButton &_confirmStyle; bool _informative = false; - Text _text; + Ui::Text::String _text; int _textWidth = 0; int _textHeight = 0; int _maxLineCount = 16; @@ -109,7 +109,7 @@ private: not_null _channel; - Text _text; + Ui::Text::String _text; int32 _textWidth, _textHeight; QRect _invitationLink; diff --git a/Telegram/SourceFiles/boxes/connection_box.cpp b/Telegram/SourceFiles/boxes/connection_box.cpp index 1be879d51..748775660 100644 --- a/Telegram/SourceFiles/boxes/connection_box.cpp +++ b/Telegram/SourceFiles/boxes/connection_box.cpp @@ -59,7 +59,7 @@ private: View _view; - Text _title; + Ui::Text::String _title; object_ptr _menuToggle; rpl::event_stream<> _deleteClicks; rpl::event_stream<> _restoreClicks; diff --git a/Telegram/SourceFiles/boxes/edit_caption_box.h b/Telegram/SourceFiles/boxes/edit_caption_box.h index c44d2b939..efdc463c1 100644 --- a/Telegram/SourceFiles/boxes/edit_caption_box.h +++ b/Telegram/SourceFiles/boxes/edit_caption_box.h @@ -100,7 +100,7 @@ private: int _thumbx = 0; int _thumbw = 0; int _thumbh = 0; - Text _name; + Ui::Text::String _name; QString _status; bool _isAudio = false; bool _isImage = false; diff --git a/Telegram/SourceFiles/boxes/language_box.cpp b/Telegram/SourceFiles/boxes/language_box.cpp index 53df92553..289b99077 100644 --- a/Telegram/SourceFiles/boxes/language_box.cpp +++ b/Telegram/SourceFiles/boxes/language_box.cpp @@ -72,8 +72,8 @@ protected: private: struct Row { Language data; - Text title = { st::boxWideWidth / 2 }; - Text description = { st::boxWideWidth / 2 }; + Ui::Text::String title = { st::boxWideWidth / 2 }; + Ui::Text::String description = { st::boxWideWidth / 2 }; int top = 0; int height = 0; mutable std::unique_ptr ripple; diff --git a/Telegram/SourceFiles/boxes/passcode_box.h b/Telegram/SourceFiles/boxes/passcode_box.h index a36a84c2b..d2b33ea8f 100644 --- a/Telegram/SourceFiles/boxes/passcode_box.h +++ b/Telegram/SourceFiles/boxes/passcode_box.h @@ -124,7 +124,7 @@ private: int _aboutHeight = 0; - Text _about, _hintText; + Ui::Text::String _about, _hintText; object_ptr _oldPasscode; object_ptr _newPasscode; diff --git a/Telegram/SourceFiles/boxes/peer_list_box.h b/Telegram/SourceFiles/boxes/peer_list_box.h index ae12484ea..594aee623 100644 --- a/Telegram/SourceFiles/boxes/peer_list_box.h +++ b/Telegram/SourceFiles/boxes/peer_list_box.h @@ -100,7 +100,7 @@ public: } void refreshName(const style::PeerListItem &st); - const Text &name() const { + const Ui::Text::String &name() const { return _name; } @@ -203,8 +203,8 @@ private: not_null _peer; std::unique_ptr _ripple; std::unique_ptr _checkbox; - Text _name; - Text _status; + Ui::Text::String _name; + Ui::Text::String _status; StatusType _statusType = StatusType::Online; crl::time _statusValidTill = 0; base::flat_set _nameFirstLetters; diff --git a/Telegram/SourceFiles/boxes/peers/add_to_contacts_box.cpp b/Telegram/SourceFiles/boxes/peers/add_to_contacts_box.cpp index b040454ea..31fffd2ce 100644 --- a/Telegram/SourceFiles/boxes/peers/add_to_contacts_box.cpp +++ b/Telegram/SourceFiles/boxes/peers/add_to_contacts_box.cpp @@ -12,9 +12,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/wrap/vertical_layout.h" #include "ui/widgets/labels.h" #include "ui/widgets/input_fields.h" +#include "ui/text/text_utilities.h" #include "info/profile/info_profile_cover.h" #include "lang/lang_keys.h" #include "window/window_controller.h" +#include "ui/toast/toast.h" #include "auth_session.h" #include "apiwrap.h" #include "styles/style_boxes.h" @@ -29,12 +31,6 @@ QString UserPhone(not_null user) { : phone; } -TextWithEntities BoldText(const QString &text) { - auto result = TextWithEntities{ text }; - result.entities.push_back({ EntityType::Bold, 0, text.size() }); - return result; -} - } // namespace AddToContactsBox::AddToContactsBox( @@ -163,6 +159,7 @@ void AddToContactsBox::initNameFields( if (box) { box->closeBox(); } + Ui::Toast::Show(lng_new_contact_add_done(lt_user, firstValue)); }).fail([=](const RPCError &error) { }).send(); }; @@ -170,21 +167,19 @@ void AddToContactsBox::initNameFields( void AddToContactsBox::setupWarning( not_null container) { - const auto name = _user->firstName.isEmpty() - ? _user->lastName - : _user->firstName; + const auto name = _user->shortName(); const auto nameWithEntities = TextWithEntities{ name }; const auto text = _phone.isEmpty() ? lng_contact_phone_after__generic( lt_user, nameWithEntities, lt_visible, - BoldText(lang(lng_contact_phone_visible)), + Ui::Text::Bold(lang(lng_contact_phone_visible)), lt_name, nameWithEntities) : lng_contact_phone_show__generic( lt_button, - BoldText(lang(lng_box_done).toUpper()), + Ui::Text::Bold(lang(lng_box_done).toUpper()), lt_user, TextWithEntities{ name }); container->add( diff --git a/Telegram/SourceFiles/boxes/peers/edit_linked_chat_box.cpp b/Telegram/SourceFiles/boxes/peers/edit_linked_chat_box.cpp index 60a3e0bc3..f7bc4919b 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_linked_chat_box.cpp +++ b/Telegram/SourceFiles/boxes/peers/edit_linked_chat_box.cpp @@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "data/data_chat.h" #include "ui/widgets/labels.h" #include "ui/wrap/vertical_layout.h" +#include "ui/text/text_utilities.h" #include "info/profile/info_profile_button.h" #include "info/profile/info_profile_values.h" #include "boxes/peer_list_box.h" @@ -26,13 +27,6 @@ namespace { constexpr auto kEnableSearchRowsCount = 10; -TextWithEntities BoldText(const QString &text) { - auto result = TextWithEntities{ text }; - result.entities.push_back( - EntityInText(EntityType::Bold, 0, text.size())); - return result; -} - class Controller : public PeerListController, public base::has_weak_ptr { public: Controller( @@ -127,9 +121,9 @@ void Controller::choose(not_null chat) { TextWithEntities >( lt_group, - BoldText(chat->name), + Ui::Text::Bold(chat->name), lt_channel, - BoldText(_channel->name)); + Ui::Text::Bold(_channel->name)); if (!_channel->isPublic()) { text.append( "\n\n" + lang(lng_manage_linked_channel_private)); @@ -140,7 +134,7 @@ void Controller::choose(not_null chat) { text.append("\n\n"); text.append(lng_manage_discussion_group_warning__generic( lt_visible, - BoldText(lang(lng_manage_discussion_group_visible)))); + Ui::Text::Bold(lang(lng_manage_discussion_group_visible)))); } } const auto box = std::make_shared>(); @@ -164,9 +158,9 @@ void Controller::choose(not_null chat) { TextWithEntities >( lt_group, - BoldText(chat->name), + Ui::Text::Bold(chat->name), lt_channel, - BoldText(_channel->name)); + Ui::Text::Bold(_channel->name)); if (!_channel->isPublic()) { text.append( "\n\n" + lang(lng_manage_linked_channel_private)); @@ -175,7 +169,7 @@ void Controller::choose(not_null chat) { text.append("\n\n"); text.append(lng_manage_discussion_group_warning__generic( lt_visible, - BoldText(lang(lng_manage_discussion_group_visible)))); + Ui::Text::Bold(lang(lng_manage_discussion_group_visible)))); const auto box = std::make_shared>(); const auto sure = [=] { if (*box) { @@ -208,11 +202,11 @@ object_ptr SetupAbout( if (!channel->isBroadcast()) { return lng_manage_linked_channel_about__generic< TextWithEntities - >(lt_channel, BoldText(chat->name)); + >(lt_channel, Ui::Text::Bold(chat->name)); } else if (chat != nullptr) { return lng_manage_discussion_group_about_chosen__generic< TextWithEntities - >(lt_group, BoldText(chat->name)); + >(lt_group, Ui::Text::Bold(chat->name)); } else { return { lang(lng_manage_discussion_group_about) }; } diff --git a/Telegram/SourceFiles/boxes/peers/edit_participant_box.cpp b/Telegram/SourceFiles/boxes/peers/edit_participant_box.cpp index f18ef8f01..bb5d8760e 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_participant_box.cpp +++ b/Telegram/SourceFiles/boxes/peers/edit_participant_box.cpp @@ -50,7 +50,7 @@ private: not_null _peer; not_null _user; object_ptr _userPhoto; - Text _userName; + Ui::Text::String _userName; bool _hasAdminRights = false; object_ptr _rows; diff --git a/Telegram/SourceFiles/boxes/send_files_box.cpp b/Telegram/SourceFiles/boxes/send_files_box.cpp index 062255064..62fe0dfb4 100644 --- a/Telegram/SourceFiles/boxes/send_files_box.cpp +++ b/Telegram/SourceFiles/boxes/send_files_box.cpp @@ -101,7 +101,7 @@ private: void prepareThumb(const QImage &preview); QPixmap _fileThumb; - Text _nameText; + Ui::Text::String _nameText; bool _fileIsAudio = false; bool _fileIsImage = false; QString _statusText; diff --git a/Telegram/SourceFiles/boxes/share_box.cpp b/Telegram/SourceFiles/boxes/share_box.cpp index cbd197673..c8ad05818 100644 --- a/Telegram/SourceFiles/boxes/share_box.cpp +++ b/Telegram/SourceFiles/boxes/share_box.cpp @@ -85,7 +85,7 @@ private: PeerData *peer; Ui::RoundImageCheckbox checkbox; - Text name; + Ui::Text::String name; Ui::Animations::Simple nameActive; }; diff --git a/Telegram/SourceFiles/boxes/username_box.h b/Telegram/SourceFiles/boxes/username_box.h index 931913a8f..f76ce0ddb 100644 --- a/Telegram/SourceFiles/boxes/username_box.h +++ b/Telegram/SourceFiles/boxes/username_box.h @@ -49,7 +49,7 @@ private: mtpRequestId _checkRequestId = 0; QString _sentUsername, _checkUsername, _errorText, _goodText; - Text _about; + Ui::Text::String _about; object_ptr _checkTimer; }; diff --git a/Telegram/SourceFiles/chat_helpers/stickers_list_widget.h b/Telegram/SourceFiles/chat_helpers/stickers_list_widget.h index d87f880e6..9051e0d62 100644 --- a/Telegram/SourceFiles/chat_helpers/stickers_list_widget.h +++ b/Telegram/SourceFiles/chat_helpers/stickers_list_widget.h @@ -268,7 +268,7 @@ private: OverState _pressed; QPoint _lastMousePosition; - Text _megagroupSetAbout; + Ui::Text::String _megagroupSetAbout; QString _megagroupSetButtonText; int _megagroupSetButtonTextWidth = 0; QRect _megagroupSetButtonRect; diff --git a/Telegram/SourceFiles/data/data_peer.cpp b/Telegram/SourceFiles/data/data_peer.cpp index be455c3b8..6daba8394 100644 --- a/Telegram/SourceFiles/data/data_peer.cpp +++ b/Telegram/SourceFiles/data/data_peer.cpp @@ -592,7 +592,7 @@ not_null PeerData::migrateToOrMe() const { return this; } -const Text &PeerData::topBarNameText() const { +const Ui::Text::String &PeerData::topBarNameText() const { if (const auto to = migrateTo()) { return to->topBarNameText(); } else if (const auto user = asUser()) { @@ -603,7 +603,7 @@ const Text &PeerData::topBarNameText() const { return _nameText; } -const Text &PeerData::nameText() const { +const Ui::Text::String &PeerData::nameText() const { if (const auto to = migrateTo()) { return to->nameText(); } @@ -611,7 +611,10 @@ const Text &PeerData::nameText() const { } const QString &PeerData::shortName() const { - return isUser() ? asUser()->firstName : name; + if (const auto user = asUser()) { + return user->firstName.isEmpty() ? user->lastName : user->firstName; + } + return name; } QString PeerData::userName() const { diff --git a/Telegram/SourceFiles/data/data_peer.h b/Telegram/SourceFiles/data/data_peer.h index 53a074e6c..65300c1b0 100644 --- a/Telegram/SourceFiles/data/data_peer.h +++ b/Telegram/SourceFiles/data/data_peer.h @@ -204,9 +204,9 @@ public: return (_lastFullUpdate != 0); } - [[nodiscard]] const Text &nameText() const; + [[nodiscard]] const Ui::Text::String &nameText() const; [[nodiscard]] const QString &shortName() const; - [[nodiscard]] const Text &topBarNameText() const; + [[nodiscard]] const Ui::Text::String &topBarNameText() const; [[nodiscard]] QString userName() const; [[nodiscard]] int32 bareId() const { @@ -359,7 +359,7 @@ private: PhotoId _userpicPhotoId = kUnknownPhotoId; mutable std::unique_ptr _userpicEmpty; StorageImageLocation _userpicLocation; - Text _nameText; + Ui::Text::String _nameText; Data::NotifySettings _notify; diff --git a/Telegram/SourceFiles/data/data_user.cpp b/Telegram/SourceFiles/data/data_user.cpp index 65a82b598..94132c474 100644 --- a/Telegram/SourceFiles/data/data_user.cpp +++ b/Telegram/SourceFiles/data/data_user.cpp @@ -33,13 +33,13 @@ BotCommand::BotCommand( bool BotCommand::setDescription(const QString &description) { if (_description != description) { _description = description; - _descriptionText = Text(); + _descriptionText = Ui::Text::String(); return true; } return false; } -const Text &BotCommand::descriptionText() const { +const Ui::Text::String &BotCommand::descriptionText() const { if (_descriptionText.isEmpty() && !_description.isEmpty()) { _descriptionText.setText( st::defaultTextStyle, @@ -158,30 +158,31 @@ void UserData::setBotInfo(const MTPBotInfo &info) { QString desc = qs(d.vdescription); if (botInfo->description != desc) { botInfo->description = desc; - botInfo->text = Text(st::msgMinWidth); + botInfo->text = Ui::Text::String(st::msgMinWidth); } auto &v = d.vcommands.v; botInfo->commands.reserve(v.size()); auto changedCommands = false; int32 j = 0; - for (int32 i = 0, l = v.size(); i < l; ++i) { - if (v.at(i).type() != mtpc_botCommand) continue; - - QString cmd = qs(v.at(i).c_botCommand().vcommand), desc = qs(v.at(i).c_botCommand().vdescription); - if (botInfo->commands.size() <= j) { - botInfo->commands.push_back(BotCommand(cmd, desc)); - changedCommands = true; - } else { - if (botInfo->commands[j].command != cmd) { - botInfo->commands[j].command = cmd; + for (const auto &command : v) { + command.match([&](const MTPDbotCommand &data) { + const auto cmd = qs(data.vcommand); + const auto desc = qs(data.vdescription); + if (botInfo->commands.size() <= j) { + botInfo->commands.push_back(BotCommand(cmd, desc)); changedCommands = true; + } else { + if (botInfo->commands[j].command != cmd) { + botInfo->commands[j].command = cmd; + changedCommands = true; + } + if (botInfo->commands[j].setDescription(desc)) { + changedCommands = true; + } } - if (botInfo->commands[j].setDescription(desc)) { - changedCommands = true; - } - } - ++j; + ++j; + }); } while (j < botInfo->commands.size()) { botInfo->commands.pop_back(); diff --git a/Telegram/SourceFiles/data/data_user.h b/Telegram/SourceFiles/data/data_user.h index 331b2b0eb..12be6cd89 100644 --- a/Telegram/SourceFiles/data/data_user.h +++ b/Telegram/SourceFiles/data/data_user.h @@ -14,13 +14,13 @@ public: BotCommand(const QString &command, const QString &description); bool setDescription(const QString &description); - const Text &descriptionText() const; + const Ui::Text::String &descriptionText() const; QString command; private: QString _description; - mutable Text _descriptionText; + mutable Ui::Text::String _descriptionText; }; @@ -31,7 +31,7 @@ struct BotInfo { int version = 0; QString description, inlinePlaceholder; QList commands; - Text text = Text{ int(st::msgMinWidth) }; // description + Ui::Text::String text = { int(st::msgMinWidth) }; // description QString startToken, startGroupToken, shareGameShortName; PeerId inlineReturnPeerId = 0; @@ -160,7 +160,7 @@ public: return _phone; } QString nameOrPhone; - Text phoneText; + Ui::Text::String phoneText; TimeId onlineTill = 0; enum class ContactStatus : char { diff --git a/Telegram/SourceFiles/dialogs/dialogs_entry.h b/Telegram/SourceFiles/dialogs/dialogs_entry.h index 714d76457..f881b879d 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_entry.h +++ b/Telegram/SourceFiles/dialogs/dialogs_entry.h @@ -169,7 +169,7 @@ public: } mutable const HistoryItem *textCachedFor = nullptr; // cache - mutable Text lastItemTextCache; + mutable Ui::Text::String lastItemTextCache; protected: auto unreadStateChangeNotifier(bool required) { diff --git a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp index 0072d9407..a9e2c1010 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp @@ -802,7 +802,7 @@ void InnerWidget::paintSearchInFilter( PaintUserpic paintUserpic, int top, const style::icon *icon, - const Text &text) const { + const Ui::Text::String &text) const { const auto savedPen = p.pen(); const auto userpicLeft = st::dialogsPadding.x(); const auto userpicTop = top @@ -838,7 +838,7 @@ void InnerWidget::paintSearchInPeer( Painter &p, not_null peer, int top, - const Text &text) const { + const Ui::Text::String &text) const { const auto paintUserpic = [&](Painter &p, int x, int y, int size) { peer->paintUserpicLeft(p, x, y, width(), size); }; @@ -849,7 +849,7 @@ void InnerWidget::paintSearchInPeer( void InnerWidget::paintSearchInSaved( Painter &p, int top, - const Text &text) const { + const Ui::Text::String &text) const { const auto paintUserpic = [&](Painter &p, int x, int y, int size) { Ui::EmptyUserpic::PaintSavedMessages(p, x, y, width(), size); }; @@ -860,7 +860,7 @@ void InnerWidget::paintSearchInSaved( // Painter &p, // not_null feed, // int top, -// const Text &text) const { +// const Ui::Text::String &text) const { // const auto paintUserpic = [&](Painter &p, int x, int y, int size) { // feed->paintUserpicLeft(p, x, y, width(), size); // }; diff --git a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h index e275dcfc5..9ed9ade43 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h +++ b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.h @@ -267,23 +267,23 @@ private: Painter &p, not_null peer, int top, - const Text &text) const; + const Ui::Text::String &text) const; void paintSearchInSaved( Painter &p, int top, - const Text &text) const; + const Ui::Text::String &text) const; //void paintSearchInFeed( // #feed // Painter &p, // not_null feed, // int top, - // const Text &text) const; + // const Ui::Text::String &text) const; template void paintSearchInFilter( Painter &p, PaintUserpic paintUserpic, int top, const style::icon *icon, - const Text &text) const; + const Ui::Text::String &text) const; void refreshSearchInChatLabel(); void clearSearchResults(bool clearPeerSearchResults = true); @@ -376,8 +376,8 @@ private: Key _searchInChat; History *_searchInMigrated = nullptr; UserData *_searchFromUser = nullptr; - Text _searchInChatText; - Text _searchFromUserText; + Ui::Text::String _searchInChatText; + Ui::Text::String _searchFromUserText; RowDescriptor _menuRow; Fn _loadMoreCallback; diff --git a/Telegram/SourceFiles/dialogs/dialogs_row.h b/Telegram/SourceFiles/dialogs/dialogs_row.h index 189211718..e8caf1d63 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_row.h +++ b/Telegram/SourceFiles/dialogs/dialogs_row.h @@ -91,7 +91,7 @@ public: uint64 sortKey() const; void validateListEntryCache() const; - const Text &listEntryCache() const { + const Ui::Text::String &listEntryCache() const { return _listEntryCache; } @@ -104,7 +104,7 @@ private: Key _id; int _pos = 0; mutable uint32 _listEntryCacheVersion = 0; - mutable Text _listEntryCache; + mutable Ui::Text::String _listEntryCache; }; @@ -125,7 +125,7 @@ private: Key _searchInChat; not_null _item; mutable const HistoryItem *_cacheFor = nullptr; - mutable Text _cache; + mutable Ui::Text::String _cache; }; diff --git a/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.cpp b/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.cpp index 4df6c4f04..377f13dea 100644 --- a/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.cpp +++ b/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.cpp @@ -926,7 +926,7 @@ void InnerWidget::mouseDoubleClickEvent(QMouseEvent *e) { mouseActionStart(e->globalPos(), e->button()); if (((_mouseAction == MouseAction::Selecting && _selectedItem != nullptr) || (_mouseAction == MouseAction::None)) && _mouseSelectType == TextSelectType::Letters && _mouseActionItem) { StateRequest request; - request.flags |= Text::StateRequest::Flag::LookupSymbol; + request.flags |= Ui::Text::StateRequest::Flag::LookupSymbol; auto dragState = _mouseActionItem->textState(_dragStartPosition, request); if (dragState.cursor == CursorState::Text) { _mouseTextSymbol = dragState.symbol; @@ -968,7 +968,7 @@ void InnerWidget::showContextMenu(QContextMenuEvent *e, bool showFromTouch) { mapFromGlobal(_mousePosition), App::mousedItem()); StateRequest request; - request.flags |= Text::StateRequest::Flag::LookupSymbol; + request.flags |= Ui::Text::StateRequest::Flag::LookupSymbol; auto dragState = App::mousedItem()->textState(mousePos, request); if (dragState.cursor == CursorState::Text && base::in_range(dragState.symbol, selFrom, selTo)) { @@ -1308,7 +1308,7 @@ void InnerWidget::mouseActionStart(const QPoint &screenPos, Qt::MouseButton butt TextState dragState; if (_trippleClickTimer.isActive() && (screenPos - _trippleClickPoint).manhattanLength() < QApplication::startDragDistance()) { StateRequest request; - request.flags = Text::StateRequest::Flag::LookupSymbol; + request.flags = Ui::Text::StateRequest::Flag::LookupSymbol; dragState = _mouseActionItem->textState(_dragStartPosition, request); if (dragState.cursor == CursorState::Text) { auto selection = TextSelection { dragState.symbol, dragState.symbol }; @@ -1322,7 +1322,7 @@ void InnerWidget::mouseActionStart(const QPoint &screenPos, Qt::MouseButton butt } } else if (App::pressedItem()) { StateRequest request; - request.flags = Text::StateRequest::Flag::LookupSymbol; + request.flags = Ui::Text::StateRequest::Flag::LookupSymbol; dragState = _mouseActionItem->textState(_dragStartPosition, request); } if (_mouseSelectType != TextSelectType::Paragraphs) { @@ -1455,7 +1455,7 @@ void InnerWidget::updateSelected() { } StateRequest request; if (_mouseAction == MouseAction::Selecting) { - request.flags |= Text::StateRequest::Flag::LookupSymbol; + request.flags |= Ui::Text::StateRequest::Flag::LookupSymbol; } else { selectingText = false; } @@ -1563,7 +1563,7 @@ void InnerWidget::performDrag() { // uponSelected = _selected.contains(_mouseActionItem); // } else { // StateRequest request; - // request.flags |= Text::StateRequest::Flag::LookupSymbol; + // request.flags |= Ui::Text::StateRequest::Flag::LookupSymbol; // auto dragState = _mouseActionItem->textState(_dragStartPosition.x(), _dragStartPosition.y(), request); // uponSelected = (dragState.cursor == CursorState::Text); // if (uponSelected) { diff --git a/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.h b/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.h index 2916d9568..e0100add3 100644 --- a/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.h +++ b/Telegram/SourceFiles/history/admin_log/history_admin_log_inner.h @@ -240,7 +240,7 @@ private: bool _upLoaded = true; bool _downLoaded = true; bool _filterChanged = false; - Text _emptyText; + Ui::Text::String _emptyText; MouseAction _mouseAction = MouseAction::None; TextSelectType _mouseSelectType = TextSelectType::Letters; diff --git a/Telegram/SourceFiles/history/history.h b/Telegram/SourceFiles/history/history.h index 0a40f659b..6d3246a5d 100644 --- a/Telegram/SourceFiles/history/history.h +++ b/Telegram/SourceFiles/history/history.h @@ -360,7 +360,7 @@ public: mtpRequestId sendRequestId = 0; - Text cloudDraftTextCache; + Ui::Text::String cloudDraftTextCache; private: friend class HistoryBlock; @@ -516,7 +516,7 @@ private: base::flat_map, crl::time> _typing; base::flat_map, SendAction> _sendActions; QString _sendActionString; - Text _sendActionText; + Ui::Text::String _sendActionText; Ui::SendActionAnimation _sendActionAnimation; base::flat_map _mySendActions; diff --git a/Telegram/SourceFiles/history/history_inner_widget.cpp b/Telegram/SourceFiles/history/history_inner_widget.cpp index 1f2486ff1..483fce13a 100644 --- a/Telegram/SourceFiles/history/history_inner_widget.cpp +++ b/Telegram/SourceFiles/history/history_inner_widget.cpp @@ -1041,7 +1041,7 @@ void HistoryInner::mouseActionStart(const QPoint &screenPos, Qt::MouseButton but TextState dragState; if (_trippleClickTimer.isActive() && (screenPos - _trippleClickPoint).manhattanLength() < QApplication::startDragDistance()) { StateRequest request; - request.flags = Text::StateRequest::Flag::LookupSymbol; + request.flags = Ui::Text::StateRequest::Flag::LookupSymbol; dragState = mouseActionView->textState(_dragStartPosition, request); if (dragState.cursor == CursorState::Text) { TextSelection selStatus = { dragState.symbol, dragState.symbol }; @@ -1060,7 +1060,7 @@ void HistoryInner::mouseActionStart(const QPoint &screenPos, Qt::MouseButton but } } else if (App::pressedItem()) { StateRequest request; - request.flags = Text::StateRequest::Flag::LookupSymbol; + request.flags = Ui::Text::StateRequest::Flag::LookupSymbol; dragState = mouseActionView->textState(_dragStartPosition, request); } if (_mouseSelectType != TextSelectType::Paragraphs) { @@ -1144,7 +1144,7 @@ std::unique_ptr HistoryInner::prepareDrag() { && (_selected.find(_dragStateItem) != _selected.cend()); } else { StateRequest request; - request.flags |= Text::StateRequest::Flag::LookupSymbol; + request.flags |= Ui::Text::StateRequest::Flag::LookupSymbol; auto dragState = mouseActionView->textState(_dragStartPosition, request); uponSelected = (dragState.cursor == CursorState::Text); if (uponSelected) { @@ -1416,7 +1416,7 @@ void HistoryInner::mouseDoubleClickEvent(QMouseEvent *e) { && (_selected.empty() || _selected.cbegin()->second != FullSelection)))) { StateRequest request; - request.flags |= Text::StateRequest::Flag::LookupSymbol; + request.flags |= Ui::Text::StateRequest::Flag::LookupSymbol; auto dragState = mouseActionView->textState(_dragStartPosition, request); if (dragState.cursor == CursorState::Text) { _mouseTextSymbol = dragState.symbol; @@ -1478,7 +1478,7 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) { if (App::mousedItem() && App::mousedItem() == App::hoveredItem()) { auto mousePos = mapPointToItem(mapFromGlobal(_mousePosition), App::mousedItem()); StateRequest request; - request.flags |= Text::StateRequest::Flag::LookupSymbol; + request.flags |= Ui::Text::StateRequest::Flag::LookupSymbol; auto dragState = App::mousedItem()->textState(mousePos, request); if (dragState.cursor == CursorState::Text && dragState.symbol >= selFrom @@ -2556,7 +2556,7 @@ void HistoryInner::mouseActionUpdate() { if (!dragState.link) { StateRequest request; if (_mouseAction == MouseAction::Selecting) { - request.flags |= Text::StateRequest::Flag::LookupSymbol; + request.flags |= Ui::Text::StateRequest::Flag::LookupSymbol; } else { selectingText = false; } @@ -3142,7 +3142,7 @@ QString HistoryInner::tooltipText() const { StateRequest request; const auto local = mapFromGlobal(_mousePosition); const auto point = _widget->clampMousePosition(local); - request.flags |= Text::StateRequest::Flag::LookupCustomTooltip; + request.flags |= Ui::Text::StateRequest::Flag::LookupCustomTooltip; const auto state = view->textState( mapPointToItem(point, view), request); diff --git a/Telegram/SourceFiles/history/history_item.cpp b/Telegram/SourceFiles/history/history_item.cpp index bf9889084..8556d7a4d 100644 --- a/Telegram/SourceFiles/history/history_item.cpp +++ b/Telegram/SourceFiles/history/history_item.cpp @@ -761,7 +761,7 @@ void HistoryItem::drawInDialog( bool selected, DrawInDialog way, const HistoryItem *&cacheFor, - Text &cache) const { + Ui::Text::String &cache) const { if (r.isEmpty()) { return; } diff --git a/Telegram/SourceFiles/history/history_item.h b/Telegram/SourceFiles/history/history_item.h index a807a0e29..9d8f718e8 100644 --- a/Telegram/SourceFiles/history/history_item.h +++ b/Telegram/SourceFiles/history/history_item.h @@ -236,7 +236,7 @@ public: bool selected, DrawInDialog way, const HistoryItem *&cacheFor, - Text &cache) const; + Ui::Text::String &cache) const; bool emptyText() const { return _text.isEmpty(); @@ -334,7 +334,7 @@ protected: void setGroupId(MessageGroupId groupId); - Text _text = { st::msgMinWidth }; + Ui::Text::String _text = { st::msgMinWidth }; int _textWidth = -1; int _textHeight = 0; diff --git a/Telegram/SourceFiles/history/history_item_components.h b/Telegram/SourceFiles/history/history_item_components.h index 1cd5bd9b7..a230b78a5 100644 --- a/Telegram/SourceFiles/history/history_item_components.h +++ b/Telegram/SourceFiles/history/history_item_components.h @@ -41,7 +41,7 @@ struct HistoryMessageSigned : public RuntimeComponent { @@ -49,7 +49,7 @@ struct HistoryMessageEdited : public RuntimeComponent hiddenSenderInfo; QString originalAuthor; MsgId originalId = 0; - mutable Text text = { 1 }; + mutable Ui::Text::String text = { 1 }; PeerData *savedFromPeer = nullptr; MsgId savedFromMsgId = 0; @@ -145,7 +145,7 @@ struct HistoryMessageReply : public RuntimeComponent replyToVia; @@ -329,7 +329,7 @@ private: Button &operator=(Button &&other); ~Button(); - Text text = { 1 }; + Ui::Text::String text = { 1 }; QRect rect; int characters = 0; float64 howMuchOver = 0.; @@ -388,7 +388,7 @@ struct HistoryDocumentThumbed : public RuntimeComponent { HistoryDocumentCaptioned(); - Text _caption; + Ui::Text::String _caption; }; struct HistoryDocumentNamed : public RuntimeComponent { diff --git a/Telegram/SourceFiles/history/history_widget.h b/Telegram/SourceFiles/history/history_widget.h index b13e40204..65b787619 100644 --- a/Telegram/SourceFiles/history/history_widget.h +++ b/Telegram/SourceFiles/history/history_widget.h @@ -486,17 +486,17 @@ private: void handlePeerMigration(); MsgId _replyToId = 0; - Text _replyToName; + Ui::Text::String _replyToName; int _replyToNameVersion = 0; HistoryItemsList _toForward; - Text _toForwardFrom, _toForwardText; + Ui::Text::String _toForwardFrom, _toForwardText; int _toForwardNameVersion = 0; MsgId _editMsgId = 0; HistoryItem *_replyEditMsg = nullptr; - Text _replyEditMsgText; + Ui::Text::String _replyEditMsgText; mutable base::Timer _updateEditTimeLeftDisplay; object_ptr _fieldBarCancel; @@ -509,7 +509,7 @@ private: MsgId msgId = 0; HistoryItem *msg = nullptr; - Text text; + Ui::Text::String text; object_ptr cancel; object_ptr shadow; }; @@ -554,8 +554,8 @@ private: typedef QMap PreviewCache; PreviewCache _previewCache; mtpRequestId _previewRequest = 0; - Text _previewTitle; - Text _previewDescription; + Ui::Text::String _previewTitle; + Ui::Text::String _previewDescription; base::Timer _previewTimer; bool _previewCancelled = false; diff --git a/Telegram/SourceFiles/history/media/history_media.cpp b/Telegram/SourceFiles/history/media/history_media.cpp index dde311297..ae976bdd5 100644 --- a/Telegram/SourceFiles/history/media/history_media.cpp +++ b/Telegram/SourceFiles/history/media/history_media.cpp @@ -37,14 +37,14 @@ QSize HistoryMedia::countCurrentSize(int newWidth) { return QSize(qMin(newWidth, maxWidth()), minHeight()); } -Text HistoryMedia::createCaption(not_null item) const { +Ui::Text::String HistoryMedia::createCaption(not_null item) const { if (item->emptyText()) { - return Text(); + return {}; } const auto minResizeWidth = st::minPhotoSize - st::msgPadding.left() - st::msgPadding.right(); - auto result = Text(minResizeWidth); + auto result = Ui::Text::String(minResizeWidth); result.setMarkedText( st::messageTextStyle, item->originalText(), diff --git a/Telegram/SourceFiles/history/media/history_media.h b/Telegram/SourceFiles/history/media/history_media.h index 2799f711c..4bb718dc9 100644 --- a/Telegram/SourceFiles/history/media/history_media.h +++ b/Telegram/SourceFiles/history/media/history_media.h @@ -236,7 +236,7 @@ protected: using InfoDisplayType = HistoryView::InfoDisplayType; QSize countCurrentSize(int newWidth) override; - Text createCaption(not_null item) const; + Ui::Text::String createCaption(not_null item) const; virtual void playAnimation(bool autoplay) { } diff --git a/Telegram/SourceFiles/history/media/history_media_contact.h b/Telegram/SourceFiles/history/media/history_media_contact.h index 31d9c048a..ea52deef6 100644 --- a/Telegram/SourceFiles/history/media/history_media_contact.h +++ b/Telegram/SourceFiles/history/media/history_media_contact.h @@ -61,7 +61,7 @@ private: int _phonew = 0; QString _fname, _lname, _phone; - Text _name; + Ui::Text::String _name; std::unique_ptr _photoEmpty; ClickHandlerPtr _linkl; diff --git a/Telegram/SourceFiles/history/media/history_media_document.cpp b/Telegram/SourceFiles/history/media/history_media_document.cpp index 8ac464c44..313d10015 100644 --- a/Telegram/SourceFiles/history/media/history_media_document.cpp +++ b/Telegram/SourceFiles/history/media/history_media_document.cpp @@ -825,7 +825,7 @@ void HistoryDocument::refreshParentId(not_null realParent) { void HistoryDocument::parentTextUpdated() { auto caption = (_parent->media() == this) ? createCaption(_parent->data()) - : Text(); + : Ui::Text::String(); if (!caption.isEmpty()) { AddComponents(HistoryDocumentCaptioned::Bit()); auto captioned = Get(); diff --git a/Telegram/SourceFiles/history/media/history_media_game.cpp b/Telegram/SourceFiles/history/media/history_media_game.cpp index 71afca95d..19a1554cb 100644 --- a/Telegram/SourceFiles/history/media/history_media_game.cpp +++ b/Telegram/SourceFiles/history/media/history_media_game.cpp @@ -290,7 +290,7 @@ TextState HistoryGame::textState(QPoint point, StateRequest request) const { auto lineHeight = unitedLineHeight(); if (_titleLines) { if (point.y() >= tshift && point.y() < tshift + _titleLines * lineHeight) { - Text::StateRequestElided titleRequest = request.forText(); + Ui::Text::StateRequestElided titleRequest = request.forText(); titleRequest.lines = _titleLines; result = TextState(_parent, _title.getStateElidedLeft( point - QPoint(padding.left(), tshift), @@ -304,7 +304,7 @@ TextState HistoryGame::textState(QPoint point, StateRequest request) const { } if (_descriptionLines) { if (point.y() >= tshift && point.y() < tshift + _descriptionLines * lineHeight) { - Text::StateRequestElided descriptionRequest = request.forText(); + Ui::Text::StateRequestElided descriptionRequest = request.forText(); descriptionRequest.lines = _descriptionLines; result = TextState(_parent, _description.getStateElidedLeft( point - QPoint(padding.left(), tshift), @@ -420,7 +420,7 @@ void HistoryGame::parentTextUpdated() { consumed, Ui::ItemTextOptions(_parent->data())); } else { - _description = Text(st::msgMinWidth - st::webPageLeft); + _description = Ui::Text::String(st::msgMinWidth - st::webPageLeft); } history()->owner().requestViewResize(_parent); } diff --git a/Telegram/SourceFiles/history/media/history_media_game.h b/Telegram/SourceFiles/history/media/history_media_game.h index 739f3ab34..708f1e543 100644 --- a/Telegram/SourceFiles/history/media/history_media_game.h +++ b/Telegram/SourceFiles/history/media/history_media_game.h @@ -93,7 +93,7 @@ private: int _titleLines, _descriptionLines; - Text _title, _description; + Ui::Text::String _title, _description; int _gameTagWidth = 0; diff --git a/Telegram/SourceFiles/history/media/history_media_gif.cpp b/Telegram/SourceFiles/history/media/history_media_gif.cpp index 82ee576bb..5115f43c1 100644 --- a/Telegram/SourceFiles/history/media/history_media_gif.cpp +++ b/Telegram/SourceFiles/history/media/history_media_gif.cpp @@ -63,7 +63,7 @@ HistoryGif::HistoryGif( QSize HistoryGif::countOptimalSize() { if (_parent->media() != this) { - _caption = Text(); + _caption = Ui::Text::String(); } else if (_caption.hasSkipBlock()) { _caption.updateSkipBlock( _parent->skipBlockWidth(), @@ -596,7 +596,7 @@ TextState HistoryGif::textState(QPoint point, StateRequest request) const { auto breakEverywhere = (forwardedHeightReal > forwardedHeight); auto textRequest = request.forText(); if (breakEverywhere) { - textRequest.flags |= Text::StateRequest::Flag::BreakEverywhere; + textRequest.flags |= Ui::Text::StateRequest::Flag::BreakEverywhere; } result = TextState(_parent, forwarded->text.getState( point - QPoint(rectx + st::msgReplyPadding.left(), recty + st::msgReplyPadding.top()), @@ -785,7 +785,7 @@ bool HistoryGif::isReadyForOpen() const { void HistoryGif::parentTextUpdated() { _caption = (_parent->media() == this) ? createCaption(_parent->data()) - : Text(); + : Ui::Text::String(); history()->owner().requestViewResize(_parent); } diff --git a/Telegram/SourceFiles/history/media/history_media_gif.h b/Telegram/SourceFiles/history/media/history_media_gif.h index 0d99e8ff2..a37690f27 100644 --- a/Telegram/SourceFiles/history/media/history_media_gif.h +++ b/Telegram/SourceFiles/history/media/history_media_gif.h @@ -106,7 +106,7 @@ private: not_null _data; int _thumbw = 1; int _thumbh = 1; - Text _caption; + Ui::Text::String _caption; Media::Clip::ReaderPointer _gif; void setStatusSize(int newSize) const; diff --git a/Telegram/SourceFiles/history/media/history_media_grouped.h b/Telegram/SourceFiles/history/media/history_media_grouped.h index 3e172487a..b23a13cd5 100644 --- a/Telegram/SourceFiles/history/media/history_media_grouped.h +++ b/Telegram/SourceFiles/history/media/history_media_grouped.h @@ -119,7 +119,7 @@ private: QPoint point, StateRequest request) const; - Text _caption; + Ui::Text::String _caption; std::vector _parts; bool _needBubble = false; diff --git a/Telegram/SourceFiles/history/media/history_media_invoice.cpp b/Telegram/SourceFiles/history/media/history_media_invoice.cpp index 01b196a13..b3a164952 100644 --- a/Telegram/SourceFiles/history/media/history_media_invoice.cpp +++ b/Telegram/SourceFiles/history/media/history_media_invoice.cpp @@ -296,7 +296,7 @@ TextState HistoryInvoice::textState(QPoint point, StateRequest request) const { auto symbolAdd = 0; if (_titleHeight) { if (point.y() >= tshift && point.y() < tshift + _titleHeight) { - Text::StateRequestElided titleRequest = request.forText(); + Ui::Text::StateRequestElided titleRequest = request.forText(); titleRequest.lines = _titleHeight / lineHeight; result = TextState(_parent, _title.getStateElidedLeft( point - QPoint(padding.left(), tshift), diff --git a/Telegram/SourceFiles/history/media/history_media_invoice.h b/Telegram/SourceFiles/history/media/history_media_invoice.h index f6601ef95..e6b6c34cc 100644 --- a/Telegram/SourceFiles/history/media/history_media_invoice.h +++ b/Telegram/SourceFiles/history/media/history_media_invoice.h @@ -83,9 +83,9 @@ private: int _titleHeight = 0; int _descriptionHeight = 0; - Text _title; - Text _description; - Text _status; + Ui::Text::String _title; + Ui::Text::String _description; + Ui::Text::String _status; MsgId _receiptMsgId = 0; diff --git a/Telegram/SourceFiles/history/media/history_media_location.h b/Telegram/SourceFiles/history/media/history_media_location.h index 20893bcbf..d815e99dc 100644 --- a/Telegram/SourceFiles/history/media/history_media_location.h +++ b/Telegram/SourceFiles/history/media/history_media_location.h @@ -59,7 +59,7 @@ private: TextSelection fromDescriptionSelection(TextSelection selection) const; LocationData *_data; - Text _title, _description; + Ui::Text::String _title, _description; ClickHandlerPtr _link; int fullWidth() const; diff --git a/Telegram/SourceFiles/history/media/history_media_photo.cpp b/Telegram/SourceFiles/history/media/history_media_photo.cpp index da03e345b..aece4700f 100644 --- a/Telegram/SourceFiles/history/media/history_media_photo.cpp +++ b/Telegram/SourceFiles/history/media/history_media_photo.cpp @@ -63,7 +63,7 @@ void HistoryPhoto::create(FullMsgId contextId, PeerData *chat) { QSize HistoryPhoto::countOptimalSize() { if (_parent->media() != this) { - _caption = Text(); + _caption = Ui::Text::String(); } else if (_caption.hasSkipBlock()) { _caption.updateSkipBlock( _parent->skipBlockWidth(), @@ -560,6 +560,6 @@ bool HistoryPhoto::isReadyForOpen() const { void HistoryPhoto::parentTextUpdated() { _caption = (_parent->media() == this) ? createCaption(_parent->data()) - : Text(); + : Ui::Text::String(); history()->owner().requestViewResize(_parent); } diff --git a/Telegram/SourceFiles/history/media/history_media_photo.h b/Telegram/SourceFiles/history/media/history_media_photo.h index 01ad075f7..9e022180c 100644 --- a/Telegram/SourceFiles/history/media/history_media_photo.h +++ b/Telegram/SourceFiles/history/media/history_media_photo.h @@ -93,6 +93,6 @@ private: int _serviceWidth = 0; int _pixw = 1; int _pixh = 1; - Text _caption; + Ui::Text::String _caption; }; diff --git a/Telegram/SourceFiles/history/media/history_media_poll.cpp b/Telegram/SourceFiles/history/media/history_media_poll.cpp index 6c7ecd8d6..4d7f8cc5b 100644 --- a/Telegram/SourceFiles/history/media/history_media_poll.cpp +++ b/Telegram/SourceFiles/history/media/history_media_poll.cpp @@ -131,7 +131,7 @@ struct HistoryPoll::Answer { void fillText(const PollAnswer &original); - Text text; + Ui::Text::String text; QByteArray option; int votes = 0; int votesPercent = 0; @@ -807,7 +807,7 @@ TextState HistoryPoll::textState(QPoint point, StateRequest request) const { result.link = answer.handler; } else { result.customTooltip = true; - using Flag = Text::StateRequest::Flag; + using Flag = Ui::Text::StateRequest::Flag; if (request.flags & Flag::LookupCustomTooltip) { result.customTooltipText = answer.votes ? lng_polls_votes_count(lt_count_decimal, answer.votes) diff --git a/Telegram/SourceFiles/history/media/history_media_poll.h b/Telegram/SourceFiles/history/media/history_media_poll.h index 0ec11ce27..4f0aecfd9 100644 --- a/Telegram/SourceFiles/history/media/history_media_poll.h +++ b/Telegram/SourceFiles/history/media/history_media_poll.h @@ -118,10 +118,10 @@ private: bool _voted = false; bool _closed = false; - Text _question; - Text _subtitle; + Ui::Text::String _question; + Ui::Text::String _subtitle; std::vector _answers; - Text _totalVotesLabel; + Ui::Text::String _totalVotesLabel; mutable std::unique_ptr _answersAnimation; mutable std::unique_ptr _sendingAnimation; diff --git a/Telegram/SourceFiles/history/media/history_media_video.cpp b/Telegram/SourceFiles/history/media/history_media_video.cpp index a77791c0a..f6323a124 100644 --- a/Telegram/SourceFiles/history/media/history_media_video.cpp +++ b/Telegram/SourceFiles/history/media/history_media_video.cpp @@ -88,7 +88,7 @@ QSize HistoryVideo::countOptimalDimensions() const { QSize HistoryVideo::countOptimalSize() { if (_parent->media() != this) { - _caption = Text(); + _caption = Ui::Text::String(); } else if (_caption.hasSkipBlock()) { _caption.updateSkipBlock( _parent->skipBlockWidth(), @@ -598,7 +598,7 @@ bool HistoryVideo::needsBubble() const { void HistoryVideo::parentTextUpdated() { _caption = (_parent->media() == this) ? createCaption(_parent->data()) - : Text(); + : Ui::Text::String(); history()->owner().requestViewResize(_parent); } diff --git a/Telegram/SourceFiles/history/media/history_media_video.h b/Telegram/SourceFiles/history/media/history_media_video.h index 100371029..f1c77aa02 100644 --- a/Telegram/SourceFiles/history/media/history_media_video.h +++ b/Telegram/SourceFiles/history/media/history_media_video.h @@ -95,7 +95,7 @@ private: not_null _data; int _thumbw = 1; int _thumbh = 1; - Text _caption; + Ui::Text::String _caption; QString _downloadSize; diff --git a/Telegram/SourceFiles/history/media/history_media_web_page.cpp b/Telegram/SourceFiles/history/media/history_media_web_page.cpp index af4114838..ceed5bb7e 100644 --- a/Telegram/SourceFiles/history/media/history_media_web_page.cpp +++ b/Telegram/SourceFiles/history/media/history_media_web_page.cpp @@ -93,8 +93,8 @@ QSize HistoryWebPage::countOptimalSize() { _openl = nullptr; _attach = nullptr; _collage = PrepareCollageMedia(_parent->data(), _data->collage); - _title = Text(st::msgMinWidth - st::webPageLeft); - _description = Text(st::msgMinWidth - st::webPageLeft); + _title = Ui::Text::String(st::msgMinWidth - st::webPageLeft); + _description = Ui::Text::String(st::msgMinWidth - st::webPageLeft); _siteNameWidth = 0; } auto lineHeight = unitedLineHeight(); @@ -191,7 +191,7 @@ QSize HistoryWebPage::countOptimalSize() { } if (isLogEntryOriginal()) { // Fix layout for small bubbles (narrow media caption edit log entries). - _description = Text(st::minPhotoSize + _description = Ui::Text::String(st::minPhotoSize - st::msgPadding.left() - st::msgPadding.right() - st::webPageLeft); @@ -561,7 +561,7 @@ TextState HistoryWebPage::textState(QPoint point, StateRequest request) const { } if (_titleLines) { if (point.y() >= tshift && point.y() < tshift + _titleLines * lineHeight) { - Text::StateRequestElided titleRequest = request.forText(); + Ui::Text::StateRequestElided titleRequest = request.forText(); titleRequest.lines = _titleLines; result = TextState(_parent, _title.getStateElidedLeft( point - QPoint(padding.left(), tshift), @@ -577,7 +577,7 @@ TextState HistoryWebPage::textState(QPoint point, StateRequest request) const { auto descriptionHeight = (_descriptionLines > 0) ? _descriptionLines * lineHeight : _description.countHeight(paintw); if (point.y() >= tshift && point.y() < tshift + descriptionHeight) { if (_descriptionLines > 0) { - Text::StateRequestElided descriptionRequest = request.forText(); + Ui::Text::StateRequestElided descriptionRequest = request.forText(); descriptionRequest.lines = _descriptionLines; result = TextState(_parent, _description.getStateElidedLeft( point - QPoint(padding.left(), tshift), diff --git a/Telegram/SourceFiles/history/media/history_media_web_page.h b/Telegram/SourceFiles/history/media/history_media_web_page.h index b16b35703..b5d9b5e8d 100644 --- a/Telegram/SourceFiles/history/media/history_media_web_page.h +++ b/Telegram/SourceFiles/history/media/history_media_web_page.h @@ -107,7 +107,7 @@ private: int _titleLines = 0; int _descriptionLines = 0; - Text _title, _description; + Ui::Text::String _title, _description; int _siteNameWidth = 0; QString _duration; diff --git a/Telegram/SourceFiles/history/view/history_view_contact_status.cpp b/Telegram/SourceFiles/history/view/history_view_contact_status.cpp index 2c040d9c4..c3dfc2d6c 100644 --- a/Telegram/SourceFiles/history/view/history_view_contact_status.cpp +++ b/Telegram/SourceFiles/history/view/history_view_contact_status.cpp @@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/widgets/buttons.h" #include "ui/widgets/checkbox.h" #include "ui/widgets/labels.h" +#include "ui/toast/toast.h" #include "data/data_peer.h" #include "data/data_user.h" #include "data/data_chat.h" @@ -28,13 +29,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL namespace HistoryView { namespace { -QString PeerFirstName(not_null peer) { - if (const auto user = peer->asUser()) { - return user->firstName; - } - return QString(); -} - bool BarCurrentlyHidden(not_null peer) { const auto settings = peer->settings(); if (!settings) { @@ -60,82 +54,6 @@ auto MapToEmpty() { return rpl::map([] { return rpl::empty_value(); }); } -TextWithEntities BoldText(const QString &text) { - auto result = TextWithEntities{ text }; - result.entities.push_back({ EntityType::Bold, 0, text.size() }); - return result; -} - -void BlockUserBox( - not_null box, - not_null user, - not_null window) { - using Flag = MTPDpeerSettings::Flag; - const auto settings = user->settings().value_or(Flag(0)); - - const auto name = user->firstName.isEmpty() - ? user->lastName - : user->firstName; - - box->addRow(object_ptr( - box, - rpl::single( - lng_blocked_list_confirm_text__generic( - lt_name, - BoldText(name))), - st::blockUserConfirmation)); - - box->addSkip(st::boxMediumSkip); - - const auto report = (settings & Flag::f_report_spam) - ? box->addRow(object_ptr( - box, - lang(lng_report_spam), - true, - st::defaultBoxCheckbox)) - : nullptr; - - if (report) { - box->addSkip(st::boxMediumSkip); - } - - const auto clear = box->addRow(object_ptr( - box, - lang(lng_blocked_list_confirm_clear), - true, - st::defaultBoxCheckbox)); - - box->addSkip(st::boxLittleSkip); - - box->setTitle([=] { - return lng_blocked_list_confirm_title(lt_name, name); - }); - - box->addButton(langFactory(lng_blocked_list_confirm_ok), [=] { - const auto reportChecked = report && report->checked(); - const auto clearChecked = clear->checked(); - - box->closeBox(); - - user->session().api().blockUser(user); - if (reportChecked) { - user->session().api().request(MTPmessages_ReportSpam( - user->input - )).send(); - } - if (clearChecked) { - crl::on_main(&user->session(), [=] { - user->session().api().deleteConversation(user, false); - }); - window->sessionController()->showBackFromStack(); - } - }, st::attentionBoxButton); - - box->addButton(langFactory(lng_cancel), [=] { - box->closeBox(); - }); -} - } // namespace ContactStatus::Bar::Bar(QWidget *parent, const QString &name) @@ -265,7 +183,7 @@ ContactStatus::ContactStatus( not_null parent, not_null peer) : _window(window) -, _bar(parent, object_ptr(parent, PeerFirstName(peer))) +, _bar(parent, object_ptr(parent, peer->shortName())) , _shadow(parent) { setupWidgets(parent); setupState(peer); @@ -382,7 +300,7 @@ void ContactStatus::setupAddHandler(not_null user) { void ContactStatus::setupBlockHandler(not_null user) { _bar.entity()->blockClicks( ) | rpl::start_with_next([=] { - _window->show(Box(BlockUserBox, user, _window)); + _window->show(Box(Window::PeerMenuBlockUserBox, user, _window)); }, _bar.lifetime()); } @@ -394,6 +312,9 @@ void ContactStatus::setupShareHandler(not_null user) { user->inputUser )).done([=](const MTPUpdates &result) { user->session().api().applyUpdates(result); + + Ui::Toast::Show( + lng_new_contact_share_done(lt_user, user->shortName())); }).send(); }, _bar.lifetime()); } @@ -420,6 +341,8 @@ void ContactStatus::setupReportHandler(not_null peer) { peer->session().api().deleteConversation(peer, false); }); + Ui::Toast::Show(lang(lng_report_spam_done)); + // Destroys _bar. _window->sessionController()->showBackFromStack(); }); diff --git a/Telegram/SourceFiles/history/view/history_view_cursor_state.cpp b/Telegram/SourceFiles/history/view/history_view_cursor_state.cpp index 4579aae06..afbd264d8 100644 --- a/Telegram/SourceFiles/history/view/history_view_cursor_state.cpp +++ b/Telegram/SourceFiles/history/view/history_view_cursor_state.cpp @@ -18,7 +18,7 @@ TextState::TextState(not_null item) TextState::TextState( not_null item, - const Text::StateResult &state) + const Ui::Text::StateResult &state) : itemId(item->fullId()) , cursor(state.uponSymbol ? CursorState::Text @@ -42,7 +42,7 @@ TextState::TextState( TextState::TextState( not_null view, - const Text::StateResult &state) + const Ui::Text::StateResult &state) : TextState(view->data(), state) { } @@ -54,7 +54,7 @@ TextState::TextState( TextState::TextState( std::nullptr_t, - const Text::StateResult &state) + const Ui::Text::StateResult &state) : cursor(state.uponSymbol ? CursorState::Text : CursorState::None) diff --git a/Telegram/SourceFiles/history/view/history_view_cursor_state.h b/Telegram/SourceFiles/history/view/history_view_cursor_state.h index f2c4174a6..d9ae01889 100644 --- a/Telegram/SourceFiles/history/view/history_view_cursor_state.h +++ b/Telegram/SourceFiles/history/view/history_view_cursor_state.h @@ -30,20 +30,20 @@ struct TextState { TextState(not_null item); TextState( not_null item, - const Text::StateResult &state); + const Ui::Text::StateResult &state); TextState( not_null item, ClickHandlerPtr link); TextState(not_null view); TextState( not_null view, - const Text::StateResult &state); + const Ui::Text::StateResult &state); TextState( not_null view, ClickHandlerPtr link); TextState( std::nullptr_t, - const Text::StateResult &state); + const Ui::Text::StateResult &state); TextState(std::nullptr_t, ClickHandlerPtr link); FullMsgId itemId; @@ -57,9 +57,9 @@ struct TextState { }; struct StateRequest { - Text::StateRequest::Flags flags = Text::StateRequest::Flag::LookupLink; - Text::StateRequest forText() const { - Text::StateRequest result; + Ui::Text::StateRequest::Flags flags = Ui::Text::StateRequest::Flag::LookupLink; + Ui::Text::StateRequest forText() const { + Ui::Text::StateRequest result; result.flags = flags; return result; } diff --git a/Telegram/SourceFiles/history/view/history_view_element.cpp b/Telegram/SourceFiles/history/view/history_view_element.cpp index 5193a590c..5b77f1bb9 100644 --- a/Telegram/SourceFiles/history/view/history_view_element.cpp +++ b/Telegram/SourceFiles/history/view/history_view_element.cpp @@ -102,13 +102,13 @@ TextSelection ShiftItemSelection( TextSelection UnshiftItemSelection( TextSelection selection, - const Text &byText) { + const Ui::Text::String &byText) { return UnshiftItemSelection(selection, byText.length()); } TextSelection ShiftItemSelection( TextSelection selection, - const Text &byText) { + const Ui::Text::String &byText) { return ShiftItemSelection(selection, byText.length()); } diff --git a/Telegram/SourceFiles/history/view/history_view_element.h b/Telegram/SourceFiles/history/view/history_view_element.h index d942bd8fc..35df7385b 100644 --- a/Telegram/SourceFiles/history/view/history_view_element.h +++ b/Telegram/SourceFiles/history/view/history_view_element.h @@ -79,10 +79,10 @@ TextSelection ShiftItemSelection( uint16 byLength); TextSelection UnshiftItemSelection( TextSelection selection, - const Text &byText); + const Ui::Text::String &byText); TextSelection ShiftItemSelection( TextSelection selection, - const Text &byText); + const Ui::Text::String &byText); // Any HistoryView::Element can have this Component for // displaying the unread messages bar above the message. diff --git a/Telegram/SourceFiles/history/view/history_view_list_widget.cpp b/Telegram/SourceFiles/history/view/history_view_list_widget.cpp index b10a7c443..09d6fbd5a 100644 --- a/Telegram/SourceFiles/history/view/history_view_list_widget.cpp +++ b/Telegram/SourceFiles/history/view/history_view_list_widget.cpp @@ -857,7 +857,7 @@ bool ListWidget::isInsideSelection( && _selectedTextItem == view->data() && state.pointState != PointState::Outside) { StateRequest stateRequest; - stateRequest.flags |= Text::StateRequest::Flag::LookupSymbol; + stateRequest.flags |= Ui::Text::StateRequest::Flag::LookupSymbol; const auto dragState = view->textState( state.point, stateRequest); @@ -1569,7 +1569,7 @@ void ListWidget::switchToWordSelection() { Expects(_overElement != nullptr); StateRequest request; - request.flags |= Text::StateRequest::Flag::LookupSymbol; + request.flags |= Ui::Text::StateRequest::Flag::LookupSymbol; auto dragState = _overElement->textState(_pressState.point, request); if (dragState.cursor != CursorState::Text) { return; @@ -1900,7 +1900,7 @@ void ListWidget::mouseActionStart( auto validStartPoint = startDistance < QApplication::startDragDistance(); if (_trippleClickStartTime != 0 && validStartPoint) { StateRequest request; - request.flags = Text::StateRequest::Flag::LookupSymbol; + request.flags = Ui::Text::StateRequest::Flag::LookupSymbol; dragState = pressElement->textState(_pressState.point, request); if (dragState.cursor == CursorState::Text) { setTextSelection(pressElement, TextSelection( @@ -1915,7 +1915,7 @@ void ListWidget::mouseActionStart( } } else if (pressElement) { StateRequest request; - request.flags = Text::StateRequest::Flag::LookupSymbol; + request.flags = Ui::Text::StateRequest::Flag::LookupSymbol; dragState = pressElement->textState(_pressState.point, request); } if (_mouseSelectType != TextSelectType::Paragraphs) { @@ -2096,7 +2096,7 @@ void ListWidget::mouseActionUpdate() { } StateRequest request; if (_mouseAction == MouseAction::Selecting) { - request.flags |= Text::StateRequest::Flag::LookupSymbol; + request.flags |= Ui::Text::StateRequest::Flag::LookupSymbol; } else { inTextSelection = false; } diff --git a/Telegram/SourceFiles/history/view/history_view_message.cpp b/Telegram/SourceFiles/history/view/history_view_message.cpp index 0d02502ae..4d1b39371 100644 --- a/Telegram/SourceFiles/history/view/history_view_message.cpp +++ b/Telegram/SourceFiles/history/view/history_view_message.cpp @@ -544,7 +544,7 @@ void Message::paintFromName( } p.setFont(st::msgNameFont); - const auto nameText = [&]() -> const Text* { + const auto nameText = [&]() -> const Ui::Text::String * { const auto from = item->displayFrom(); if (item->isPost()) { p.setPen(selected ? st::msgInServiceFgSelected : st::msgInServiceFg); @@ -886,7 +886,7 @@ bool Message::getStateFromName( availableWidth -= st::msgPadding.right() + replyWidth; } const auto from = item->displayFrom(); - const auto nameText = [&]() -> const Text* { + const auto nameText = [&]() -> const Ui::Text::String * { if (from) { return &from->nameText(); } else if (const auto info = item->hiddenForwardedInfo()) { @@ -932,7 +932,7 @@ bool Message::getStateForwardedInfo( auto breakEverywhere = (forwarded->text.countHeight(trect.width()) > 2 * st::semiboldFont->height); auto textRequest = request.forText(); if (breakEverywhere) { - textRequest.flags |= Text::StateRequest::Flag::BreakEverywhere; + textRequest.flags |= Ui::Text::StateRequest::Flag::BreakEverywhere; } *outResult = TextState(item, forwarded->text.getState( point - trect.topLeft(), @@ -1561,7 +1561,7 @@ void Message::fromNameUpdated(int width) const { item->_fromNameVersion = from ? from->nameVersion : 1; if (const auto via = item->Get()) { if (!displayForwardedFrom()) { - const auto nameText = [&]() -> const Text* { + const auto nameText = [&]() -> const Ui::Text::String * { if (from) { return &from->nameText(); } else if (const auto info = item->hiddenForwardedInfo()) { diff --git a/Telegram/SourceFiles/history/view/history_view_service_message.cpp b/Telegram/SourceFiles/history/view/history_view_service_message.cpp index d9c0e4773..dadfa2da6 100644 --- a/Telegram/SourceFiles/history/view/history_view_service_message.cpp +++ b/Telegram/SourceFiles/history/view/history_view_service_message.cpp @@ -207,7 +207,7 @@ void ServiceMessagePainter::paintBubble(Painter &p, int x, int y, int w, int h) paintBubblePart(p, x, y, w, h, SideStyle::Rounded, SideStyle::Rounded); } -void ServiceMessagePainter::paintComplexBubble(Painter &p, int left, int width, const Text &text, const QRect &textRect) { +void ServiceMessagePainter::paintComplexBubble(Painter &p, int left, int width, const Ui::Text::String &text, const QRect &textRect) { createCircleMasks(); auto lineWidths = countLineWidths(text, textRect); @@ -259,7 +259,7 @@ void ServiceMessagePainter::paintComplexBubble(Painter &p, int left, int width, } } -QVector ServiceMessagePainter::countLineWidths(const Text &text, const QRect &textRect) { +QVector ServiceMessagePainter::countLineWidths(const Ui::Text::String &text, const QRect &textRect) { int linesCount = qMax(textRect.height() / st::msgServiceFont->height, 1); QVector lineWidths; lineWidths.reserve(linesCount); @@ -553,7 +553,7 @@ void EmptyPainter::fillAboutGroup() { lang(lng_group_about3), lang(lng_group_about4), }; - const auto setText = [](Text &text, const QString &content) { + const auto setText = [](Ui::Text::String &text, const QString &content) { text.setText( st::serviceTextStyle, content, @@ -575,7 +575,7 @@ void EmptyPainter::paint(Painter &p, int width, int height) { const auto maxPhraseWidth = ranges::max_element( _phrases, ranges::less(), - &Text::maxWidth + &Ui::Text::String::maxWidth )->maxWidth(); const auto &font = st::serviceTextStyle.font; @@ -589,7 +589,7 @@ void EmptyPainter::paint(Painter &p, int width, int height) { _header.maxWidth(), _text.maxWidth() }) + padding.left() + padding.right()); const auto innerWidth = bubbleWidth - padding.left() - padding.right(); - const auto textHeight = [&](const Text &text) { + const auto textHeight = [&](const Ui::Text::String &text) { return std::min( text.countHeight(innerWidth), kMaxTextLines * font->height); diff --git a/Telegram/SourceFiles/history/view/history_view_service_message.h b/Telegram/SourceFiles/history/view/history_view_service_message.h index ff0da884e..acb2b2f2c 100644 --- a/Telegram/SourceFiles/history/view/history_view_service_message.h +++ b/Telegram/SourceFiles/history/view/history_view_service_message.h @@ -67,10 +67,10 @@ public: static void paintBubble(Painter &p, int x, int y, int w, int h); - static void paintComplexBubble(Painter &p, int left, int width, const Text &text, const QRect &textRect); + static void paintComplexBubble(Painter &p, int left, int width, const Ui::Text::String &text, const QRect &textRect); private: - static QVector countLineWidths(const Text &text, const QRect &textRect); + static QVector countLineWidths(const Ui::Text::String &text, const QRect &textRect); }; @@ -84,9 +84,9 @@ private: void fillAboutGroup(); not_null _history; - Text _header = { st::msgMinWidth }; - Text _text = { st::msgMinWidth }; - std::vector _phrases; + Ui::Text::String _header = { st::msgMinWidth }; + Ui::Text::String _text = { st::msgMinWidth }; + std::vector _phrases; }; diff --git a/Telegram/SourceFiles/history/view/history_view_top_bar_widget.h b/Telegram/SourceFiles/history/view/history_view_top_bar_widget.h index f53fcffa0..2b5e5c9e1 100644 --- a/Telegram/SourceFiles/history/view/history_view_top_bar_widget.h +++ b/Telegram/SourceFiles/history/view/history_view_top_bar_widget.h @@ -132,7 +132,7 @@ private: object_ptr _membersShowArea = { nullptr }; rpl::event_stream _membersShowAreaActive; - Text _titlePeerText; + Ui::Text::String _titlePeerText; bool _titlePeerTextOnline = false; int _leftTaken = 0; int _rightTaken = 0; diff --git a/Telegram/SourceFiles/info/media/info_media_list_widget.cpp b/Telegram/SourceFiles/info/media/info_media_list_widget.cpp index 94523007c..64eb48d15 100644 --- a/Telegram/SourceFiles/info/media/info_media_list_widget.cpp +++ b/Telegram/SourceFiles/info/media/info_media_list_widget.cpp @@ -142,7 +142,7 @@ private: void refreshHeight(); Type _type = Type::Photo; - Text _header; + Ui::Text::String _header; Items _items; int _itemsLeft = 0; int _itemsTop = 0; @@ -1452,7 +1452,7 @@ void ListWidget::switchToWordSelection() { Expects(_overLayout != nullptr); StateRequest request; - request.flags |= Text::StateRequest::Flag::LookupSymbol; + request.flags |= Ui::Text::StateRequest::Flag::LookupSymbol; auto dragState = _overLayout->getState(_pressState.cursor, request); if (dragState.cursor != CursorState::Text) { return; @@ -1665,7 +1665,7 @@ void ListWidget::mouseActionUpdate(const QPoint &globalPosition) { } StateRequest request; if (_mouseAction == MouseAction::Selecting) { - request.flags |= Text::StateRequest::Flag::LookupSymbol; + request.flags |= Ui::Text::StateRequest::Flag::LookupSymbol; } else { inTextSelection = false; } @@ -1830,7 +1830,7 @@ void ListWidget::mouseActionStart( auto validStartPoint = startDistance < QApplication::startDragDistance(); if (_trippleClickStartTime != 0 && validStartPoint) { StateRequest request; - request.flags = Text::StateRequest::Flag::LookupSymbol; + request.flags = Ui::Text::StateRequest::Flag::LookupSymbol; dragState = pressLayout->getState(_pressState.cursor, request); if (dragState.cursor == CursorState::Text) { TextSelection selStatus = { dragState.symbol, dragState.symbol }; @@ -1846,7 +1846,7 @@ void ListWidget::mouseActionStart( } } else { StateRequest request; - request.flags = Text::StateRequest::Flag::LookupSymbol; + request.flags = Ui::Text::StateRequest::Flag::LookupSymbol; dragState = pressLayout->getState(_pressState.cursor, request); } if (_mouseSelectType != TextSelectType::Paragraphs) { @@ -1901,7 +1901,7 @@ void ListWidget::performDrag() { } else if (auto pressLayout = getExistingLayout( _pressState.itemId)) { StateRequest request; - request.flags |= Text::StateRequest::Flag::LookupSymbol; + request.flags |= Ui::Text::StateRequest::Flag::LookupSymbol; auto dragState = pressLayout->getState( _pressState.cursor, request); diff --git a/Telegram/SourceFiles/info/profile/info_profile_actions.cpp b/Telegram/SourceFiles/info/profile/info_profile_actions.cpp index 8db6b060d..9aed1af2a 100644 --- a/Telegram/SourceFiles/info/profile/info_profile_actions.cpp +++ b/Telegram/SourceFiles/info/profile/info_profile_actions.cpp @@ -24,6 +24,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "boxes/peer_list_controllers.h" #include "boxes/add_contact_box.h" #include "boxes/report_box.h" +#include "boxes/generic_box.h" #include "lang/lang_keys.h" #include "info/info_controller.h" #include "info/info_memento.h" @@ -33,8 +34,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "info/profile/info_profile_text.h" #include "support/support_helper.h" #include "window/window_session_controller.h" +#include "window/window_controller.h" #include "window/window_peer_menu.h" #include "mainwidget.h" +#include "mainwindow.h" // MainWindow::controller. #include "auth_session.h" #include "core/application.h" #include "apiwrap.h" @@ -566,6 +569,8 @@ void ActionsFiller::addReportAction() { } void ActionsFiller::addBlockAction(not_null user) { + const auto window = &_controller->parentController()->window()->controller(); + auto text = Notify::PeerUpdateValue( user, Notify::PeerUpdate::Flag::UserIsBlocked @@ -591,12 +596,14 @@ void ActionsFiller::addBlockAction(not_null user) { }); auto callback = [=] { if (user->isBlocked()) { - Auth().api().unblockUser(user); + user->session().api().unblockUser(user); if (user->botInfo) { Ui::showPeerHistory(user, ShowAtUnreadMsgId); } + } else if (user->isBot()) { + user->session().api().blockUser(user); } else { - Auth().api().blockUser(user); + window->show(Box(Window::PeerMenuBlockUserBox, user, window)); } }; AddActionButton( diff --git a/Telegram/SourceFiles/inline_bots/inline_bot_layout_internal.h b/Telegram/SourceFiles/inline_bots/inline_bot_layout_internal.h index c29983dd1..e6696d6e6 100644 --- a/Telegram/SourceFiles/inline_bots/inline_bot_layout_internal.h +++ b/Telegram/SourceFiles/inline_bots/inline_bot_layout_internal.h @@ -199,7 +199,7 @@ private: ClickHandlerPtr _link; mutable QPixmap _thumb; - Text _title, _description; + Ui::Text::String _title, _description; QString _duration; int _durationWidth = 0; @@ -286,7 +286,7 @@ private: }; mutable std::unique_ptr _animation; - Text _title, _description; + Ui::Text::String _title, _description; ClickHandlerPtr _open, _cancel; // >= 0 will contain download / upload string, _statusSize = loaded bytes @@ -317,7 +317,7 @@ public: private: mutable QPixmap _thumb; - Text _title, _description; + Ui::Text::String _title, _description; void prepareThumbnail(int width, int height) const; @@ -340,7 +340,7 @@ private: bool _withThumb; mutable QPixmap _thumb; - Text _title, _description; + Ui::Text::String _title, _description; QString _thumbLetter, _urlText; int32 _urlWidth; @@ -375,7 +375,7 @@ private: mutable QPixmap _thumb; mutable bool _thumbGood = false; mutable std::unique_ptr _radial; - Text _title, _description; + Ui::Text::String _title, _description; QSize _frameSize; diff --git a/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp b/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp index 8ccc8a165..3d991c6d9 100644 --- a/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp +++ b/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp @@ -1607,7 +1607,7 @@ void OverlayWidget::refreshFromLabel(HistoryItem *item) { } void OverlayWidget::refreshCaption(HistoryItem *item) { - _caption = Text(); + _caption = Ui::Text::String(); if (!item) { return; } else if (const auto media = item->media()) { @@ -1625,7 +1625,7 @@ void OverlayWidget::refreshCaption(HistoryItem *item) { } return false; }(); - _caption = Text(st::msgMinWidth); + _caption = Ui::Text::String(st::msgMinWidth); _caption.setMarkedText( st::mediaviewCaptionStyle, caption, diff --git a/Telegram/SourceFiles/media/view/media_view_overlay_widget.h b/Telegram/SourceFiles/media/view/media_view_overlay_widget.h index 43da370bd..8817a2e78 100644 --- a/Telegram/SourceFiles/media/view/media_view_overlay_widget.h +++ b/Telegram/SourceFiles/media/view/media_view_overlay_widget.h @@ -348,7 +348,7 @@ private: int _groupThumbsAvailableWidth = 0; int _groupThumbsLeft = 0; int _groupThumbsTop = 0; - Text _caption; + Ui::Text::String _caption; QRect _captionRect; int _width = 0; @@ -394,7 +394,7 @@ private: PeerData *_from = nullptr; QString _fromName; - Text _fromNameLabel; + Ui::Text::String _fromNameLabel; std::optional _index; // Index in current _sharedMedia data. std::optional _fullIndex; // Index in full shared media. @@ -448,7 +448,7 @@ private: anim::value _saveMsgOpacity; QRect _saveMsg; QTimer _saveMsgUpdater; - Text _saveMsgText; + Ui::Text::String _saveMsgText; base::flat_map _animations; base::flat_map _animationOpacities; diff --git a/Telegram/SourceFiles/overview/overview_layout.h b/Telegram/SourceFiles/overview/overview_layout.h index f24803a74..293cd2211 100644 --- a/Telegram/SourceFiles/overview/overview_layout.h +++ b/Telegram/SourceFiles/overview/overview_layout.h @@ -282,7 +282,7 @@ private: const style::OverviewFileLayout &_st; - Text _name, _details; + Ui::Text::String _name, _details; int _nameVersion; void updateName(); @@ -330,7 +330,7 @@ private: bool _thumbLoaded = false; QPixmap _thumb; - Text _name; + Ui::Text::String _name; QString _date, _ext; int32 _datew, _extw; int32 _thumbw, _colorIndex; @@ -364,7 +364,7 @@ private: WebPageData *_page = nullptr; int _pixw = 0; int _pixh = 0; - Text _text = { st::msgMinWidth }; + Ui::Text::String _text = { st::msgMinWidth }; struct LinkEntry { LinkEntry() : width(0) { diff --git a/Telegram/SourceFiles/passport/passport_panel_edit_scans.cpp b/Telegram/SourceFiles/passport/passport_panel_edit_scans.cpp index e6b0afded..c3d979302 100644 --- a/Telegram/SourceFiles/passport/passport_panel_edit_scans.cpp +++ b/Telegram/SourceFiles/passport/passport_panel_edit_scans.cpp @@ -99,8 +99,8 @@ private: int countAvailableWidth() const; const style::PassportScanRow &_st; - Text _name; - Text _status; + Ui::Text::String _name; + Ui::Text::String _status; int _nameHeight = 0; int _statusHeight = 0; bool _error = false; diff --git a/Telegram/SourceFiles/passport/passport_panel_form.cpp b/Telegram/SourceFiles/passport/passport_panel_form.cpp index 6d73697ac..05a704c7d 100644 --- a/Telegram/SourceFiles/passport/passport_panel_form.cpp +++ b/Telegram/SourceFiles/passport/passport_panel_form.cpp @@ -47,8 +47,8 @@ private: int countAvailableWidth() const; int countAvailableWidth(int newWidth) const; - Text _title; - Text _description; + Ui::Text::String _title; + Ui::Text::String _description; int _titleHeight = 0; int _descriptionHeight = 0; bool _ready = false; diff --git a/Telegram/SourceFiles/profile/profile_block_peer_list.h b/Telegram/SourceFiles/profile/profile_block_peer_list.h index d834780d3..2dc1b03b1 100644 --- a/Telegram/SourceFiles/profile/profile_block_peer_list.h +++ b/Telegram/SourceFiles/profile/profile_block_peer_list.h @@ -33,7 +33,7 @@ public: ~Item(); PeerData * const peer; - Text name; + Ui::Text::String name; QString statusText; bool statusHasOnlineColor = false; enum class AdminState { diff --git a/Telegram/SourceFiles/support/support_autocomplete.cpp b/Telegram/SourceFiles/support/support_autocomplete.cpp index 8c8b03bd6..20c965fe6 100644 --- a/Telegram/SourceFiles/support/support_autocomplete.cpp +++ b/Telegram/SourceFiles/support/support_autocomplete.cpp @@ -54,9 +54,9 @@ protected: private: struct Row { Question data; - Text question = { st::windowMinWidth / 2 }; - Text keys = { st::windowMinWidth / 2 }; - Text answer = { st::windowMinWidth / 2 }; + Ui::Text::String question = { st::windowMinWidth / 2 }; + Ui::Text::String keys = { st::windowMinWidth / 2 }; + Ui::Text::String answer = { st::windowMinWidth / 2 }; int top = 0; int height = 0; }; @@ -73,7 +73,7 @@ private: }; -int TextHeight(const Text &text, int available, int lines) { +int TextHeight(const Ui::Text::String &text, int available, int lines) { Expects(text.style() != nullptr); const auto st = text.style(); @@ -179,7 +179,7 @@ void Inner::paintEvent(QPaintEvent *e) { const auto padding = st::autocompleteRowPadding; const auto available = width() - padding.left() - padding.right(); auto top = padding.top(); - const auto drawText = [&](const Text &text, int lines) { + const auto drawText = [&](const Ui::Text::String &text, int lines) { text.drawLeftElided( p, padding.left(), diff --git a/Telegram/SourceFiles/ui/text/text.cpp b/Telegram/SourceFiles/ui/text/text.cpp index 067c7fbee..3de8ef874 100644 --- a/Telegram/SourceFiles/ui/text/text.cpp +++ b/Telegram/SourceFiles/ui/text/text.cpp @@ -18,14 +18,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "boxes/confirm_box.h" #include "mainwindow.h" -namespace { - -inline int32 countBlockHeight(const ITextBlock *b, const style::TextStyle *st) { - return (b->type() == TextBlockTSkip) ? static_cast(b)->height() : (st->lineHeight > st->font->height) ? st->lineHeight : st->font->height; -} - -} // namespace - bool chIsBad(QChar ch) { return (ch == 0) || (ch >= 8232 && ch < 8237) @@ -139,7 +131,24 @@ const QChar *textSkipCommand(const QChar *from, const QChar *end, bool canLink) return (result < end && *result == TextCommand) ? (result + 1) : from; } -class TextParser { +const TextParseOptions _defaultOptions = { + TextParseLinks | TextParseMultiline, // flags + 0, // maxw + 0, // maxh + Qt::LayoutDirectionAuto, // dir +}; + +const TextParseOptions _textPlainOptions = { + TextParseMultiline, // flags + 0, // maxw + 0, // maxh + Qt::LayoutDirectionAuto, // dir +}; + +namespace Ui { +namespace Text { + +class Parser { public: static Qt::LayoutDirection stringDirection(const QString &str, int32 from, int32 to) { const ushort *p = reinterpret_cast(str.unicode()) + from; @@ -505,7 +514,7 @@ public: emoji = e; } - TextParser(Text *t, const QString &text, const TextParseOptions &options) : _t(t), + Parser(String *t, const QString &text, const TextParseOptions &options) : _t(t), source { text }, rich(options.flags & TextParseRichText), multiline(options.flags & TextParseMultiline), @@ -516,7 +525,7 @@ public: parse(options); } - TextParser(Text *t, const TextWithEntities &textWithEntities, const TextParseOptions &options) : _t(t), + Parser(String *t, const TextWithEntities &textWithEntities, const TextParseOptions &options) : _t(t), source(textWithEntities), rich(options.flags & TextParseRichText), multiline(options.flags & TextParseMultiline), @@ -717,7 +726,7 @@ private: *outDisplayStatus = (*outLinkText == readable) ? LinkDisplayedFull : LinkDisplayedElided; } - Text *_t; + String *_t; TextWithEntities source; const QChar *start, *end, *ptr; bool rich, multiline; @@ -749,6 +758,7 @@ private: }; namespace { + // COPIED FROM qtextengine.cpp AND MODIFIED struct BidiStatus { @@ -841,17 +851,21 @@ static void eAppendItems(QScriptAnalysis *analysis, int &start, int &stop, const start = stop; } +inline int32 countBlockHeight(const AbstractBlock *b, const style::TextStyle *st) { + return (b->type() == TextBlockTSkip) ? static_cast(b)->height() : (st->lineHeight > st->font->height) ? st->lineHeight : st->font->height; +} + } // namespace -class TextPainter { +class Renderer { public: - TextPainter(Painter *p, const Text *t) + Renderer(Painter *p, const String *t) : _p(p) , _t(t) , _originalPen(p ? p->pen() : QPen()) { } - ~TextPainter() { + ~Renderer() { restoreAfterElided(); if (_p) { _p->setPen(_originalPen); @@ -1071,15 +1085,15 @@ public: draw(left, top, w, align, yFrom, yTo, selection); } - Text::StateResult getState(QPoint point, int w, Text::StateRequest request) { + StateResult getState(QPoint point, int w, StateRequest request) { if (!_t->isNull() && point.y() >= 0) { _lookupRequest = request; _lookupX = point.x(); _lookupY = point.y(); - _breakEverywhere = (_lookupRequest.flags & Text::StateRequest::Flag::BreakEverywhere); - _lookupSymbol = (_lookupRequest.flags & Text::StateRequest::Flag::LookupSymbol); - _lookupLink = (_lookupRequest.flags & Text::StateRequest::Flag::LookupLink); + _breakEverywhere = (_lookupRequest.flags & StateRequest::Flag::BreakEverywhere); + _lookupSymbol = (_lookupRequest.flags & StateRequest::Flag::LookupSymbol); + _lookupLink = (_lookupRequest.flags & StateRequest::Flag::LookupLink); if (_lookupSymbol || (_lookupX >= 0 && _lookupX < w)) { draw(0, 0, w, _lookupRequest.align, _lookupY, _lookupY + 1); } @@ -1087,15 +1101,15 @@ public: return _lookupResult; } - Text::StateResult getStateElided(QPoint point, int w, Text::StateRequestElided request) { + StateResult getStateElided(QPoint point, int w, StateRequestElided request) { if (!_t->isNull() && point.y() >= 0 && request.lines > 0) { _lookupRequest = request; _lookupX = point.x(); _lookupY = point.y(); - _breakEverywhere = (_lookupRequest.flags & Text::StateRequest::Flag::BreakEverywhere); - _lookupSymbol = (_lookupRequest.flags & Text::StateRequest::Flag::LookupSymbol); - _lookupLink = (_lookupRequest.flags & Text::StateRequest::Flag::LookupLink); + _breakEverywhere = (_lookupRequest.flags & StateRequest::Flag::BreakEverywhere); + _lookupSymbol = (_lookupRequest.flags & StateRequest::Flag::LookupSymbol); + _lookupLink = (_lookupRequest.flags & StateRequest::Flag::LookupLink); if (_lookupSymbol || (_lookupX >= 0 && _lookupX < w)) { int yTo = _lookupY + 1; if (yTo < 0 || (request.lines - 1) * _t->_st->font->height < yTo) { @@ -1110,9 +1124,9 @@ public: } private: - void initNextParagraph(Text::TextBlocks::const_iterator i) { + void initNextParagraph(String::TextBlocks::const_iterator i) { _parStartBlock = i; - Text::TextBlocks::const_iterator e = _t->_blocks.cend(); + const auto e = _t->_blocks.cend(); if (i == e) { _parStart = _t->_text.size(); _parLength = 0; @@ -1131,7 +1145,7 @@ private: void initParagraphBidi() { if (!_parLength || !_parAnalysis.isEmpty()) return; - Text::TextBlocks::const_iterator i = _parStartBlock, e = _t->_blocks.cend(), n = i + 1; + String::TextBlocks::const_iterator i = _parStartBlock, e = _t->_blocks.cend(), n = i + 1; bool ignore = false; bool rtl = (_parDirection == Qt::RightToLeft); @@ -1171,7 +1185,7 @@ private: } } - bool drawLine(uint16 _lineEnd, const Text::TextBlocks::const_iterator &_endBlockIter, const Text::TextBlocks::const_iterator &_end) { + bool drawLine(uint16 _lineEnd, const String::TextBlocks::const_iterator &_endBlockIter, const String::TextBlocks::const_iterator &_end) { _yDelta = (_lineHeight - _fontHeight) / 2; if (_yTo >= 0 && (_y + _yDelta >= _yTo || _y >= _yTo)) return false; if (_y + _yDelta + _fontHeight <= _yFrom) { @@ -1618,13 +1632,13 @@ private: _p->fillRect(left, _y + _yDelta, width, _fontHeight, _textPalette->selectBg); } - void elideSaveBlock(int32 blockIndex, ITextBlock *&_endBlock, int32 elideStart, int32 elideWidth) { + void elideSaveBlock(int32 blockIndex, AbstractBlock *&_endBlock, int32 elideStart, int32 elideWidth) { if (_elideSavedBlock) { restoreAfterElided(); } _elideSavedIndex = blockIndex; - auto mutableText = const_cast(_t); + auto mutableText = const_cast(_t); _elideSavedBlock = std::move(mutableText->_blocks[blockIndex]); mutableText->_blocks[blockIndex] = std::make_unique(_t->_st->font, _t->_text, QFIXED_MAX, elideStart, 0, _elideSavedBlock->flags(), _elideSavedBlock->lnkIndex()); _blocksSize = blockIndex + 1; @@ -1641,7 +1655,7 @@ private: } } - void prepareElidedLine(QString &lineText, int32 lineStart, int32 &lineLength, ITextBlock *&_endBlock, int repeat = 0) { + void prepareElidedLine(QString &lineText, int32 lineStart, int32 &lineLength, AbstractBlock *&_endBlock, int repeat = 0) { static const QString _Elide = qsl("..."); _f = _t->_st->font; @@ -1751,7 +1765,7 @@ private: void restoreAfterElided() { if (_elideSavedBlock) { - const_cast(_t)->_blocks[_elideSavedIndex] = std::move(_elideSavedBlock); + const_cast(_t)->_blocks[_elideSavedIndex] = std::move(_elideSavedBlock); } } @@ -1807,7 +1821,7 @@ private: return result; } - void eSetFont(ITextBlock *block) { + void eSetFont(AbstractBlock *block) { style::font newFont = _t->_st->font; int flags = block->flags(); if (flags) { @@ -1931,8 +1945,8 @@ private: QChar::Direction eSkipBoundryNeutrals(QScriptAnalysis *analysis, const ushort *unicode, int &sor, int &eor, BidiControl &control, - Text::TextBlocks::const_iterator i) { - Text::TextBlocks::const_iterator e = _t->_blocks.cend(), n = i + 1; + String::TextBlocks::const_iterator i) { + String::TextBlocks::const_iterator e = _t->_blocks.cend(), n = i + 1; QChar::Direction dir = control.basicDirection(); int level = sor > 0 ? analysis[sor - 1].bidiLevel : control.level; @@ -1980,7 +1994,7 @@ private: QChar::Direction dir = rightToLeft ? QChar::DirR : QChar::DirL; BidiStatus status; - Text::TextBlocks::const_iterator i = _parStartBlock, e = _t->_blocks.cend(), n = i + 1; + String::TextBlocks::const_iterator i = _parStartBlock, e = _t->_blocks.cend(), n = i + 1; QChar::Direction sdir; TextBlockType _stype = (*_parStartBlock)->type(); @@ -2389,7 +2403,7 @@ private: } private: - void applyBlockProperties(ITextBlock *block) { + void applyBlockProperties(AbstractBlock *block) { eSetFont(block); if (_p) { if (block->lnkIndex()) { @@ -2407,7 +2421,7 @@ private: Painter *_p = nullptr; const style::TextPalette *_textPalette = nullptr; - const Text *_t = nullptr; + const String *_t = nullptr; bool _elideLast = false; bool _breakEverywhere = false; int _elideRemoveFromEnd = 0; @@ -2424,7 +2438,7 @@ private: const QChar *_str = nullptr; // current paragraph data - Text::TextBlocks::const_iterator _parStartBlock; + String::TextBlocks::const_iterator _parStartBlock; Qt::LayoutDirection _parDirection; int _parStart = 0; int _parLength = 0; @@ -2440,7 +2454,7 @@ private: // elided hack support int _blocksSize = 0; int _elideSavedIndex = 0; - std::unique_ptr _elideSavedBlock; + std::unique_ptr _elideSavedBlock; int _lineStart = 0; int _localFrom = 0; @@ -2451,29 +2465,15 @@ private: int _lookupY = 0; bool _lookupSymbol = false; bool _lookupLink = false; - Text::StateRequest _lookupRequest; - Text::StateResult _lookupResult; + StateRequest _lookupRequest; + StateResult _lookupResult; }; -const TextParseOptions _defaultOptions = { - TextParseLinks | TextParseMultiline, // flags - 0, // maxw - 0, // maxh - Qt::LayoutDirectionAuto, // dir -}; - -const TextParseOptions _textPlainOptions = { - TextParseMultiline, // flags - 0, // maxw - 0, // maxh - Qt::LayoutDirectionAuto, // dir -}; - -Text::Text(int32 minResizeWidth) : _minResizeWidth(minResizeWidth) { +String::String(int32 minResizeWidth) : _minResizeWidth(minResizeWidth) { } -Text::Text(const style::TextStyle &st, const QString &text, const TextParseOptions &options, int32 minResizeWidth, bool richText) : _minResizeWidth(minResizeWidth) { +String::String(const style::TextStyle &st, const QString &text, const TextParseOptions &options, int32 minResizeWidth, bool richText) : _minResizeWidth(minResizeWidth) { if (richText) { setRichText(st, text, options); } else { @@ -2481,7 +2481,7 @@ Text::Text(const style::TextStyle &st, const QString &text, const TextParseOptio } } -Text::Text(const Text &other) +String::String(const String &other) : _minResizeWidth(other._minResizeWidth) , _maxWidth(other._maxWidth) , _minHeight(other._minHeight) @@ -2495,7 +2495,7 @@ Text::Text(const Text &other) } } -Text::Text(Text &&other) +String::String(String &&other) : _minResizeWidth(other._minResizeWidth) , _maxWidth(other._maxWidth) , _minHeight(other._minHeight) @@ -2507,7 +2507,7 @@ Text::Text(Text &&other) other.clearFields(); } -Text &Text::operator=(const Text &other) { +String &String::operator=(const String &other) { _minResizeWidth = other._minResizeWidth; _maxWidth = other._maxWidth; _minHeight = other._minHeight; @@ -2522,7 +2522,7 @@ Text &Text::operator=(const Text &other) { return *this; } -Text &Text::operator=(Text &&other) { +String &String::operator=(String &&other) { _minResizeWidth = other._minResizeWidth; _maxWidth = other._maxWidth; _minHeight = other._minHeight; @@ -2535,16 +2535,16 @@ Text &Text::operator=(Text &&other) { return *this; } -void Text::setText(const style::TextStyle &st, const QString &text, const TextParseOptions &options) { +void String::setText(const style::TextStyle &st, const QString &text, const TextParseOptions &options) { _st = &st; clear(); { - TextParser parser(this, text, options); + Parser parser(this, text, options); } recountNaturalSize(true, options.dir); } -void Text::recountNaturalSize(bool initial, Qt::LayoutDirection optionsDir) { +void String::recountNaturalSize(bool initial, Qt::LayoutDirection optionsDir) { NewlineBlock *lastNewline = 0; _maxWidth = _minHeight = 0; @@ -2560,7 +2560,7 @@ void Text::recountNaturalSize(bool initial, Qt::LayoutDirection optionsDir) { if (initial) { Qt::LayoutDirection dir = optionsDir; if (dir == Qt::LayoutDirectionAuto) { - dir = TextParser::stringDirection(_text, lastNewlineStart, b->from()); + dir = Parser::stringDirection(_text, lastNewlineStart, b->from()); } if (lastNewline) { lastNewline->_nextDir = dir; @@ -2602,7 +2602,7 @@ void Text::recountNaturalSize(bool initial, Qt::LayoutDirection optionsDir) { if (initial) { Qt::LayoutDirection dir = optionsDir; if (dir == Qt::LayoutDirectionAuto) { - dir = TextParser::stringDirection(_text, lastNewlineStart, _text.size()); + dir = Parser::stringDirection(_text, lastNewlineStart, _text.size()); } if (lastNewline) { lastNewline->_nextDir = dir; @@ -2617,7 +2617,7 @@ void Text::recountNaturalSize(bool initial, Qt::LayoutDirection optionsDir) { } } -void Text::setMarkedText(const style::TextStyle &st, const TextWithEntities &textWithEntities, const TextParseOptions &options) { +void String::setMarkedText(const style::TextStyle &st, const TextWithEntities &textWithEntities, const TextParseOptions &options) { _st = &st; clear(); { @@ -2645,14 +2645,14 @@ void Text::setMarkedText(const style::TextStyle &st, const TextWithEntities &tex // } // } // newText.append("},\n\n").append(text); -// TextParser parser(this, { newText, EntitiesInText() }, options); +// Parser parser(this, { newText, EntitiesInText() }, options); - TextParser parser(this, textWithEntities, options); + Parser parser(this, textWithEntities, options); } recountNaturalSize(true, options.dir); } -void Text::setRichText(const style::TextStyle &st, const QString &text, TextParseOptions options, const TextCustomTagsMap &custom) { +void String::setRichText(const style::TextStyle &st, const QString &text, TextParseOptions options, const TextCustomTagsMap &custom) { QString parsed; parsed.reserve(text.size()); const QChar *s = text.constData(), *ch = s; @@ -2730,20 +2730,20 @@ void Text::setRichText(const style::TextStyle &st, const QString &text, TextPars setText(st, parsed, options); } -void Text::setLink(uint16 lnkIndex, const ClickHandlerPtr &lnk) { +void String::setLink(uint16 lnkIndex, const ClickHandlerPtr &lnk) { if (!lnkIndex || lnkIndex > _links.size()) return; _links[lnkIndex - 1] = lnk; } -bool Text::hasLinks() const { +bool String::hasLinks() const { return !_links.isEmpty(); } -bool Text::hasSkipBlock() const { +bool String::hasSkipBlock() const { return _blocks.empty() ? false : _blocks.back()->type() == TextBlockTSkip; } -bool Text::updateSkipBlock(int width, int height) { +bool String::updateSkipBlock(int width, int height) { if (!_blocks.empty() && _blocks.back()->type() == TextBlockTSkip) { const auto block = static_cast(_blocks.back().get()); if (block->width() == width && block->height() == height) { @@ -2764,7 +2764,7 @@ bool Text::updateSkipBlock(int width, int height) { return true; } -bool Text::removeSkipBlock() { +bool String::removeSkipBlock() { if (_blocks.empty() || _blocks.back()->type() != TextBlockTSkip) { return false; } @@ -2774,7 +2774,7 @@ bool Text::removeSkipBlock() { return true; } -int Text::countWidth(int width) const { +int String::countWidth(int width) const { if (QFixed(width) >= _maxWidth) { return _maxWidth.ceil().toInt(); } @@ -2788,7 +2788,7 @@ int Text::countWidth(int width) const { return maxLineWidth.ceil().toInt(); } -int Text::countHeight(int width) const { +int String::countHeight(int width) const { if (QFixed(width) >= _maxWidth) { return _minHeight; } @@ -2799,14 +2799,14 @@ int Text::countHeight(int width) const { return result; } -void Text::countLineWidths(int width, QVector *lineWidths) const { +void String::countLineWidths(int width, QVector *lineWidths) const { enumerateLines(width, [lineWidths](QFixed lineWidth, int lineHeight) { lineWidths->push_back(lineWidth.ceil().toInt()); }); } template -void Text::enumerateLines(int w, Callback callback) const { +void String::enumerateLines(int w, Callback callback) const { QFixed width = w; if (width < _minResizeWidth) width = _minResizeWidth; @@ -2915,27 +2915,27 @@ void Text::enumerateLines(int w, Callback callback) const { } } -void Text::draw(Painter &painter, int32 left, int32 top, int32 w, style::align align, int32 yFrom, int32 yTo, TextSelection selection, bool fullWidthSelection) const { +void String::draw(Painter &painter, int32 left, int32 top, int32 w, style::align align, int32 yFrom, int32 yTo, TextSelection selection, bool fullWidthSelection) const { // painter.fillRect(QRect(left, top, w, countHeight(w)), QColor(0, 0, 0, 32)); // debug - TextPainter p(&painter, this); + Renderer p(&painter, this); p.draw(left, top, w, align, yFrom, yTo, selection, fullWidthSelection); } -void Text::drawElided(Painter &painter, int32 left, int32 top, int32 w, int32 lines, style::align align, int32 yFrom, int32 yTo, int32 removeFromEnd, bool breakEverywhere, TextSelection selection) const { +void String::drawElided(Painter &painter, int32 left, int32 top, int32 w, int32 lines, style::align align, int32 yFrom, int32 yTo, int32 removeFromEnd, bool breakEverywhere, TextSelection selection) const { // painter.fillRect(QRect(left, top, w, countHeight(w)), QColor(0, 0, 0, 32)); // debug - TextPainter p(&painter, this); + Renderer p(&painter, this); p.drawElided(left, top, w, align, lines, yFrom, yTo, removeFromEnd, breakEverywhere, selection); } -Text::StateResult Text::getState(QPoint point, int width, StateRequest request) const { - return TextPainter(nullptr, this).getState(point, width, request); +StateResult String::getState(QPoint point, int width, StateRequest request) const { + return Renderer(nullptr, this).getState(point, width, request); } -Text::StateResult Text::getStateElided(QPoint point, int width, StateRequestElided request) const { - return TextPainter(nullptr, this).getStateElided(point, width, request); +StateResult String::getStateElided(QPoint point, int width, StateRequestElided request) const { + return Renderer(nullptr, this).getStateElided(point, width, request); } -TextSelection Text::adjustSelection(TextSelection selection, TextSelectType selectType) const { +TextSelection String::adjustSelection(TextSelection selection, TextSelectType selectType) const { uint16 from = selection.from, to = selection.to; if (from < _text.size() && from <= to) { if (to > _text.size()) to = _text.size(); @@ -2974,20 +2974,20 @@ TextSelection Text::adjustSelection(TextSelection selection, TextSelectType sele return { from, to }; } -bool Text::isEmpty() const { +bool String::isEmpty() const { return _blocks.empty() || _blocks[0]->type() == TextBlockTSkip; } -uint16 Text::countBlockEnd(const TextBlocks::const_iterator &i, const TextBlocks::const_iterator &e) const { +uint16 String::countBlockEnd(const TextBlocks::const_iterator &i, const TextBlocks::const_iterator &e) const { return (i + 1 == e) ? _text.size() : (*(i + 1))->from(); } -uint16 Text::countBlockLength(const Text::TextBlocks::const_iterator &i, const Text::TextBlocks::const_iterator &e) const { +uint16 String::countBlockLength(const String::TextBlocks::const_iterator &i, const String::TextBlocks::const_iterator &e) const { return countBlockEnd(i, e) - (*i)->from(); } template -void Text::enumerateText(TextSelection selection, AppendPartCallback appendPartCallback, ClickHandlerStartCallback clickHandlerStartCallback, ClickHandlerFinishCallback clickHandlerFinishCallback, FlagsChangeCallback flagsChangeCallback) const { +void String::enumerateText(TextSelection selection, AppendPartCallback appendPartCallback, ClickHandlerStartCallback clickHandlerStartCallback, ClickHandlerFinishCallback clickHandlerFinishCallback, FlagsChangeCallback flagsChangeCallback) const { if (isEmpty() || selection.empty()) { return; } @@ -3045,19 +3045,19 @@ void Text::enumerateText(TextSelection selection, AppendPartCallback appendPartC } } -QString Text::toString(TextSelection selection) const { +QString String::toString(TextSelection selection) const { return toText(selection, false, false).rich.text; } -TextWithEntities Text::toTextWithEntities(TextSelection selection) const { +TextWithEntities String::toTextWithEntities(TextSelection selection) const { return toText(selection, false, true).rich; } -TextForMimeData Text::toTextForMimeData(TextSelection selection) const { +TextForMimeData String::toTextForMimeData(TextSelection selection) const { return toText(selection, true, true); } -TextForMimeData Text::toText( +TextForMimeData String::toText( TextSelection selection, bool composeExpanded, bool composeEntities) const { @@ -3143,16 +3143,19 @@ TextForMimeData Text::toText( return result; } -void Text::clear() { +void String::clear() { clearFields(); _text.clear(); } -void Text::clearFields() { +void String::clearFields() { _blocks.clear(); _links.clear(); _maxWidth = _minHeight = 0; _startDir = Qt::LayoutDirectionAuto; } -Text::~Text() = default; +String::~String() = default; + +} // namespace Text +} // namespace Ui diff --git a/Telegram/SourceFiles/ui/text/text.h b/Telegram/SourceFiles/ui/text/text.h index 63af339ee..90af49b51 100644 --- a/Telegram/SourceFiles/ui/text/text.h +++ b/Telegram/SourceFiles/ui/text/text.h @@ -67,15 +67,52 @@ static constexpr TextSelection AllTextSelection = { 0, 0xFFFF }; typedef QPair TextCustomTag; // open str and close str typedef QMap TextCustomTagsMap; -class ITextBlock; -class Text { +namespace Ui { +namespace Text { + +class AbstractBlock; + +struct StateRequest { + enum class Flag { + BreakEverywhere = (1 << 0), + LookupSymbol = (1 << 1), + LookupLink = (1 << 2), + LookupCustomTooltip = (1 << 3), + }; + using Flags = base::flags; + friend inline constexpr auto is_flag_type(Flag) { return true; }; + + StateRequest() { + } + + style::align align = style::al_left; + Flags flags = Flag::LookupLink; +}; + +struct StateResult { + ClickHandlerPtr link; + bool uponSymbol = false; + bool afterSymbol = false; + uint16 symbol = 0; +}; + +struct StateRequestElided : public StateRequest { + StateRequestElided() { + } + StateRequestElided(const StateRequest &other) : StateRequest(other) { + } + int lines = 1; + int removeFromEnd = 0; +}; + +class String { public: - Text(int32 minResizeWidth = QFIXED_MAX); - Text(const style::TextStyle &st, const QString &text, const TextParseOptions &options = _defaultOptions, int32 minResizeWidth = QFIXED_MAX, bool richText = false); - Text(const Text &other); - Text(Text &&other); - Text &operator=(const Text &other); - Text &operator=(Text &&other); + String(int32 minResizeWidth = QFIXED_MAX); + String(const style::TextStyle &st, const QString &text, const TextParseOptions &options = _defaultOptions, int32 minResizeWidth = QFIXED_MAX, bool richText = false); + String(const String &other); + String(String &&other); + String &operator=(const String &other); + String &operator=(String &&other); int countWidth(int width) const; int countHeight(int width) const; @@ -113,40 +150,10 @@ public: drawElided(p, rtl() ? right : (outerw - right - width), top, width, lines, align, yFrom, yTo, removeFromEnd, breakEverywhere, selection); } - struct StateRequest { - enum class Flag { - BreakEverywhere = (1 << 0), - LookupSymbol = (1 << 1), - LookupLink = (1 << 2), - LookupCustomTooltip = (1 << 3), - }; - using Flags = base::flags; - friend inline constexpr auto is_flag_type(Flag) { return true; }; - - StateRequest() { - } - - style::align align = style::al_left; - Flags flags = Flag::LookupLink; - }; - struct StateResult { - ClickHandlerPtr link; - bool uponSymbol = false; - bool afterSymbol = false; - uint16 symbol = 0; - }; StateResult getState(QPoint point, int width, StateRequest request = StateRequest()) const; StateResult getStateLeft(QPoint point, int width, int outerw, StateRequest request = StateRequest()) const { return getState(rtlpoint(point, outerw), width, request); } - struct StateRequestElided : public StateRequest { - StateRequestElided() { - } - StateRequestElided(const StateRequest &other) : StateRequest(other) { - } - int lines = 1; - int removeFromEnd = 0; - }; StateResult getStateElided(QPoint point, int width, StateRequestElided request = StateRequestElided()) const; StateResult getStateElidedLeft(QPoint point, int width, int outerw, StateRequestElided request = StateRequestElided()) const { return getStateElided(rtlpoint(point, outerw), width, request); @@ -195,14 +202,14 @@ public: } void clear(); - ~Text(); + ~String(); private: - using TextBlocks = std::vector>; + using TextBlocks = std::vector>; using TextLinks = QVector; uint16 countBlockEnd(const TextBlocks::const_iterator &i, const TextBlocks::const_iterator &e) const; - uint16 countBlockLength(const Text::TextBlocks::const_iterator &i, const Text::TextBlocks::const_iterator &e) const; + uint16 countBlockLength(const TextBlocks::const_iterator &i, const TextBlocks::const_iterator &e) const; // Template method for originalText(), originalTextWithEntities(). template @@ -237,10 +244,14 @@ private: Qt::LayoutDirection _startDir = Qt::LayoutDirectionAuto; - friend class TextParser; - friend class TextPainter; + friend class Parser; + friend class Renderer; }; + +} // namespace Text +} // namespace Ui + inline TextSelection snapSelection(int from, int to) { return { static_cast(snap(from, 0, 0xFFFF)), static_cast(snap(to, 0, 0xFFFF)) }; } @@ -250,10 +261,10 @@ inline TextSelection shiftSelection(TextSelection selection, uint16 byLength) { inline TextSelection unshiftSelection(TextSelection selection, uint16 byLength) { return snapSelection(int(selection.from) - int(byLength), int(selection.to) - int(byLength)); } -inline TextSelection shiftSelection(TextSelection selection, const Text &byText) { +inline TextSelection shiftSelection(TextSelection selection, const Ui::Text::String &byText) { return shiftSelection(selection, byText.length()); } -inline TextSelection unshiftSelection(TextSelection selection, const Text &byText) { +inline TextSelection unshiftSelection(TextSelection selection, const Ui::Text::String &byText) { return unshiftSelection(selection, byText.length()); } diff --git a/Telegram/SourceFiles/ui/text/text_block.cpp b/Telegram/SourceFiles/ui/text/text_block.cpp index 2959cec77..9c758a3b5 100644 --- a/Telegram/SourceFiles/ui/text/text_block.cpp +++ b/Telegram/SourceFiles/ui/text/text_block.cpp @@ -10,6 +10,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "core/crash_reports.h" // COPIED FROM qtextlayout.cpp AND MODIFIED +namespace Ui { +namespace Text { namespace { struct ScriptLine { @@ -154,17 +156,17 @@ public: void parseWords(QFixed minResizeWidth, int32 blockFrom) { LineBreakHelper lbh; -// Helper for debugging crashes in text processing. -// -// auto debugChars = QString(); -// debugChars.reserve(str.size() * 7); -// for (const auto ch : str) { -// debugChars.append( -// "0x").append( -// QString::number(ch.unicode(), 16).toUpper()).append( -// ' '); -// } -// LOG(("Text: %1, chars: %2").arg(str).arg(debugChars)); + // Helper for debugging crashes in text processing. + // + // auto debugChars = QString(); + // debugChars.reserve(str.size() * 7); + // for (const auto ch : str) { + // debugChars.append( + // "0x").append( + // QString::number(ch.unicode(), 16).toUpper()).append( + // ' '); + // } + // LOG(("Text: %1, chars: %2").arg(str).arg(debugChars)); int item = -1; int newItem = eng->findItem(0); @@ -292,11 +294,11 @@ private: }; -QFixed ITextBlock::f_rbearing() const { +QFixed AbstractBlock::f_rbearing() const { return (type() == TextBlockTText) ? static_cast(this)->real_f_rbearing() : 0; } -TextBlock::TextBlock(const style::font &font, const QString &str, QFixed minResizeWidth, uint16 from, uint16 length, uchar flags, uint16 lnkIndex) : ITextBlock(font, str, from, length, flags, lnkIndex) { +TextBlock::TextBlock(const style::font &font, const QString &str, QFixed minResizeWidth, uint16 from, uint16 length, uchar flags, uint16 lnkIndex) : AbstractBlock(font, str, from, length, flags, lnkIndex) { _flags |= ((TextBlockTText & 0x0F) << 8); if (length) { style::font blockFont = font; @@ -337,7 +339,7 @@ TextBlock::TextBlock(const style::font &font, const QString &str, QFixed minResi } } -EmojiBlock::EmojiBlock(const style::font &font, const QString &str, uint16 from, uint16 length, uchar flags, uint16 lnkIndex, EmojiPtr emoji) : ITextBlock(font, str, from, length, flags, lnkIndex) +EmojiBlock::EmojiBlock(const style::font &font, const QString &str, uint16 from, uint16 length, uchar flags, uint16 lnkIndex, EmojiPtr emoji) : AbstractBlock(font, str, from, length, flags, lnkIndex) , emoji(emoji) { _flags |= ((TextBlockTEmoji & 0x0F) << 8); _width = int(st::emojiSize + 2 * st::emojiPadding); @@ -353,7 +355,10 @@ EmojiBlock::EmojiBlock(const style::font &font, const QString &str, uint16 from, } } -SkipBlock::SkipBlock(const style::font &font, const QString &str, uint16 from, int32 w, int32 h, uint16 lnkIndex) : ITextBlock(font, str, from, 1, 0, lnkIndex), _height(h) { +SkipBlock::SkipBlock(const style::font &font, const QString &str, uint16 from, int32 w, int32 h, uint16 lnkIndex) : AbstractBlock(font, str, from, 1, 0, lnkIndex), _height(h) { _flags |= ((TextBlockTSkip & 0x0F) << 8); _width = w; } + +} // namespace Text +} // namespace Ui diff --git a/Telegram/SourceFiles/ui/text/text_block.h b/Telegram/SourceFiles/ui/text/text_block.h index 3517208cf..853851030 100644 --- a/Telegram/SourceFiles/ui/text/text_block.h +++ b/Telegram/SourceFiles/ui/text/text_block.h @@ -9,6 +9,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "private/qfontengine_p.h" +namespace Ui { +namespace Text { + enum TextBlockType { TextBlockTNewline = 0x01, TextBlockTText = 0x02, @@ -26,9 +29,9 @@ enum TextBlockFlags { TextBlockFPre = 0x40, }; -class ITextBlock { +class AbstractBlock { public: - ITextBlock(const style::font &font, const QString &str, uint16 from, uint16 length, uchar flags, uint16 lnkIndex) : _from(from), _flags((flags & 0xFF) | ((lnkIndex & 0xFFFF) << 12)) { + AbstractBlock(const style::font &font, const QString &str, uint16 from, uint16 length, uchar flags, uint16 lnkIndex) : _from(from), _flags((flags & 0xFF) | ((lnkIndex & 0xFFFF) << 12)) { } uint16 from() const { @@ -64,8 +67,8 @@ public: return (_flags & 0xFF); } - virtual std::unique_ptr clone() const = 0; - virtual ~ITextBlock() { + virtual std::unique_ptr clone() const = 0; + virtual ~AbstractBlock() { } protected: @@ -84,9 +87,9 @@ protected: }; -class NewlineBlock : public ITextBlock { +class NewlineBlock : public AbstractBlock { public: - NewlineBlock(const style::font &font, const QString &str, uint16 from, uint16 length, uchar flags, uint16 lnkIndex) : ITextBlock(font, str, from, length, flags, lnkIndex), _nextDir(Qt::LayoutDirectionAuto) { + NewlineBlock(const style::font &font, const QString &str, uint16 from, uint16 length, uchar flags, uint16 lnkIndex) : AbstractBlock(font, str, from, length, flags, lnkIndex), _nextDir(Qt::LayoutDirectionAuto) { _flags |= ((TextBlockTNewline & 0x0F) << 8); } @@ -94,17 +97,16 @@ public: return _nextDir; } - std::unique_ptr clone() const override { + std::unique_ptr clone() const override { return std::make_unique(*this); } private: Qt::LayoutDirection _nextDir; - friend class Text; - friend class TextParser; - - friend class TextPainter; + friend class String; + friend class Parser; + friend class Renderer; }; @@ -140,50 +142,48 @@ private: }; -class TextBlock : public ITextBlock { +class TextBlock : public AbstractBlock { public: TextBlock(const style::font &font, const QString &str, QFixed minResizeWidth, uint16 from, uint16 length, uchar flags, uint16 lnkIndex); - std::unique_ptr clone() const override { + std::unique_ptr clone() const override { return std::make_unique(*this); } private: - friend class ITextBlock; + friend class AbstractBlock; QFixed real_f_rbearing() const { return _words.isEmpty() ? 0 : _words.back().f_rbearing(); } - typedef QVector TextWords; + using TextWords = QVector; TextWords _words; - friend class Text; - friend class TextParser; - + friend class String; + friend class Parser; + friend class Renderer; friend class BlockParser; - friend class TextPainter; }; -class EmojiBlock : public ITextBlock { +class EmojiBlock : public AbstractBlock { public: EmojiBlock(const style::font &font, const QString &str, uint16 from, uint16 length, uchar flags, uint16 lnkIndex, EmojiPtr emoji); - std::unique_ptr clone() const { + std::unique_ptr clone() const override { return std::make_unique(*this); } private: EmojiPtr emoji = nullptr; - friend class Text; - friend class TextParser; - - friend class TextPainter; + friend class String; + friend class Parser; + friend class Renderer; }; -class SkipBlock : public ITextBlock { +class SkipBlock : public AbstractBlock { public: SkipBlock(const style::font &font, const QString &str, uint16 from, int32 w, int32 h, uint16 lnkIndex); @@ -191,16 +191,18 @@ public: return _height; } - std::unique_ptr clone() const override { + std::unique_ptr clone() const override { return std::make_unique(*this); } private: int32 _height; - friend class Text; - friend class TextParser; - - friend class TextPainter; + friend class String; + friend class Parser; + friend class Renderer; }; + +} // namespace Text +} // namespace Ui diff --git a/Telegram/SourceFiles/ui/text/text_utilities.cpp b/Telegram/SourceFiles/ui/text/text_utilities.cpp new file mode 100644 index 000000000..4ca4b040f --- /dev/null +++ b/Telegram/SourceFiles/ui/text/text_utilities.cpp @@ -0,0 +1,20 @@ +/* +This file is part of Telegram Desktop, +the official desktop application for the Telegram messaging service. + +For license and copyright information please follow this link: +https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL +*/ +#include "ui/text/text_utilities.h" + +namespace Ui { +namespace Text { + +TextWithEntities Bold(const QString &text) { + auto result = TextWithEntities{ text }; + result.entities.push_back({ EntityType::Bold, 0, text.size() }); + return result; +} + +} // namespace Text +} // namespace Ui diff --git a/Telegram/SourceFiles/ui/text/text_utilities.h b/Telegram/SourceFiles/ui/text/text_utilities.h new file mode 100644 index 000000000..b81197c73 --- /dev/null +++ b/Telegram/SourceFiles/ui/text/text_utilities.h @@ -0,0 +1,26 @@ +/* +This file is part of Telegram Desktop, +the official desktop application for the Telegram messaging service. + +For license and copyright information please follow this link: +https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL +*/ +#pragma once + +namespace Ui { +namespace Text { + +TextWithEntities Bold(const QString &text); + +inline auto ToBold() { + return rpl::map(Bold); +} + +inline auto ToUpper() { + return rpl::map([](QString &&text) { + return std::move(text).toUpper(); + }); +} + +} // namespace Text +} // namespace Ui diff --git a/Telegram/SourceFiles/ui/toast/toast_widget.h b/Telegram/SourceFiles/ui/toast/toast_widget.h index 29c8ec495..bc13db400 100644 --- a/Telegram/SourceFiles/ui/toast/toast_widget.h +++ b/Telegram/SourceFiles/ui/toast/toast_widget.h @@ -35,7 +35,7 @@ private: int _maxTextWidth = 0; int _textWidth = 0; - Text _text; + Text::String _text; }; diff --git a/Telegram/SourceFiles/ui/widgets/checkbox.h b/Telegram/SourceFiles/ui/widgets/checkbox.h index b470fd223..2216cd255 100644 --- a/Telegram/SourceFiles/ui/widgets/checkbox.h +++ b/Telegram/SourceFiles/ui/widgets/checkbox.h @@ -198,7 +198,7 @@ private: rpl::event_stream _checkedChanges; QPixmap _checkCache; - Text _text; + Text::String _text; style::align _checkAlignment = style::al_left; bool _allowMultiline = false; diff --git a/Telegram/SourceFiles/ui/widgets/labels.cpp b/Telegram/SourceFiles/ui/widgets/labels.cpp index 06006743e..4e4753f65 100644 --- a/Telegram/SourceFiles/ui/widgets/labels.cpp +++ b/Telegram/SourceFiles/ui/widgets/labels.cpp @@ -306,7 +306,7 @@ void FlatLabel::mousePressEvent(QMouseEvent *e) { dragActionStart(e->globalPos(), e->button()); } -Text::StateResult FlatLabel::dragActionStart(const QPoint &p, Qt::MouseButton button) { +Ui::Text::StateResult FlatLabel::dragActionStart(const QPoint &p, Qt::MouseButton button) { _lastMousePos = p; auto state = dragActionUpdate(); @@ -359,7 +359,7 @@ Text::StateResult FlatLabel::dragActionStart(const QPoint &p, Qt::MouseButton bu return state; } -Text::StateResult FlatLabel::dragActionFinish(const QPoint &p, Qt::MouseButton button) { +Ui::Text::StateResult FlatLabel::dragActionFinish(const QPoint &p, Qt::MouseButton button) { _lastMousePos = p; auto state = dragActionUpdate(); @@ -715,7 +715,7 @@ std::unique_ptr FlatLabel::CrossFade( return result; } -Text::StateResult FlatLabel::dragActionUpdate() { +Ui::Text::StateResult FlatLabel::dragActionUpdate() { auto m = mapFromGlobal(_lastMousePos); auto state = getTextState(m); updateHover(state); @@ -728,7 +728,7 @@ Text::StateResult FlatLabel::dragActionUpdate() { return state; } -void FlatLabel::updateHover(const Text::StateResult &state) { +void FlatLabel::updateHover(const Ui::Text::StateResult &state) { bool lnkChanged = ClickHandler::setActive(state.link, this); if (!_selectable) { @@ -791,15 +791,15 @@ void FlatLabel::refreshCursor(bool uponSymbol) { } } -Text::StateResult FlatLabel::getTextState(const QPoint &m) const { - Text::StateRequestElided request; +Ui::Text::StateResult FlatLabel::getTextState(const QPoint &m) const { + Ui::Text::StateRequestElided request; request.align = _st.align; if (_selectable) { - request.flags |= Text::StateRequest::Flag::LookupSymbol; + request.flags |= Ui::Text::StateRequest::Flag::LookupSymbol; } int textWidth = width() - _st.margin.left() - _st.margin.right(); - Text::StateResult state; + Ui::Text::StateResult state; bool heightExceeded = _st.maxHeight && (_st.maxHeight < _fullTextHeight || textWidth < _text.maxWidth()); bool renderElided = _breakEverywhere || heightExceeded; if (renderElided) { @@ -807,7 +807,7 @@ Text::StateResult FlatLabel::getTextState(const QPoint &m) const { auto lines = _st.maxHeight ? qMax(_st.maxHeight / lineHeight, 1) : ((height() / lineHeight) + 2); request.lines = lines; if (_breakEverywhere) { - request.flags |= Text::StateRequest::Flag::BreakEverywhere; + request.flags |= Ui::Text::StateRequest::Flag::BreakEverywhere; } state = _text.getStateElided(m - QPoint(_st.margin.left(), _st.margin.top()), textWidth, request); } else { diff --git a/Telegram/SourceFiles/ui/widgets/labels.h b/Telegram/SourceFiles/ui/widgets/labels.h index 691fcb8a6..18fce8a88 100644 --- a/Telegram/SourceFiles/ui/widgets/labels.h +++ b/Telegram/SourceFiles/ui/widgets/labels.h @@ -157,11 +157,11 @@ private: void init(); void textUpdated(); - Text::StateResult dragActionUpdate(); - Text::StateResult dragActionStart(const QPoint &p, Qt::MouseButton button); - Text::StateResult dragActionFinish(const QPoint &p, Qt::MouseButton button); - void updateHover(const Text::StateResult &state); - Text::StateResult getTextState(const QPoint &m) const; + Ui::Text::StateResult dragActionUpdate(); + Ui::Text::StateResult dragActionStart(const QPoint &p, Qt::MouseButton button); + Ui::Text::StateResult dragActionFinish(const QPoint &p, Qt::MouseButton button); + void updateHover(const Ui::Text::StateResult &state); + Ui::Text::StateResult getTextState(const QPoint &m) const; void refreshCursor(bool uponSymbol); int countTextWidth() const; @@ -174,7 +174,7 @@ private: }; void showContextMenu(QContextMenuEvent *e, ContextMenuReason reason); - Text _text; + Text::String _text; const style::FlatLabel &_st; std::optional _textColorOverride; float64 _opacity = 1.; diff --git a/Telegram/SourceFiles/ui/widgets/multi_select.h b/Telegram/SourceFiles/ui/widgets/multi_select.h index 4e5664524..d403f4919 100644 --- a/Telegram/SourceFiles/ui/widgets/multi_select.h +++ b/Telegram/SourceFiles/ui/widgets/multi_select.h @@ -230,7 +230,7 @@ private: int _x = -1; int _y = -1; int _width = 0; - Text _text; + Text::String _text; style::color _color; bool _over = false; QPixmap _cache; diff --git a/Telegram/SourceFiles/ui/widgets/tooltip.cpp b/Telegram/SourceFiles/ui/widgets/tooltip.cpp index 61dd7ab1e..7eecf01de 100644 --- a/Telegram/SourceFiles/ui/widgets/tooltip.cpp +++ b/Telegram/SourceFiles/ui/widgets/tooltip.cpp @@ -88,7 +88,7 @@ void Tooltip::popup(const QPoint &m, const QString &text, const style::Tooltip * _point = m; _st = st; - _text = Text(_st->textStyle, text, _textPlainOptions, _st->widthMax, true); + _text = Text::String(_st->textStyle, text, _textPlainOptions, _st->widthMax, true); _useTransparency = Platform::TranslucentWindowsSupported(_point); setAttribute(Qt::WA_OpaquePaintEvent, !_useTransparency); diff --git a/Telegram/SourceFiles/ui/widgets/tooltip.h b/Telegram/SourceFiles/ui/widgets/tooltip.h index be0146537..286d4cf49 100644 --- a/Telegram/SourceFiles/ui/widgets/tooltip.h +++ b/Telegram/SourceFiles/ui/widgets/tooltip.h @@ -51,7 +51,7 @@ private: const AbstractTooltipShower *_shower = nullptr; base::Timer _showTimer; - Text _text; + Text::String _text; QPoint _point; const style::Tooltip *_st = nullptr; diff --git a/Telegram/SourceFiles/window/layer_widget.h b/Telegram/SourceFiles/window/layer_widget.h index 422cc3453..0b1b82f40 100644 --- a/Telegram/SourceFiles/window/layer_widget.h +++ b/Telegram/SourceFiles/window/layer_widget.h @@ -245,8 +245,10 @@ private: }; -template +class GenericBox; + +template inline object_ptr Box(Args&&... args) { - auto parent = static_cast(nullptr); + const auto parent = static_cast(nullptr); return object_ptr(parent, std::forward(args)...); } diff --git a/Telegram/SourceFiles/window/notifications_manager_default.cpp b/Telegram/SourceFiles/window/notifications_manager_default.cpp index 824a350e1..368d1d930 100644 --- a/Telegram/SourceFiles/window/notifications_manager_default.cpp +++ b/Telegram/SourceFiles/window/notifications_manager_default.cpp @@ -684,7 +684,7 @@ void Notification::updateNotifyDisplay() { if (!options.hideMessageText) { const HistoryItem *textCachedFor = nullptr; - Text itemTextCache(itemWidth); + Ui::Text::String itemTextCache(itemWidth); QRect r(st::notifyPhotoPos.x() + st::notifyPhotoSize + st::notifyTextLeft, st::notifyItemTop + st::msgNameFont->height, itemWidth, 2 * st::dialogsTextFont->height); if (_item) { auto active = false, selected = false; diff --git a/Telegram/SourceFiles/window/themes/window_theme_editor_block.cpp b/Telegram/SourceFiles/window/themes/window_theme_editor_block.cpp index a4b1e0932..b9409ff68 100644 --- a/Telegram/SourceFiles/window/themes/window_theme_editor_block.cpp +++ b/Telegram/SourceFiles/window/themes/window_theme_editor_block.cpp @@ -45,7 +45,7 @@ public: QString description() const { return _description.toString(); } - const Text &descriptionText() const { + const Ui::Text::String &descriptionText() const { return _description; } void setDescription(const QString &description) { @@ -102,7 +102,7 @@ private: QString _copyOf; QColor _value; QString _valueString; - Text _description = { st::windowMinWidth / 2 }; + Ui::Text::String _description = { st::windowMinWidth / 2 }; OrderedSet _searchWords; OrderedSet _searchStartChars; diff --git a/Telegram/SourceFiles/window/themes/window_theme_preview.cpp b/Telegram/SourceFiles/window/themes/window_theme_preview.cpp index 25861a274..d09a17938 100644 --- a/Telegram/SourceFiles/window/themes/window_theme_preview.cpp +++ b/Telegram/SourceFiles/window/themes/window_theme_preview.cpp @@ -94,7 +94,7 @@ private: Received }; struct Row { - Text name; + Ui::Text::String name; QString letters; enum class Type { User, @@ -107,7 +107,7 @@ private: bool muted = false; bool pinned = false; QString date; - Text text; + Ui::Text::String text; Status status = Status::None; bool selected = false; bool active = false; @@ -120,15 +120,15 @@ private: QString date; bool attached = false; bool tail = true; - Text text = { st::msgMinWidth }; + Ui::Text::String text = { st::msgMinWidth }; QVector waveform; int waveactive = 0; QString wavestatus; QImage photo; int photoWidth = 0; int photoHeight = 0; - Text replyName = { st::msgMinWidth }; - Text replyText = { st::msgMinWidth }; + Ui::Text::String replyName = { st::msgMinWidth }; + Ui::Text::String replyText = { st::msgMinWidth }; }; void prepare(); @@ -177,7 +177,7 @@ private: int _rowsTop = 0; std::vector _rows; - Text _topBarName; + Ui::Text::String _topBarName; QString _topBarStatus; bool _topBarStatusActive = false; diff --git a/Telegram/SourceFiles/window/window_peer_menu.cpp b/Telegram/SourceFiles/window/window_peer_menu.cpp index 060198644..90ac604f7 100644 --- a/Telegram/SourceFiles/window/window_peer_menu.cpp +++ b/Telegram/SourceFiles/window/window_peer_menu.cpp @@ -12,10 +12,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "boxes/mute_settings_box.h" #include "boxes/add_contact_box.h" #include "boxes/report_box.h" +#include "boxes/generic_box.h" #include "boxes/create_poll_box.h" #include "boxes/peers/add_participants_box.h" #include "boxes/peers/add_to_contacts_box.h" #include "ui/toast/toast.h" +#include "ui/text/text_utilities.h" +#include "ui/widgets/labels.h" +#include "ui/widgets/checkbox.h" #include "auth_session.h" #include "apiwrap.h" #include "mainwidget.h" @@ -23,6 +27,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "observer_peer.h" #include "history/history.h" #include "window/window_session_controller.h" +#include "window/window_controller.h" #include "support/support_helper.h" #include "info/info_memento.h" #include "info/info_controller.h" @@ -248,9 +253,9 @@ void Filler::addTogglePin() { } void Filler::addInfo() { - auto controller = _controller; - auto peer = _peer; - auto infoKey = (peer->isChat() || peer->isMegagroup()) + const auto controller = _controller; + const auto peer = _peer; + const auto infoKey = (peer->isChat() || peer->isMegagroup()) ? lng_context_view_group : (peer->isUser() ? lng_context_view_profile @@ -324,7 +329,8 @@ void Filler::addToggleArchive() { } void Filler::addBlockUser(not_null user) { - auto blockText = [](not_null user) { + const auto window = &_controller->window()->controller(); + const auto blockText = [](not_null user) { return lang(user->isBlocked() ? ((user->isBot() && !user->isSupport()) ? lng_profile_restart_bot @@ -333,11 +339,13 @@ void Filler::addBlockUser(not_null user) { ? lng_profile_block_bot : lng_profile_block_user)); }; - auto blockAction = _addAction(blockText(user), [=] { + const auto blockAction = _addAction(blockText(user), [=] { if (user->isBlocked()) { - Auth().api().unblockUser(user); + user->session().api().unblockUser(user); + } else if (user->isBot()) { + user->session().api().blockUser(user); } else { - Auth().api().blockUser(user); + window->show(Box(PeerMenuBlockUserBox, user, window)); } }); @@ -696,6 +704,77 @@ void PeerMenuCreatePoll(not_null peer) { }, box->lifetime()); } +void PeerMenuBlockUserBox( + not_null box, + not_null user, + not_null window) { + using Flag = MTPDpeerSettings::Flag; + const auto settings = user->settings().value_or(Flag(0)); + + const auto name = user->shortName(); + + box->addRow(object_ptr( + box, + rpl::single( + lng_blocked_list_confirm_text__generic( + lt_name, + Ui::Text::Bold(name))), + st::blockUserConfirmation)); + + box->addSkip(st::boxMediumSkip); + + const auto report = (settings & Flag::f_report_spam) + ? box->addRow(object_ptr( + box, + lang(lng_report_spam), + true, + st::defaultBoxCheckbox)) + : nullptr; + + if (report) { + box->addSkip(st::boxMediumSkip); + } + + const auto clear = box->addRow(object_ptr( + box, + lang(lng_blocked_list_confirm_clear), + true, + st::defaultBoxCheckbox)); + + box->addSkip(st::boxLittleSkip); + + box->setTitle([=] { + return lng_blocked_list_confirm_title(lt_name, name); + }); + + box->addButton(langFactory(lng_blocked_list_confirm_ok), [=] { + const auto reportChecked = report && report->checked(); + const auto clearChecked = clear->checked(); + + box->closeBox(); + + user->session().api().blockUser(user); + if (reportChecked) { + user->session().api().request(MTPmessages_ReportSpam( + user->input + )).send(); + } + if (clearChecked) { + crl::on_main(&user->session(), [=] { + user->session().api().deleteConversation(user, false); + }); + window->sessionController()->showBackFromStack(); + } + + Ui::Toast::Show( + lng_new_contact_block_done(lt_user, user->shortName())); + }, st::attentionBoxButton); + + box->addButton(langFactory(lng_cancel), [=] { + box->closeBox(); + }); +} + QPointer ShowForwardMessagesBox( MessageIdsList &&items, FnMut &&successCallback) { diff --git a/Telegram/SourceFiles/window/window_peer_menu.h b/Telegram/SourceFiles/window/window_peer_menu.h index 39a5729e1..cf6fe0384 100644 --- a/Telegram/SourceFiles/window/window_peer_menu.h +++ b/Telegram/SourceFiles/window/window_peer_menu.h @@ -7,6 +7,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #pragma once +class GenericBox; + namespace Ui { class RpWidget; } // namespace Ui @@ -17,6 +19,7 @@ class Folder; namespace Window { +class Controller; class SessionController; enum class PeerMenuSource { @@ -51,6 +54,10 @@ void PeerMenuAddContact(not_null user); void PeerMenuAddChannelMembers(not_null channel); //void PeerMenuUngroupFeed(not_null feed); // #feed void PeerMenuCreatePoll(not_null peer); +void PeerMenuBlockUserBox( + not_null box, + not_null user, + not_null window); void ToggleHistoryArchived(not_null history, bool archived); Fn ClearHistoryHandler(not_null peer); diff --git a/Telegram/gyp/telegram_sources.txt b/Telegram/gyp/telegram_sources.txt index c4c5a53a4..7f13699b2 100644 --- a/Telegram/gyp/telegram_sources.txt +++ b/Telegram/gyp/telegram_sources.txt @@ -745,6 +745,8 @@ <(src_loc)/ui/text/text_block.h <(src_loc)/ui/text/text_entity.cpp <(src_loc)/ui/text/text_entity.h +<(src_loc)/ui/text/text_utilities.cpp +<(src_loc)/ui/text/text_utilities.h <(src_loc)/ui/toast/toast.cpp <(src_loc)/ui/toast/toast.h <(src_loc)/ui/toast/toast_manager.cpp