Rename Text to Ui::Text::String.

This commit is contained in:
John Preston 2019-06-12 15:26:04 +02:00
parent e9677779b8
commit 2162aa8df0
92 changed files with 615 additions and 531 deletions

View file

@ -1195,13 +1195,17 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_delete_all_from" = "Delete all from this user"; "lng_delete_all_from" = "Delete all from this user";
"lng_report_spam" = "Report Spam"; "lng_report_spam" = "Report Spam";
"lng_report_spam_and_leave" = "Report spam and leave"; "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_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_sure_channel" = "Are you sure you want to report spam in this channel?";
"lng_report_spam_ok" = "Report"; "lng_report_spam_ok" = "Report";
"lng_new_contact_block" = "Block user"; "lng_new_contact_block" = "Block user";
"lng_new_contact_block_done" = "{user} is now blocked.";
"lng_new_contact_add" = "Add contact"; "lng_new_contact_add" = "Add contact";
"lng_new_contact_share" = "Share my phone number"; "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_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_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_invite_not_contact" = "Sorry, you can only add mutual contacts\nto groups at the moment.\n{more_info}";
"lng_cant_more_info" = "More info »"; "lng_cant_more_info" = "More info »";

View file

@ -168,7 +168,7 @@ private:
} }
not_null<PeerData*> peer; not_null<PeerData*> peer;
Text name, status; Ui::Text::String name, status;
}; };
void paintChat(Painter &p, const ChatRow &row, bool selected) const; void paintChat(Painter &p, const ChatRow &row, bool selected) const;
void updateSelected(); void updateSelected();

View file

@ -169,7 +169,7 @@ private:
object_ptr<Ui::Radioenum<Privacy>> _public; object_ptr<Ui::Radioenum<Privacy>> _public;
object_ptr<Ui::Radioenum<Privacy>> _private; object_ptr<Ui::Radioenum<Privacy>> _private;
int32 _aboutPublicWidth, _aboutPublicHeight; int32 _aboutPublicWidth, _aboutPublicHeight;
Text _aboutPublic, _aboutPrivate; Ui::Text::String _aboutPublic, _aboutPrivate;
object_ptr<Ui::UsernameInput> _link; object_ptr<Ui::UsernameInput> _link;

View file

@ -67,7 +67,7 @@ private:
const style::RoundButton &_confirmStyle; const style::RoundButton &_confirmStyle;
bool _informative = false; bool _informative = false;
Text _text; Ui::Text::String _text;
int _textWidth = 0; int _textWidth = 0;
int _textHeight = 0; int _textHeight = 0;
int _maxLineCount = 16; int _maxLineCount = 16;
@ -109,7 +109,7 @@ private:
not_null<ChannelData*> _channel; not_null<ChannelData*> _channel;
Text _text; Ui::Text::String _text;
int32 _textWidth, _textHeight; int32 _textWidth, _textHeight;
QRect _invitationLink; QRect _invitationLink;

View file

@ -59,7 +59,7 @@ private:
View _view; View _view;
Text _title; Ui::Text::String _title;
object_ptr<Ui::IconButton> _menuToggle; object_ptr<Ui::IconButton> _menuToggle;
rpl::event_stream<> _deleteClicks; rpl::event_stream<> _deleteClicks;
rpl::event_stream<> _restoreClicks; rpl::event_stream<> _restoreClicks;

View file

@ -100,7 +100,7 @@ private:
int _thumbx = 0; int _thumbx = 0;
int _thumbw = 0; int _thumbw = 0;
int _thumbh = 0; int _thumbh = 0;
Text _name; Ui::Text::String _name;
QString _status; QString _status;
bool _isAudio = false; bool _isAudio = false;
bool _isImage = false; bool _isImage = false;

View file

@ -72,8 +72,8 @@ protected:
private: private:
struct Row { struct Row {
Language data; Language data;
Text title = { st::boxWideWidth / 2 }; Ui::Text::String title = { st::boxWideWidth / 2 };
Text description = { st::boxWideWidth / 2 }; Ui::Text::String description = { st::boxWideWidth / 2 };
int top = 0; int top = 0;
int height = 0; int height = 0;
mutable std::unique_ptr<Ui::RippleAnimation> ripple; mutable std::unique_ptr<Ui::RippleAnimation> ripple;

View file

@ -124,7 +124,7 @@ private:
int _aboutHeight = 0; int _aboutHeight = 0;
Text _about, _hintText; Ui::Text::String _about, _hintText;
object_ptr<Ui::PasswordInput> _oldPasscode; object_ptr<Ui::PasswordInput> _oldPasscode;
object_ptr<Ui::PasswordInput> _newPasscode; object_ptr<Ui::PasswordInput> _newPasscode;

View file

@ -100,7 +100,7 @@ public:
} }
void refreshName(const style::PeerListItem &st); void refreshName(const style::PeerListItem &st);
const Text &name() const { const Ui::Text::String &name() const {
return _name; return _name;
} }
@ -203,8 +203,8 @@ private:
not_null<PeerData*> _peer; not_null<PeerData*> _peer;
std::unique_ptr<Ui::RippleAnimation> _ripple; std::unique_ptr<Ui::RippleAnimation> _ripple;
std::unique_ptr<Ui::RoundImageCheckbox> _checkbox; std::unique_ptr<Ui::RoundImageCheckbox> _checkbox;
Text _name; Ui::Text::String _name;
Text _status; Ui::Text::String _status;
StatusType _statusType = StatusType::Online; StatusType _statusType = StatusType::Online;
crl::time _statusValidTill = 0; crl::time _statusValidTill = 0;
base::flat_set<QChar> _nameFirstLetters; base::flat_set<QChar> _nameFirstLetters;

View file

@ -12,9 +12,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/wrap/vertical_layout.h" #include "ui/wrap/vertical_layout.h"
#include "ui/widgets/labels.h" #include "ui/widgets/labels.h"
#include "ui/widgets/input_fields.h" #include "ui/widgets/input_fields.h"
#include "ui/text/text_utilities.h"
#include "info/profile/info_profile_cover.h" #include "info/profile/info_profile_cover.h"
#include "lang/lang_keys.h" #include "lang/lang_keys.h"
#include "window/window_controller.h" #include "window/window_controller.h"
#include "ui/toast/toast.h"
#include "auth_session.h" #include "auth_session.h"
#include "apiwrap.h" #include "apiwrap.h"
#include "styles/style_boxes.h" #include "styles/style_boxes.h"
@ -29,12 +31,6 @@ QString UserPhone(not_null<UserData*> user) {
: phone; : phone;
} }
TextWithEntities BoldText(const QString &text) {
auto result = TextWithEntities{ text };
result.entities.push_back({ EntityType::Bold, 0, text.size() });
return result;
}
} // namespace } // namespace
AddToContactsBox::AddToContactsBox( AddToContactsBox::AddToContactsBox(
@ -163,6 +159,7 @@ void AddToContactsBox::initNameFields(
if (box) { if (box) {
box->closeBox(); box->closeBox();
} }
Ui::Toast::Show(lng_new_contact_add_done(lt_user, firstValue));
}).fail([=](const RPCError &error) { }).fail([=](const RPCError &error) {
}).send(); }).send();
}; };
@ -170,21 +167,19 @@ void AddToContactsBox::initNameFields(
void AddToContactsBox::setupWarning( void AddToContactsBox::setupWarning(
not_null<Ui::VerticalLayout*> container) { not_null<Ui::VerticalLayout*> container) {
const auto name = _user->firstName.isEmpty() const auto name = _user->shortName();
? _user->lastName
: _user->firstName;
const auto nameWithEntities = TextWithEntities{ name }; const auto nameWithEntities = TextWithEntities{ name };
const auto text = _phone.isEmpty() const auto text = _phone.isEmpty()
? lng_contact_phone_after__generic<TextWithEntities>( ? lng_contact_phone_after__generic<TextWithEntities>(
lt_user, lt_user,
nameWithEntities, nameWithEntities,
lt_visible, lt_visible,
BoldText(lang(lng_contact_phone_visible)), Ui::Text::Bold(lang(lng_contact_phone_visible)),
lt_name, lt_name,
nameWithEntities) nameWithEntities)
: lng_contact_phone_show__generic<TextWithEntities>( : lng_contact_phone_show__generic<TextWithEntities>(
lt_button, lt_button,
BoldText(lang(lng_box_done).toUpper()), Ui::Text::Bold(lang(lng_box_done).toUpper()),
lt_user, lt_user,
TextWithEntities{ name }); TextWithEntities{ name });
container->add( container->add(

View file

@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_chat.h" #include "data/data_chat.h"
#include "ui/widgets/labels.h" #include "ui/widgets/labels.h"
#include "ui/wrap/vertical_layout.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_button.h"
#include "info/profile/info_profile_values.h" #include "info/profile/info_profile_values.h"
#include "boxes/peer_list_box.h" #include "boxes/peer_list_box.h"
@ -26,13 +27,6 @@ namespace {
constexpr auto kEnableSearchRowsCount = 10; 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 { class Controller : public PeerListController, public base::has_weak_ptr {
public: public:
Controller( Controller(
@ -127,9 +121,9 @@ void Controller::choose(not_null<ChannelData*> chat) {
TextWithEntities TextWithEntities
>( >(
lt_group, lt_group,
BoldText(chat->name), Ui::Text::Bold(chat->name),
lt_channel, lt_channel,
BoldText(_channel->name)); Ui::Text::Bold(_channel->name));
if (!_channel->isPublic()) { if (!_channel->isPublic()) {
text.append( text.append(
"\n\n" + lang(lng_manage_linked_channel_private)); "\n\n" + lang(lng_manage_linked_channel_private));
@ -140,7 +134,7 @@ void Controller::choose(not_null<ChannelData*> chat) {
text.append("\n\n"); text.append("\n\n");
text.append(lng_manage_discussion_group_warning__generic( text.append(lng_manage_discussion_group_warning__generic(
lt_visible, lt_visible,
BoldText(lang(lng_manage_discussion_group_visible)))); Ui::Text::Bold(lang(lng_manage_discussion_group_visible))));
} }
} }
const auto box = std::make_shared<QPointer<BoxContent>>(); const auto box = std::make_shared<QPointer<BoxContent>>();
@ -164,9 +158,9 @@ void Controller::choose(not_null<ChatData*> chat) {
TextWithEntities TextWithEntities
>( >(
lt_group, lt_group,
BoldText(chat->name), Ui::Text::Bold(chat->name),
lt_channel, lt_channel,
BoldText(_channel->name)); Ui::Text::Bold(_channel->name));
if (!_channel->isPublic()) { if (!_channel->isPublic()) {
text.append( text.append(
"\n\n" + lang(lng_manage_linked_channel_private)); "\n\n" + lang(lng_manage_linked_channel_private));
@ -175,7 +169,7 @@ void Controller::choose(not_null<ChatData*> chat) {
text.append("\n\n"); text.append("\n\n");
text.append(lng_manage_discussion_group_warning__generic( text.append(lng_manage_discussion_group_warning__generic(
lt_visible, lt_visible,
BoldText(lang(lng_manage_discussion_group_visible)))); Ui::Text::Bold(lang(lng_manage_discussion_group_visible))));
const auto box = std::make_shared<QPointer<BoxContent>>(); const auto box = std::make_shared<QPointer<BoxContent>>();
const auto sure = [=] { const auto sure = [=] {
if (*box) { if (*box) {
@ -208,11 +202,11 @@ object_ptr<Ui::RpWidget> SetupAbout(
if (!channel->isBroadcast()) { if (!channel->isBroadcast()) {
return lng_manage_linked_channel_about__generic< return lng_manage_linked_channel_about__generic<
TextWithEntities TextWithEntities
>(lt_channel, BoldText(chat->name)); >(lt_channel, Ui::Text::Bold(chat->name));
} else if (chat != nullptr) { } else if (chat != nullptr) {
return lng_manage_discussion_group_about_chosen__generic< return lng_manage_discussion_group_about_chosen__generic<
TextWithEntities TextWithEntities
>(lt_group, BoldText(chat->name)); >(lt_group, Ui::Text::Bold(chat->name));
} else { } else {
return { lang(lng_manage_discussion_group_about) }; return { lang(lng_manage_discussion_group_about) };
} }

View file

@ -50,7 +50,7 @@ private:
not_null<PeerData*> _peer; not_null<PeerData*> _peer;
not_null<UserData*> _user; not_null<UserData*> _user;
object_ptr<Ui::UserpicButton> _userPhoto; object_ptr<Ui::UserpicButton> _userPhoto;
Text _userName; Ui::Text::String _userName;
bool _hasAdminRights = false; bool _hasAdminRights = false;
object_ptr<Ui::VerticalLayout> _rows; object_ptr<Ui::VerticalLayout> _rows;

View file

@ -101,7 +101,7 @@ private:
void prepareThumb(const QImage &preview); void prepareThumb(const QImage &preview);
QPixmap _fileThumb; QPixmap _fileThumb;
Text _nameText; Ui::Text::String _nameText;
bool _fileIsAudio = false; bool _fileIsAudio = false;
bool _fileIsImage = false; bool _fileIsImage = false;
QString _statusText; QString _statusText;

View file

@ -85,7 +85,7 @@ private:
PeerData *peer; PeerData *peer;
Ui::RoundImageCheckbox checkbox; Ui::RoundImageCheckbox checkbox;
Text name; Ui::Text::String name;
Ui::Animations::Simple nameActive; Ui::Animations::Simple nameActive;
}; };

View file

@ -49,7 +49,7 @@ private:
mtpRequestId _checkRequestId = 0; mtpRequestId _checkRequestId = 0;
QString _sentUsername, _checkUsername, _errorText, _goodText; QString _sentUsername, _checkUsername, _errorText, _goodText;
Text _about; Ui::Text::String _about;
object_ptr<QTimer> _checkTimer; object_ptr<QTimer> _checkTimer;
}; };

View file

@ -268,7 +268,7 @@ private:
OverState _pressed; OverState _pressed;
QPoint _lastMousePosition; QPoint _lastMousePosition;
Text _megagroupSetAbout; Ui::Text::String _megagroupSetAbout;
QString _megagroupSetButtonText; QString _megagroupSetButtonText;
int _megagroupSetButtonTextWidth = 0; int _megagroupSetButtonTextWidth = 0;
QRect _megagroupSetButtonRect; QRect _megagroupSetButtonRect;

View file

@ -592,7 +592,7 @@ not_null<const PeerData*> PeerData::migrateToOrMe() const {
return this; return this;
} }
const Text &PeerData::topBarNameText() const { const Ui::Text::String &PeerData::topBarNameText() const {
if (const auto to = migrateTo()) { if (const auto to = migrateTo()) {
return to->topBarNameText(); return to->topBarNameText();
} else if (const auto user = asUser()) { } else if (const auto user = asUser()) {
@ -603,7 +603,7 @@ const Text &PeerData::topBarNameText() const {
return _nameText; return _nameText;
} }
const Text &PeerData::nameText() const { const Ui::Text::String &PeerData::nameText() const {
if (const auto to = migrateTo()) { if (const auto to = migrateTo()) {
return to->nameText(); return to->nameText();
} }
@ -611,7 +611,10 @@ const Text &PeerData::nameText() const {
} }
const QString &PeerData::shortName() 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 { QString PeerData::userName() const {

View file

@ -204,9 +204,9 @@ public:
return (_lastFullUpdate != 0); return (_lastFullUpdate != 0);
} }
[[nodiscard]] const Text &nameText() const; [[nodiscard]] const Ui::Text::String &nameText() const;
[[nodiscard]] const QString &shortName() const; [[nodiscard]] const QString &shortName() const;
[[nodiscard]] const Text &topBarNameText() const; [[nodiscard]] const Ui::Text::String &topBarNameText() const;
[[nodiscard]] QString userName() const; [[nodiscard]] QString userName() const;
[[nodiscard]] int32 bareId() const { [[nodiscard]] int32 bareId() const {
@ -359,7 +359,7 @@ private:
PhotoId _userpicPhotoId = kUnknownPhotoId; PhotoId _userpicPhotoId = kUnknownPhotoId;
mutable std::unique_ptr<Ui::EmptyUserpic> _userpicEmpty; mutable std::unique_ptr<Ui::EmptyUserpic> _userpicEmpty;
StorageImageLocation _userpicLocation; StorageImageLocation _userpicLocation;
Text _nameText; Ui::Text::String _nameText;
Data::NotifySettings _notify; Data::NotifySettings _notify;

View file

@ -33,13 +33,13 @@ BotCommand::BotCommand(
bool BotCommand::setDescription(const QString &description) { bool BotCommand::setDescription(const QString &description) {
if (_description != description) { if (_description != description) {
_description = description; _description = description;
_descriptionText = Text(); _descriptionText = Ui::Text::String();
return true; return true;
} }
return false; return false;
} }
const Text &BotCommand::descriptionText() const { const Ui::Text::String &BotCommand::descriptionText() const {
if (_descriptionText.isEmpty() && !_description.isEmpty()) { if (_descriptionText.isEmpty() && !_description.isEmpty()) {
_descriptionText.setText( _descriptionText.setText(
st::defaultTextStyle, st::defaultTextStyle,
@ -158,30 +158,31 @@ void UserData::setBotInfo(const MTPBotInfo &info) {
QString desc = qs(d.vdescription); QString desc = qs(d.vdescription);
if (botInfo->description != desc) { if (botInfo->description != desc) {
botInfo->description = desc; botInfo->description = desc;
botInfo->text = Text(st::msgMinWidth); botInfo->text = Ui::Text::String(st::msgMinWidth);
} }
auto &v = d.vcommands.v; auto &v = d.vcommands.v;
botInfo->commands.reserve(v.size()); botInfo->commands.reserve(v.size());
auto changedCommands = false; auto changedCommands = false;
int32 j = 0; int32 j = 0;
for (int32 i = 0, l = v.size(); i < l; ++i) { for (const auto &command : v) {
if (v.at(i).type() != mtpc_botCommand) continue; command.match([&](const MTPDbotCommand &data) {
const auto cmd = qs(data.vcommand);
QString cmd = qs(v.at(i).c_botCommand().vcommand), desc = qs(v.at(i).c_botCommand().vdescription); const auto desc = qs(data.vdescription);
if (botInfo->commands.size() <= j) { if (botInfo->commands.size() <= j) {
botInfo->commands.push_back(BotCommand(cmd, desc)); botInfo->commands.push_back(BotCommand(cmd, desc));
changedCommands = true;
} else {
if (botInfo->commands[j].command != cmd) {
botInfo->commands[j].command = cmd;
changedCommands = true; 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)) { ++j;
changedCommands = true; });
}
}
++j;
} }
while (j < botInfo->commands.size()) { while (j < botInfo->commands.size()) {
botInfo->commands.pop_back(); botInfo->commands.pop_back();

View file

@ -14,13 +14,13 @@ public:
BotCommand(const QString &command, const QString &description); BotCommand(const QString &command, const QString &description);
bool setDescription(const QString &description); bool setDescription(const QString &description);
const Text &descriptionText() const; const Ui::Text::String &descriptionText() const;
QString command; QString command;
private: private:
QString _description; QString _description;
mutable Text _descriptionText; mutable Ui::Text::String _descriptionText;
}; };
@ -31,7 +31,7 @@ struct BotInfo {
int version = 0; int version = 0;
QString description, inlinePlaceholder; QString description, inlinePlaceholder;
QList<BotCommand> commands; QList<BotCommand> commands;
Text text = Text{ int(st::msgMinWidth) }; // description Ui::Text::String text = { int(st::msgMinWidth) }; // description
QString startToken, startGroupToken, shareGameShortName; QString startToken, startGroupToken, shareGameShortName;
PeerId inlineReturnPeerId = 0; PeerId inlineReturnPeerId = 0;
@ -160,7 +160,7 @@ public:
return _phone; return _phone;
} }
QString nameOrPhone; QString nameOrPhone;
Text phoneText; Ui::Text::String phoneText;
TimeId onlineTill = 0; TimeId onlineTill = 0;
enum class ContactStatus : char { enum class ContactStatus : char {

View file

@ -169,7 +169,7 @@ public:
} }
mutable const HistoryItem *textCachedFor = nullptr; // cache mutable const HistoryItem *textCachedFor = nullptr; // cache
mutable Text lastItemTextCache; mutable Ui::Text::String lastItemTextCache;
protected: protected:
auto unreadStateChangeNotifier(bool required) { auto unreadStateChangeNotifier(bool required) {

View file

@ -802,7 +802,7 @@ void InnerWidget::paintSearchInFilter(
PaintUserpic paintUserpic, PaintUserpic paintUserpic,
int top, int top,
const style::icon *icon, const style::icon *icon,
const Text &text) const { const Ui::Text::String &text) const {
const auto savedPen = p.pen(); const auto savedPen = p.pen();
const auto userpicLeft = st::dialogsPadding.x(); const auto userpicLeft = st::dialogsPadding.x();
const auto userpicTop = top const auto userpicTop = top
@ -838,7 +838,7 @@ void InnerWidget::paintSearchInPeer(
Painter &p, Painter &p,
not_null<PeerData*> peer, not_null<PeerData*> peer,
int top, int top,
const Text &text) const { const Ui::Text::String &text) const {
const auto paintUserpic = [&](Painter &p, int x, int y, int size) { const auto paintUserpic = [&](Painter &p, int x, int y, int size) {
peer->paintUserpicLeft(p, x, y, width(), size); peer->paintUserpicLeft(p, x, y, width(), size);
}; };
@ -849,7 +849,7 @@ void InnerWidget::paintSearchInPeer(
void InnerWidget::paintSearchInSaved( void InnerWidget::paintSearchInSaved(
Painter &p, Painter &p,
int top, int top,
const Text &text) const { const Ui::Text::String &text) const {
const auto paintUserpic = [&](Painter &p, int x, int y, int size) { const auto paintUserpic = [&](Painter &p, int x, int y, int size) {
Ui::EmptyUserpic::PaintSavedMessages(p, x, y, width(), size); Ui::EmptyUserpic::PaintSavedMessages(p, x, y, width(), size);
}; };
@ -860,7 +860,7 @@ void InnerWidget::paintSearchInSaved(
// Painter &p, // Painter &p,
// not_null<Data::Feed*> feed, // not_null<Data::Feed*> feed,
// int top, // int top,
// const Text &text) const { // const Ui::Text::String &text) const {
// const auto paintUserpic = [&](Painter &p, int x, int y, int size) { // const auto paintUserpic = [&](Painter &p, int x, int y, int size) {
// feed->paintUserpicLeft(p, x, y, width(), size); // feed->paintUserpicLeft(p, x, y, width(), size);
// }; // };

View file

@ -267,23 +267,23 @@ private:
Painter &p, Painter &p,
not_null<PeerData*> peer, not_null<PeerData*> peer,
int top, int top,
const Text &text) const; const Ui::Text::String &text) const;
void paintSearchInSaved( void paintSearchInSaved(
Painter &p, Painter &p,
int top, int top,
const Text &text) const; const Ui::Text::String &text) const;
//void paintSearchInFeed( // #feed //void paintSearchInFeed( // #feed
// Painter &p, // Painter &p,
// not_null<Data::Feed*> feed, // not_null<Data::Feed*> feed,
// int top, // int top,
// const Text &text) const; // const Ui::Text::String &text) const;
template <typename PaintUserpic> template <typename PaintUserpic>
void paintSearchInFilter( void paintSearchInFilter(
Painter &p, Painter &p,
PaintUserpic paintUserpic, PaintUserpic paintUserpic,
int top, int top,
const style::icon *icon, const style::icon *icon,
const Text &text) const; const Ui::Text::String &text) const;
void refreshSearchInChatLabel(); void refreshSearchInChatLabel();
void clearSearchResults(bool clearPeerSearchResults = true); void clearSearchResults(bool clearPeerSearchResults = true);
@ -376,8 +376,8 @@ private:
Key _searchInChat; Key _searchInChat;
History *_searchInMigrated = nullptr; History *_searchInMigrated = nullptr;
UserData *_searchFromUser = nullptr; UserData *_searchFromUser = nullptr;
Text _searchInChatText; Ui::Text::String _searchInChatText;
Text _searchFromUserText; Ui::Text::String _searchFromUserText;
RowDescriptor _menuRow; RowDescriptor _menuRow;
Fn<void()> _loadMoreCallback; Fn<void()> _loadMoreCallback;

View file

@ -91,7 +91,7 @@ public:
uint64 sortKey() const; uint64 sortKey() const;
void validateListEntryCache() const; void validateListEntryCache() const;
const Text &listEntryCache() const { const Ui::Text::String &listEntryCache() const {
return _listEntryCache; return _listEntryCache;
} }
@ -104,7 +104,7 @@ private:
Key _id; Key _id;
int _pos = 0; int _pos = 0;
mutable uint32 _listEntryCacheVersion = 0; mutable uint32 _listEntryCacheVersion = 0;
mutable Text _listEntryCache; mutable Ui::Text::String _listEntryCache;
}; };
@ -125,7 +125,7 @@ private:
Key _searchInChat; Key _searchInChat;
not_null<HistoryItem*> _item; not_null<HistoryItem*> _item;
mutable const HistoryItem *_cacheFor = nullptr; mutable const HistoryItem *_cacheFor = nullptr;
mutable Text _cache; mutable Ui::Text::String _cache;
}; };

View file

@ -926,7 +926,7 @@ void InnerWidget::mouseDoubleClickEvent(QMouseEvent *e) {
mouseActionStart(e->globalPos(), e->button()); mouseActionStart(e->globalPos(), e->button());
if (((_mouseAction == MouseAction::Selecting && _selectedItem != nullptr) || (_mouseAction == MouseAction::None)) && _mouseSelectType == TextSelectType::Letters && _mouseActionItem) { if (((_mouseAction == MouseAction::Selecting && _selectedItem != nullptr) || (_mouseAction == MouseAction::None)) && _mouseSelectType == TextSelectType::Letters && _mouseActionItem) {
StateRequest request; StateRequest request;
request.flags |= Text::StateRequest::Flag::LookupSymbol; request.flags |= Ui::Text::StateRequest::Flag::LookupSymbol;
auto dragState = _mouseActionItem->textState(_dragStartPosition, request); auto dragState = _mouseActionItem->textState(_dragStartPosition, request);
if (dragState.cursor == CursorState::Text) { if (dragState.cursor == CursorState::Text) {
_mouseTextSymbol = dragState.symbol; _mouseTextSymbol = dragState.symbol;
@ -968,7 +968,7 @@ void InnerWidget::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
mapFromGlobal(_mousePosition), mapFromGlobal(_mousePosition),
App::mousedItem()); App::mousedItem());
StateRequest request; StateRequest request;
request.flags |= Text::StateRequest::Flag::LookupSymbol; request.flags |= Ui::Text::StateRequest::Flag::LookupSymbol;
auto dragState = App::mousedItem()->textState(mousePos, request); auto dragState = App::mousedItem()->textState(mousePos, request);
if (dragState.cursor == CursorState::Text if (dragState.cursor == CursorState::Text
&& base::in_range(dragState.symbol, selFrom, selTo)) { && base::in_range(dragState.symbol, selFrom, selTo)) {
@ -1308,7 +1308,7 @@ void InnerWidget::mouseActionStart(const QPoint &screenPos, Qt::MouseButton butt
TextState dragState; TextState dragState;
if (_trippleClickTimer.isActive() && (screenPos - _trippleClickPoint).manhattanLength() < QApplication::startDragDistance()) { if (_trippleClickTimer.isActive() && (screenPos - _trippleClickPoint).manhattanLength() < QApplication::startDragDistance()) {
StateRequest request; StateRequest request;
request.flags = Text::StateRequest::Flag::LookupSymbol; request.flags = Ui::Text::StateRequest::Flag::LookupSymbol;
dragState = _mouseActionItem->textState(_dragStartPosition, request); dragState = _mouseActionItem->textState(_dragStartPosition, request);
if (dragState.cursor == CursorState::Text) { if (dragState.cursor == CursorState::Text) {
auto selection = TextSelection { dragState.symbol, dragState.symbol }; auto selection = TextSelection { dragState.symbol, dragState.symbol };
@ -1322,7 +1322,7 @@ void InnerWidget::mouseActionStart(const QPoint &screenPos, Qt::MouseButton butt
} }
} else if (App::pressedItem()) { } else if (App::pressedItem()) {
StateRequest request; StateRequest request;
request.flags = Text::StateRequest::Flag::LookupSymbol; request.flags = Ui::Text::StateRequest::Flag::LookupSymbol;
dragState = _mouseActionItem->textState(_dragStartPosition, request); dragState = _mouseActionItem->textState(_dragStartPosition, request);
} }
if (_mouseSelectType != TextSelectType::Paragraphs) { if (_mouseSelectType != TextSelectType::Paragraphs) {
@ -1455,7 +1455,7 @@ void InnerWidget::updateSelected() {
} }
StateRequest request; StateRequest request;
if (_mouseAction == MouseAction::Selecting) { if (_mouseAction == MouseAction::Selecting) {
request.flags |= Text::StateRequest::Flag::LookupSymbol; request.flags |= Ui::Text::StateRequest::Flag::LookupSymbol;
} else { } else {
selectingText = false; selectingText = false;
} }
@ -1563,7 +1563,7 @@ void InnerWidget::performDrag() {
// uponSelected = _selected.contains(_mouseActionItem); // uponSelected = _selected.contains(_mouseActionItem);
// } else { // } else {
// StateRequest request; // StateRequest request;
// request.flags |= Text::StateRequest::Flag::LookupSymbol; // request.flags |= Ui::Text::StateRequest::Flag::LookupSymbol;
// auto dragState = _mouseActionItem->textState(_dragStartPosition.x(), _dragStartPosition.y(), request); // auto dragState = _mouseActionItem->textState(_dragStartPosition.x(), _dragStartPosition.y(), request);
// uponSelected = (dragState.cursor == CursorState::Text); // uponSelected = (dragState.cursor == CursorState::Text);
// if (uponSelected) { // if (uponSelected) {

View file

@ -240,7 +240,7 @@ private:
bool _upLoaded = true; bool _upLoaded = true;
bool _downLoaded = true; bool _downLoaded = true;
bool _filterChanged = false; bool _filterChanged = false;
Text _emptyText; Ui::Text::String _emptyText;
MouseAction _mouseAction = MouseAction::None; MouseAction _mouseAction = MouseAction::None;
TextSelectType _mouseSelectType = TextSelectType::Letters; TextSelectType _mouseSelectType = TextSelectType::Letters;

View file

@ -360,7 +360,7 @@ public:
mtpRequestId sendRequestId = 0; mtpRequestId sendRequestId = 0;
Text cloudDraftTextCache; Ui::Text::String cloudDraftTextCache;
private: private:
friend class HistoryBlock; friend class HistoryBlock;
@ -516,7 +516,7 @@ private:
base::flat_map<not_null<UserData*>, crl::time> _typing; base::flat_map<not_null<UserData*>, crl::time> _typing;
base::flat_map<not_null<UserData*>, SendAction> _sendActions; base::flat_map<not_null<UserData*>, SendAction> _sendActions;
QString _sendActionString; QString _sendActionString;
Text _sendActionText; Ui::Text::String _sendActionText;
Ui::SendActionAnimation _sendActionAnimation; Ui::SendActionAnimation _sendActionAnimation;
base::flat_map<SendAction::Type, crl::time> _mySendActions; base::flat_map<SendAction::Type, crl::time> _mySendActions;

View file

@ -1041,7 +1041,7 @@ void HistoryInner::mouseActionStart(const QPoint &screenPos, Qt::MouseButton but
TextState dragState; TextState dragState;
if (_trippleClickTimer.isActive() && (screenPos - _trippleClickPoint).manhattanLength() < QApplication::startDragDistance()) { if (_trippleClickTimer.isActive() && (screenPos - _trippleClickPoint).manhattanLength() < QApplication::startDragDistance()) {
StateRequest request; StateRequest request;
request.flags = Text::StateRequest::Flag::LookupSymbol; request.flags = Ui::Text::StateRequest::Flag::LookupSymbol;
dragState = mouseActionView->textState(_dragStartPosition, request); dragState = mouseActionView->textState(_dragStartPosition, request);
if (dragState.cursor == CursorState::Text) { if (dragState.cursor == CursorState::Text) {
TextSelection selStatus = { dragState.symbol, dragState.symbol }; TextSelection selStatus = { dragState.symbol, dragState.symbol };
@ -1060,7 +1060,7 @@ void HistoryInner::mouseActionStart(const QPoint &screenPos, Qt::MouseButton but
} }
} else if (App::pressedItem()) { } else if (App::pressedItem()) {
StateRequest request; StateRequest request;
request.flags = Text::StateRequest::Flag::LookupSymbol; request.flags = Ui::Text::StateRequest::Flag::LookupSymbol;
dragState = mouseActionView->textState(_dragStartPosition, request); dragState = mouseActionView->textState(_dragStartPosition, request);
} }
if (_mouseSelectType != TextSelectType::Paragraphs) { if (_mouseSelectType != TextSelectType::Paragraphs) {
@ -1144,7 +1144,7 @@ std::unique_ptr<QMimeData> HistoryInner::prepareDrag() {
&& (_selected.find(_dragStateItem) != _selected.cend()); && (_selected.find(_dragStateItem) != _selected.cend());
} else { } else {
StateRequest request; StateRequest request;
request.flags |= Text::StateRequest::Flag::LookupSymbol; request.flags |= Ui::Text::StateRequest::Flag::LookupSymbol;
auto dragState = mouseActionView->textState(_dragStartPosition, request); auto dragState = mouseActionView->textState(_dragStartPosition, request);
uponSelected = (dragState.cursor == CursorState::Text); uponSelected = (dragState.cursor == CursorState::Text);
if (uponSelected) { if (uponSelected) {
@ -1416,7 +1416,7 @@ void HistoryInner::mouseDoubleClickEvent(QMouseEvent *e) {
&& (_selected.empty() && (_selected.empty()
|| _selected.cbegin()->second != FullSelection)))) { || _selected.cbegin()->second != FullSelection)))) {
StateRequest request; StateRequest request;
request.flags |= Text::StateRequest::Flag::LookupSymbol; request.flags |= Ui::Text::StateRequest::Flag::LookupSymbol;
auto dragState = mouseActionView->textState(_dragStartPosition, request); auto dragState = mouseActionView->textState(_dragStartPosition, request);
if (dragState.cursor == CursorState::Text) { if (dragState.cursor == CursorState::Text) {
_mouseTextSymbol = dragState.symbol; _mouseTextSymbol = dragState.symbol;
@ -1478,7 +1478,7 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
if (App::mousedItem() && App::mousedItem() == App::hoveredItem()) { if (App::mousedItem() && App::mousedItem() == App::hoveredItem()) {
auto mousePos = mapPointToItem(mapFromGlobal(_mousePosition), App::mousedItem()); auto mousePos = mapPointToItem(mapFromGlobal(_mousePosition), App::mousedItem());
StateRequest request; StateRequest request;
request.flags |= Text::StateRequest::Flag::LookupSymbol; request.flags |= Ui::Text::StateRequest::Flag::LookupSymbol;
auto dragState = App::mousedItem()->textState(mousePos, request); auto dragState = App::mousedItem()->textState(mousePos, request);
if (dragState.cursor == CursorState::Text if (dragState.cursor == CursorState::Text
&& dragState.symbol >= selFrom && dragState.symbol >= selFrom
@ -2556,7 +2556,7 @@ void HistoryInner::mouseActionUpdate() {
if (!dragState.link) { if (!dragState.link) {
StateRequest request; StateRequest request;
if (_mouseAction == MouseAction::Selecting) { if (_mouseAction == MouseAction::Selecting) {
request.flags |= Text::StateRequest::Flag::LookupSymbol; request.flags |= Ui::Text::StateRequest::Flag::LookupSymbol;
} else { } else {
selectingText = false; selectingText = false;
} }
@ -3142,7 +3142,7 @@ QString HistoryInner::tooltipText() const {
StateRequest request; StateRequest request;
const auto local = mapFromGlobal(_mousePosition); const auto local = mapFromGlobal(_mousePosition);
const auto point = _widget->clampMousePosition(local); const auto point = _widget->clampMousePosition(local);
request.flags |= Text::StateRequest::Flag::LookupCustomTooltip; request.flags |= Ui::Text::StateRequest::Flag::LookupCustomTooltip;
const auto state = view->textState( const auto state = view->textState(
mapPointToItem(point, view), mapPointToItem(point, view),
request); request);

View file

@ -761,7 +761,7 @@ void HistoryItem::drawInDialog(
bool selected, bool selected,
DrawInDialog way, DrawInDialog way,
const HistoryItem *&cacheFor, const HistoryItem *&cacheFor,
Text &cache) const { Ui::Text::String &cache) const {
if (r.isEmpty()) { if (r.isEmpty()) {
return; return;
} }

View file

@ -236,7 +236,7 @@ public:
bool selected, bool selected,
DrawInDialog way, DrawInDialog way,
const HistoryItem *&cacheFor, const HistoryItem *&cacheFor,
Text &cache) const; Ui::Text::String &cache) const;
bool emptyText() const { bool emptyText() const {
return _text.isEmpty(); return _text.isEmpty();
@ -334,7 +334,7 @@ protected:
void setGroupId(MessageGroupId groupId); void setGroupId(MessageGroupId groupId);
Text _text = { st::msgMinWidth }; Ui::Text::String _text = { st::msgMinWidth };
int _textWidth = -1; int _textWidth = -1;
int _textHeight = 0; int _textHeight = 0;

View file

@ -41,7 +41,7 @@ struct HistoryMessageSigned : public RuntimeComponent<HistoryMessageSigned, Hist
bool isElided = false; bool isElided = false;
QString author; QString author;
Text signature; Ui::Text::String signature;
}; };
struct HistoryMessageEdited : public RuntimeComponent<HistoryMessageEdited, HistoryItem> { struct HistoryMessageEdited : public RuntimeComponent<HistoryMessageEdited, HistoryItem> {
@ -49,7 +49,7 @@ struct HistoryMessageEdited : public RuntimeComponent<HistoryMessageEdited, Hist
int maxWidth() const; int maxWidth() const;
TimeId date = 0; TimeId date = 0;
Text text; Ui::Text::String text;
}; };
struct HiddenSenderInfo { struct HiddenSenderInfo {
@ -60,7 +60,7 @@ struct HiddenSenderInfo {
QString lastName; QString lastName;
PeerId colorPeerId = 0; PeerId colorPeerId = 0;
Ui::EmptyUserpic userpic; Ui::EmptyUserpic userpic;
Text nameText; Ui::Text::String nameText;
inline bool operator==(const HiddenSenderInfo &other) const { inline bool operator==(const HiddenSenderInfo &other) const {
return name == other.name; return name == other.name;
@ -78,7 +78,7 @@ struct HistoryMessageForwarded : public RuntimeComponent<HistoryMessageForwarded
std::unique_ptr<HiddenSenderInfo> hiddenSenderInfo; std::unique_ptr<HiddenSenderInfo> hiddenSenderInfo;
QString originalAuthor; QString originalAuthor;
MsgId originalId = 0; MsgId originalId = 0;
mutable Text text = { 1 }; mutable Ui::Text::String text = { 1 };
PeerData *savedFromPeer = nullptr; PeerData *savedFromPeer = nullptr;
MsgId savedFromMsgId = 0; MsgId savedFromMsgId = 0;
@ -145,7 +145,7 @@ struct HistoryMessageReply : public RuntimeComponent<HistoryMessageReply, Histor
MsgId replyToMsgId = 0; MsgId replyToMsgId = 0;
HistoryItem *replyToMsg = nullptr; HistoryItem *replyToMsg = nullptr;
ClickHandlerPtr replyToLnk; ClickHandlerPtr replyToLnk;
mutable Text replyToName, replyToText; mutable Ui::Text::String replyToName, replyToText;
mutable int replyToVersion = 0; mutable int replyToVersion = 0;
mutable int maxReplyWidth = 0; mutable int maxReplyWidth = 0;
std::unique_ptr<HistoryMessageVia> replyToVia; std::unique_ptr<HistoryMessageVia> replyToVia;
@ -329,7 +329,7 @@ private:
Button &operator=(Button &&other); Button &operator=(Button &&other);
~Button(); ~Button();
Text text = { 1 }; Ui::Text::String text = { 1 };
QRect rect; QRect rect;
int characters = 0; int characters = 0;
float64 howMuchOver = 0.; float64 howMuchOver = 0.;
@ -388,7 +388,7 @@ struct HistoryDocumentThumbed : public RuntimeComponent<HistoryDocumentThumbed,
struct HistoryDocumentCaptioned : public RuntimeComponent<HistoryDocumentCaptioned, HistoryDocument> { struct HistoryDocumentCaptioned : public RuntimeComponent<HistoryDocumentCaptioned, HistoryDocument> {
HistoryDocumentCaptioned(); HistoryDocumentCaptioned();
Text _caption; Ui::Text::String _caption;
}; };
struct HistoryDocumentNamed : public RuntimeComponent<HistoryDocumentNamed, HistoryDocument> { struct HistoryDocumentNamed : public RuntimeComponent<HistoryDocumentNamed, HistoryDocument> {

View file

@ -486,17 +486,17 @@ private:
void handlePeerMigration(); void handlePeerMigration();
MsgId _replyToId = 0; MsgId _replyToId = 0;
Text _replyToName; Ui::Text::String _replyToName;
int _replyToNameVersion = 0; int _replyToNameVersion = 0;
HistoryItemsList _toForward; HistoryItemsList _toForward;
Text _toForwardFrom, _toForwardText; Ui::Text::String _toForwardFrom, _toForwardText;
int _toForwardNameVersion = 0; int _toForwardNameVersion = 0;
MsgId _editMsgId = 0; MsgId _editMsgId = 0;
HistoryItem *_replyEditMsg = nullptr; HistoryItem *_replyEditMsg = nullptr;
Text _replyEditMsgText; Ui::Text::String _replyEditMsgText;
mutable base::Timer _updateEditTimeLeftDisplay; mutable base::Timer _updateEditTimeLeftDisplay;
object_ptr<Ui::IconButton> _fieldBarCancel; object_ptr<Ui::IconButton> _fieldBarCancel;
@ -509,7 +509,7 @@ private:
MsgId msgId = 0; MsgId msgId = 0;
HistoryItem *msg = nullptr; HistoryItem *msg = nullptr;
Text text; Ui::Text::String text;
object_ptr<Ui::IconButton> cancel; object_ptr<Ui::IconButton> cancel;
object_ptr<Ui::PlainShadow> shadow; object_ptr<Ui::PlainShadow> shadow;
}; };
@ -554,8 +554,8 @@ private:
typedef QMap<QString, WebPageId> PreviewCache; typedef QMap<QString, WebPageId> PreviewCache;
PreviewCache _previewCache; PreviewCache _previewCache;
mtpRequestId _previewRequest = 0; mtpRequestId _previewRequest = 0;
Text _previewTitle; Ui::Text::String _previewTitle;
Text _previewDescription; Ui::Text::String _previewDescription;
base::Timer _previewTimer; base::Timer _previewTimer;
bool _previewCancelled = false; bool _previewCancelled = false;

View file

@ -37,14 +37,14 @@ QSize HistoryMedia::countCurrentSize(int newWidth) {
return QSize(qMin(newWidth, maxWidth()), minHeight()); return QSize(qMin(newWidth, maxWidth()), minHeight());
} }
Text HistoryMedia::createCaption(not_null<HistoryItem*> item) const { Ui::Text::String HistoryMedia::createCaption(not_null<HistoryItem*> item) const {
if (item->emptyText()) { if (item->emptyText()) {
return Text(); return {};
} }
const auto minResizeWidth = st::minPhotoSize const auto minResizeWidth = st::minPhotoSize
- st::msgPadding.left() - st::msgPadding.left()
- st::msgPadding.right(); - st::msgPadding.right();
auto result = Text(minResizeWidth); auto result = Ui::Text::String(minResizeWidth);
result.setMarkedText( result.setMarkedText(
st::messageTextStyle, st::messageTextStyle,
item->originalText(), item->originalText(),

View file

@ -236,7 +236,7 @@ protected:
using InfoDisplayType = HistoryView::InfoDisplayType; using InfoDisplayType = HistoryView::InfoDisplayType;
QSize countCurrentSize(int newWidth) override; QSize countCurrentSize(int newWidth) override;
Text createCaption(not_null<HistoryItem*> item) const; Ui::Text::String createCaption(not_null<HistoryItem*> item) const;
virtual void playAnimation(bool autoplay) { virtual void playAnimation(bool autoplay) {
} }

View file

@ -61,7 +61,7 @@ private:
int _phonew = 0; int _phonew = 0;
QString _fname, _lname, _phone; QString _fname, _lname, _phone;
Text _name; Ui::Text::String _name;
std::unique_ptr<Ui::EmptyUserpic> _photoEmpty; std::unique_ptr<Ui::EmptyUserpic> _photoEmpty;
ClickHandlerPtr _linkl; ClickHandlerPtr _linkl;

View file

@ -825,7 +825,7 @@ void HistoryDocument::refreshParentId(not_null<HistoryItem*> realParent) {
void HistoryDocument::parentTextUpdated() { void HistoryDocument::parentTextUpdated() {
auto caption = (_parent->media() == this) auto caption = (_parent->media() == this)
? createCaption(_parent->data()) ? createCaption(_parent->data())
: Text(); : Ui::Text::String();
if (!caption.isEmpty()) { if (!caption.isEmpty()) {
AddComponents(HistoryDocumentCaptioned::Bit()); AddComponents(HistoryDocumentCaptioned::Bit());
auto captioned = Get<HistoryDocumentCaptioned>(); auto captioned = Get<HistoryDocumentCaptioned>();

View file

@ -290,7 +290,7 @@ TextState HistoryGame::textState(QPoint point, StateRequest request) const {
auto lineHeight = unitedLineHeight(); auto lineHeight = unitedLineHeight();
if (_titleLines) { if (_titleLines) {
if (point.y() >= tshift && point.y() < tshift + _titleLines * lineHeight) { if (point.y() >= tshift && point.y() < tshift + _titleLines * lineHeight) {
Text::StateRequestElided titleRequest = request.forText(); Ui::Text::StateRequestElided titleRequest = request.forText();
titleRequest.lines = _titleLines; titleRequest.lines = _titleLines;
result = TextState(_parent, _title.getStateElidedLeft( result = TextState(_parent, _title.getStateElidedLeft(
point - QPoint(padding.left(), tshift), point - QPoint(padding.left(), tshift),
@ -304,7 +304,7 @@ TextState HistoryGame::textState(QPoint point, StateRequest request) const {
} }
if (_descriptionLines) { if (_descriptionLines) {
if (point.y() >= tshift && point.y() < tshift + _descriptionLines * lineHeight) { if (point.y() >= tshift && point.y() < tshift + _descriptionLines * lineHeight) {
Text::StateRequestElided descriptionRequest = request.forText(); Ui::Text::StateRequestElided descriptionRequest = request.forText();
descriptionRequest.lines = _descriptionLines; descriptionRequest.lines = _descriptionLines;
result = TextState(_parent, _description.getStateElidedLeft( result = TextState(_parent, _description.getStateElidedLeft(
point - QPoint(padding.left(), tshift), point - QPoint(padding.left(), tshift),
@ -420,7 +420,7 @@ void HistoryGame::parentTextUpdated() {
consumed, consumed,
Ui::ItemTextOptions(_parent->data())); Ui::ItemTextOptions(_parent->data()));
} else { } else {
_description = Text(st::msgMinWidth - st::webPageLeft); _description = Ui::Text::String(st::msgMinWidth - st::webPageLeft);
} }
history()->owner().requestViewResize(_parent); history()->owner().requestViewResize(_parent);
} }

View file

@ -93,7 +93,7 @@ private:
int _titleLines, _descriptionLines; int _titleLines, _descriptionLines;
Text _title, _description; Ui::Text::String _title, _description;
int _gameTagWidth = 0; int _gameTagWidth = 0;

View file

@ -63,7 +63,7 @@ HistoryGif::HistoryGif(
QSize HistoryGif::countOptimalSize() { QSize HistoryGif::countOptimalSize() {
if (_parent->media() != this) { if (_parent->media() != this) {
_caption = Text(); _caption = Ui::Text::String();
} else if (_caption.hasSkipBlock()) { } else if (_caption.hasSkipBlock()) {
_caption.updateSkipBlock( _caption.updateSkipBlock(
_parent->skipBlockWidth(), _parent->skipBlockWidth(),
@ -596,7 +596,7 @@ TextState HistoryGif::textState(QPoint point, StateRequest request) const {
auto breakEverywhere = (forwardedHeightReal > forwardedHeight); auto breakEverywhere = (forwardedHeightReal > forwardedHeight);
auto textRequest = request.forText(); auto textRequest = request.forText();
if (breakEverywhere) { if (breakEverywhere) {
textRequest.flags |= Text::StateRequest::Flag::BreakEverywhere; textRequest.flags |= Ui::Text::StateRequest::Flag::BreakEverywhere;
} }
result = TextState(_parent, forwarded->text.getState( result = TextState(_parent, forwarded->text.getState(
point - QPoint(rectx + st::msgReplyPadding.left(), recty + st::msgReplyPadding.top()), point - QPoint(rectx + st::msgReplyPadding.left(), recty + st::msgReplyPadding.top()),
@ -785,7 +785,7 @@ bool HistoryGif::isReadyForOpen() const {
void HistoryGif::parentTextUpdated() { void HistoryGif::parentTextUpdated() {
_caption = (_parent->media() == this) _caption = (_parent->media() == this)
? createCaption(_parent->data()) ? createCaption(_parent->data())
: Text(); : Ui::Text::String();
history()->owner().requestViewResize(_parent); history()->owner().requestViewResize(_parent);
} }

View file

@ -106,7 +106,7 @@ private:
not_null<DocumentData*> _data; not_null<DocumentData*> _data;
int _thumbw = 1; int _thumbw = 1;
int _thumbh = 1; int _thumbh = 1;
Text _caption; Ui::Text::String _caption;
Media::Clip::ReaderPointer _gif; Media::Clip::ReaderPointer _gif;
void setStatusSize(int newSize) const; void setStatusSize(int newSize) const;

View file

@ -119,7 +119,7 @@ private:
QPoint point, QPoint point,
StateRequest request) const; StateRequest request) const;
Text _caption; Ui::Text::String _caption;
std::vector<Part> _parts; std::vector<Part> _parts;
bool _needBubble = false; bool _needBubble = false;

View file

@ -296,7 +296,7 @@ TextState HistoryInvoice::textState(QPoint point, StateRequest request) const {
auto symbolAdd = 0; auto symbolAdd = 0;
if (_titleHeight) { if (_titleHeight) {
if (point.y() >= tshift && point.y() < tshift + _titleHeight) { if (point.y() >= tshift && point.y() < tshift + _titleHeight) {
Text::StateRequestElided titleRequest = request.forText(); Ui::Text::StateRequestElided titleRequest = request.forText();
titleRequest.lines = _titleHeight / lineHeight; titleRequest.lines = _titleHeight / lineHeight;
result = TextState(_parent, _title.getStateElidedLeft( result = TextState(_parent, _title.getStateElidedLeft(
point - QPoint(padding.left(), tshift), point - QPoint(padding.left(), tshift),

View file

@ -83,9 +83,9 @@ private:
int _titleHeight = 0; int _titleHeight = 0;
int _descriptionHeight = 0; int _descriptionHeight = 0;
Text _title; Ui::Text::String _title;
Text _description; Ui::Text::String _description;
Text _status; Ui::Text::String _status;
MsgId _receiptMsgId = 0; MsgId _receiptMsgId = 0;

View file

@ -59,7 +59,7 @@ private:
TextSelection fromDescriptionSelection(TextSelection selection) const; TextSelection fromDescriptionSelection(TextSelection selection) const;
LocationData *_data; LocationData *_data;
Text _title, _description; Ui::Text::String _title, _description;
ClickHandlerPtr _link; ClickHandlerPtr _link;
int fullWidth() const; int fullWidth() const;

View file

@ -63,7 +63,7 @@ void HistoryPhoto::create(FullMsgId contextId, PeerData *chat) {
QSize HistoryPhoto::countOptimalSize() { QSize HistoryPhoto::countOptimalSize() {
if (_parent->media() != this) { if (_parent->media() != this) {
_caption = Text(); _caption = Ui::Text::String();
} else if (_caption.hasSkipBlock()) { } else if (_caption.hasSkipBlock()) {
_caption.updateSkipBlock( _caption.updateSkipBlock(
_parent->skipBlockWidth(), _parent->skipBlockWidth(),
@ -560,6 +560,6 @@ bool HistoryPhoto::isReadyForOpen() const {
void HistoryPhoto::parentTextUpdated() { void HistoryPhoto::parentTextUpdated() {
_caption = (_parent->media() == this) _caption = (_parent->media() == this)
? createCaption(_parent->data()) ? createCaption(_parent->data())
: Text(); : Ui::Text::String();
history()->owner().requestViewResize(_parent); history()->owner().requestViewResize(_parent);
} }

View file

@ -93,6 +93,6 @@ private:
int _serviceWidth = 0; int _serviceWidth = 0;
int _pixw = 1; int _pixw = 1;
int _pixh = 1; int _pixh = 1;
Text _caption; Ui::Text::String _caption;
}; };

View file

@ -131,7 +131,7 @@ struct HistoryPoll::Answer {
void fillText(const PollAnswer &original); void fillText(const PollAnswer &original);
Text text; Ui::Text::String text;
QByteArray option; QByteArray option;
int votes = 0; int votes = 0;
int votesPercent = 0; int votesPercent = 0;
@ -807,7 +807,7 @@ TextState HistoryPoll::textState(QPoint point, StateRequest request) const {
result.link = answer.handler; result.link = answer.handler;
} else { } else {
result.customTooltip = true; result.customTooltip = true;
using Flag = Text::StateRequest::Flag; using Flag = Ui::Text::StateRequest::Flag;
if (request.flags & Flag::LookupCustomTooltip) { if (request.flags & Flag::LookupCustomTooltip) {
result.customTooltipText = answer.votes result.customTooltipText = answer.votes
? lng_polls_votes_count(lt_count_decimal, answer.votes) ? lng_polls_votes_count(lt_count_decimal, answer.votes)

View file

@ -118,10 +118,10 @@ private:
bool _voted = false; bool _voted = false;
bool _closed = false; bool _closed = false;
Text _question; Ui::Text::String _question;
Text _subtitle; Ui::Text::String _subtitle;
std::vector<Answer> _answers; std::vector<Answer> _answers;
Text _totalVotesLabel; Ui::Text::String _totalVotesLabel;
mutable std::unique_ptr<AnswersAnimation> _answersAnimation; mutable std::unique_ptr<AnswersAnimation> _answersAnimation;
mutable std::unique_ptr<SendingAnimation> _sendingAnimation; mutable std::unique_ptr<SendingAnimation> _sendingAnimation;

View file

@ -88,7 +88,7 @@ QSize HistoryVideo::countOptimalDimensions() const {
QSize HistoryVideo::countOptimalSize() { QSize HistoryVideo::countOptimalSize() {
if (_parent->media() != this) { if (_parent->media() != this) {
_caption = Text(); _caption = Ui::Text::String();
} else if (_caption.hasSkipBlock()) { } else if (_caption.hasSkipBlock()) {
_caption.updateSkipBlock( _caption.updateSkipBlock(
_parent->skipBlockWidth(), _parent->skipBlockWidth(),
@ -598,7 +598,7 @@ bool HistoryVideo::needsBubble() const {
void HistoryVideo::parentTextUpdated() { void HistoryVideo::parentTextUpdated() {
_caption = (_parent->media() == this) _caption = (_parent->media() == this)
? createCaption(_parent->data()) ? createCaption(_parent->data())
: Text(); : Ui::Text::String();
history()->owner().requestViewResize(_parent); history()->owner().requestViewResize(_parent);
} }

View file

@ -95,7 +95,7 @@ private:
not_null<DocumentData*> _data; not_null<DocumentData*> _data;
int _thumbw = 1; int _thumbw = 1;
int _thumbh = 1; int _thumbh = 1;
Text _caption; Ui::Text::String _caption;
QString _downloadSize; QString _downloadSize;

View file

@ -93,8 +93,8 @@ QSize HistoryWebPage::countOptimalSize() {
_openl = nullptr; _openl = nullptr;
_attach = nullptr; _attach = nullptr;
_collage = PrepareCollageMedia(_parent->data(), _data->collage); _collage = PrepareCollageMedia(_parent->data(), _data->collage);
_title = Text(st::msgMinWidth - st::webPageLeft); _title = Ui::Text::String(st::msgMinWidth - st::webPageLeft);
_description = Text(st::msgMinWidth - st::webPageLeft); _description = Ui::Text::String(st::msgMinWidth - st::webPageLeft);
_siteNameWidth = 0; _siteNameWidth = 0;
} }
auto lineHeight = unitedLineHeight(); auto lineHeight = unitedLineHeight();
@ -191,7 +191,7 @@ QSize HistoryWebPage::countOptimalSize() {
} }
if (isLogEntryOriginal()) { if (isLogEntryOriginal()) {
// Fix layout for small bubbles (narrow media caption edit log entries). // 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.left()
- st::msgPadding.right() - st::msgPadding.right()
- st::webPageLeft); - st::webPageLeft);
@ -561,7 +561,7 @@ TextState HistoryWebPage::textState(QPoint point, StateRequest request) const {
} }
if (_titleLines) { if (_titleLines) {
if (point.y() >= tshift && point.y() < tshift + _titleLines * lineHeight) { if (point.y() >= tshift && point.y() < tshift + _titleLines * lineHeight) {
Text::StateRequestElided titleRequest = request.forText(); Ui::Text::StateRequestElided titleRequest = request.forText();
titleRequest.lines = _titleLines; titleRequest.lines = _titleLines;
result = TextState(_parent, _title.getStateElidedLeft( result = TextState(_parent, _title.getStateElidedLeft(
point - QPoint(padding.left(), tshift), 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); auto descriptionHeight = (_descriptionLines > 0) ? _descriptionLines * lineHeight : _description.countHeight(paintw);
if (point.y() >= tshift && point.y() < tshift + descriptionHeight) { if (point.y() >= tshift && point.y() < tshift + descriptionHeight) {
if (_descriptionLines > 0) { if (_descriptionLines > 0) {
Text::StateRequestElided descriptionRequest = request.forText(); Ui::Text::StateRequestElided descriptionRequest = request.forText();
descriptionRequest.lines = _descriptionLines; descriptionRequest.lines = _descriptionLines;
result = TextState(_parent, _description.getStateElidedLeft( result = TextState(_parent, _description.getStateElidedLeft(
point - QPoint(padding.left(), tshift), point - QPoint(padding.left(), tshift),

View file

@ -107,7 +107,7 @@ private:
int _titleLines = 0; int _titleLines = 0;
int _descriptionLines = 0; int _descriptionLines = 0;
Text _title, _description; Ui::Text::String _title, _description;
int _siteNameWidth = 0; int _siteNameWidth = 0;
QString _duration; QString _duration;

View file

@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/widgets/buttons.h" #include "ui/widgets/buttons.h"
#include "ui/widgets/checkbox.h" #include "ui/widgets/checkbox.h"
#include "ui/widgets/labels.h" #include "ui/widgets/labels.h"
#include "ui/toast/toast.h"
#include "data/data_peer.h" #include "data/data_peer.h"
#include "data/data_user.h" #include "data/data_user.h"
#include "data/data_chat.h" #include "data/data_chat.h"
@ -28,13 +29,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
namespace HistoryView { namespace HistoryView {
namespace { namespace {
QString PeerFirstName(not_null<PeerData*> peer) {
if (const auto user = peer->asUser()) {
return user->firstName;
}
return QString();
}
bool BarCurrentlyHidden(not_null<PeerData*> peer) { bool BarCurrentlyHidden(not_null<PeerData*> peer) {
const auto settings = peer->settings(); const auto settings = peer->settings();
if (!settings) { if (!settings) {
@ -60,82 +54,6 @@ auto MapToEmpty() {
return rpl::map([] { return rpl::empty_value(); }); 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<GenericBox*> box,
not_null<UserData*> user,
not_null<Window::Controller*> 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<Ui::FlatLabel>(
box,
rpl::single(
lng_blocked_list_confirm_text__generic<TextWithEntities>(
lt_name,
BoldText(name))),
st::blockUserConfirmation));
box->addSkip(st::boxMediumSkip);
const auto report = (settings & Flag::f_report_spam)
? box->addRow(object_ptr<Ui::Checkbox>(
box,
lang(lng_report_spam),
true,
st::defaultBoxCheckbox))
: nullptr;
if (report) {
box->addSkip(st::boxMediumSkip);
}
const auto clear = box->addRow(object_ptr<Ui::Checkbox>(
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 } // namespace
ContactStatus::Bar::Bar(QWidget *parent, const QString &name) ContactStatus::Bar::Bar(QWidget *parent, const QString &name)
@ -265,7 +183,7 @@ ContactStatus::ContactStatus(
not_null<Ui::RpWidget*> parent, not_null<Ui::RpWidget*> parent,
not_null<PeerData*> peer) not_null<PeerData*> peer)
: _window(window) : _window(window)
, _bar(parent, object_ptr<Bar>(parent, PeerFirstName(peer))) , _bar(parent, object_ptr<Bar>(parent, peer->shortName()))
, _shadow(parent) { , _shadow(parent) {
setupWidgets(parent); setupWidgets(parent);
setupState(peer); setupState(peer);
@ -382,7 +300,7 @@ void ContactStatus::setupAddHandler(not_null<UserData*> user) {
void ContactStatus::setupBlockHandler(not_null<UserData*> user) { void ContactStatus::setupBlockHandler(not_null<UserData*> user) {
_bar.entity()->blockClicks( _bar.entity()->blockClicks(
) | rpl::start_with_next([=] { ) | rpl::start_with_next([=] {
_window->show(Box<GenericBox>(BlockUserBox, user, _window)); _window->show(Box(Window::PeerMenuBlockUserBox, user, _window));
}, _bar.lifetime()); }, _bar.lifetime());
} }
@ -394,6 +312,9 @@ void ContactStatus::setupShareHandler(not_null<UserData*> user) {
user->inputUser user->inputUser
)).done([=](const MTPUpdates &result) { )).done([=](const MTPUpdates &result) {
user->session().api().applyUpdates(result); user->session().api().applyUpdates(result);
Ui::Toast::Show(
lng_new_contact_share_done(lt_user, user->shortName()));
}).send(); }).send();
}, _bar.lifetime()); }, _bar.lifetime());
} }
@ -420,6 +341,8 @@ void ContactStatus::setupReportHandler(not_null<PeerData*> peer) {
peer->session().api().deleteConversation(peer, false); peer->session().api().deleteConversation(peer, false);
}); });
Ui::Toast::Show(lang(lng_report_spam_done));
// Destroys _bar. // Destroys _bar.
_window->sessionController()->showBackFromStack(); _window->sessionController()->showBackFromStack();
}); });

View file

@ -18,7 +18,7 @@ TextState::TextState(not_null<const HistoryItem*> item)
TextState::TextState( TextState::TextState(
not_null<const HistoryItem*> item, not_null<const HistoryItem*> item,
const Text::StateResult &state) const Ui::Text::StateResult &state)
: itemId(item->fullId()) : itemId(item->fullId())
, cursor(state.uponSymbol , cursor(state.uponSymbol
? CursorState::Text ? CursorState::Text
@ -42,7 +42,7 @@ TextState::TextState(
TextState::TextState( TextState::TextState(
not_null<const HistoryView::Element*> view, not_null<const HistoryView::Element*> view,
const Text::StateResult &state) const Ui::Text::StateResult &state)
: TextState(view->data(), state) { : TextState(view->data(), state) {
} }
@ -54,7 +54,7 @@ TextState::TextState(
TextState::TextState( TextState::TextState(
std::nullptr_t, std::nullptr_t,
const Text::StateResult &state) const Ui::Text::StateResult &state)
: cursor(state.uponSymbol : cursor(state.uponSymbol
? CursorState::Text ? CursorState::Text
: CursorState::None) : CursorState::None)

View file

@ -30,20 +30,20 @@ struct TextState {
TextState(not_null<const HistoryItem*> item); TextState(not_null<const HistoryItem*> item);
TextState( TextState(
not_null<const HistoryItem*> item, not_null<const HistoryItem*> item,
const Text::StateResult &state); const Ui::Text::StateResult &state);
TextState( TextState(
not_null<const HistoryItem*> item, not_null<const HistoryItem*> item,
ClickHandlerPtr link); ClickHandlerPtr link);
TextState(not_null<const HistoryView::Element*> view); TextState(not_null<const HistoryView::Element*> view);
TextState( TextState(
not_null<const HistoryView::Element*> view, not_null<const HistoryView::Element*> view,
const Text::StateResult &state); const Ui::Text::StateResult &state);
TextState( TextState(
not_null<const HistoryView::Element*> view, not_null<const HistoryView::Element*> view,
ClickHandlerPtr link); ClickHandlerPtr link);
TextState( TextState(
std::nullptr_t, std::nullptr_t,
const Text::StateResult &state); const Ui::Text::StateResult &state);
TextState(std::nullptr_t, ClickHandlerPtr link); TextState(std::nullptr_t, ClickHandlerPtr link);
FullMsgId itemId; FullMsgId itemId;
@ -57,9 +57,9 @@ struct TextState {
}; };
struct StateRequest { struct StateRequest {
Text::StateRequest::Flags flags = Text::StateRequest::Flag::LookupLink; Ui::Text::StateRequest::Flags flags = Ui::Text::StateRequest::Flag::LookupLink;
Text::StateRequest forText() const { Ui::Text::StateRequest forText() const {
Text::StateRequest result; Ui::Text::StateRequest result;
result.flags = flags; result.flags = flags;
return result; return result;
} }

View file

@ -102,13 +102,13 @@ TextSelection ShiftItemSelection(
TextSelection UnshiftItemSelection( TextSelection UnshiftItemSelection(
TextSelection selection, TextSelection selection,
const Text &byText) { const Ui::Text::String &byText) {
return UnshiftItemSelection(selection, byText.length()); return UnshiftItemSelection(selection, byText.length());
} }
TextSelection ShiftItemSelection( TextSelection ShiftItemSelection(
TextSelection selection, TextSelection selection,
const Text &byText) { const Ui::Text::String &byText) {
return ShiftItemSelection(selection, byText.length()); return ShiftItemSelection(selection, byText.length());
} }

View file

@ -79,10 +79,10 @@ TextSelection ShiftItemSelection(
uint16 byLength); uint16 byLength);
TextSelection UnshiftItemSelection( TextSelection UnshiftItemSelection(
TextSelection selection, TextSelection selection,
const Text &byText); const Ui::Text::String &byText);
TextSelection ShiftItemSelection( TextSelection ShiftItemSelection(
TextSelection selection, TextSelection selection,
const Text &byText); const Ui::Text::String &byText);
// Any HistoryView::Element can have this Component for // Any HistoryView::Element can have this Component for
// displaying the unread messages bar above the message. // displaying the unread messages bar above the message.

View file

@ -857,7 +857,7 @@ bool ListWidget::isInsideSelection(
&& _selectedTextItem == view->data() && _selectedTextItem == view->data()
&& state.pointState != PointState::Outside) { && state.pointState != PointState::Outside) {
StateRequest stateRequest; StateRequest stateRequest;
stateRequest.flags |= Text::StateRequest::Flag::LookupSymbol; stateRequest.flags |= Ui::Text::StateRequest::Flag::LookupSymbol;
const auto dragState = view->textState( const auto dragState = view->textState(
state.point, state.point,
stateRequest); stateRequest);
@ -1569,7 +1569,7 @@ void ListWidget::switchToWordSelection() {
Expects(_overElement != nullptr); Expects(_overElement != nullptr);
StateRequest request; StateRequest request;
request.flags |= Text::StateRequest::Flag::LookupSymbol; request.flags |= Ui::Text::StateRequest::Flag::LookupSymbol;
auto dragState = _overElement->textState(_pressState.point, request); auto dragState = _overElement->textState(_pressState.point, request);
if (dragState.cursor != CursorState::Text) { if (dragState.cursor != CursorState::Text) {
return; return;
@ -1900,7 +1900,7 @@ void ListWidget::mouseActionStart(
auto validStartPoint = startDistance < QApplication::startDragDistance(); auto validStartPoint = startDistance < QApplication::startDragDistance();
if (_trippleClickStartTime != 0 && validStartPoint) { if (_trippleClickStartTime != 0 && validStartPoint) {
StateRequest request; StateRequest request;
request.flags = Text::StateRequest::Flag::LookupSymbol; request.flags = Ui::Text::StateRequest::Flag::LookupSymbol;
dragState = pressElement->textState(_pressState.point, request); dragState = pressElement->textState(_pressState.point, request);
if (dragState.cursor == CursorState::Text) { if (dragState.cursor == CursorState::Text) {
setTextSelection(pressElement, TextSelection( setTextSelection(pressElement, TextSelection(
@ -1915,7 +1915,7 @@ void ListWidget::mouseActionStart(
} }
} else if (pressElement) { } else if (pressElement) {
StateRequest request; StateRequest request;
request.flags = Text::StateRequest::Flag::LookupSymbol; request.flags = Ui::Text::StateRequest::Flag::LookupSymbol;
dragState = pressElement->textState(_pressState.point, request); dragState = pressElement->textState(_pressState.point, request);
} }
if (_mouseSelectType != TextSelectType::Paragraphs) { if (_mouseSelectType != TextSelectType::Paragraphs) {
@ -2096,7 +2096,7 @@ void ListWidget::mouseActionUpdate() {
} }
StateRequest request; StateRequest request;
if (_mouseAction == MouseAction::Selecting) { if (_mouseAction == MouseAction::Selecting) {
request.flags |= Text::StateRequest::Flag::LookupSymbol; request.flags |= Ui::Text::StateRequest::Flag::LookupSymbol;
} else { } else {
inTextSelection = false; inTextSelection = false;
} }

View file

@ -544,7 +544,7 @@ void Message::paintFromName(
} }
p.setFont(st::msgNameFont); p.setFont(st::msgNameFont);
const auto nameText = [&]() -> const Text* { const auto nameText = [&]() -> const Ui::Text::String * {
const auto from = item->displayFrom(); const auto from = item->displayFrom();
if (item->isPost()) { if (item->isPost()) {
p.setPen(selected ? st::msgInServiceFgSelected : st::msgInServiceFg); p.setPen(selected ? st::msgInServiceFgSelected : st::msgInServiceFg);
@ -886,7 +886,7 @@ bool Message::getStateFromName(
availableWidth -= st::msgPadding.right() + replyWidth; availableWidth -= st::msgPadding.right() + replyWidth;
} }
const auto from = item->displayFrom(); const auto from = item->displayFrom();
const auto nameText = [&]() -> const Text* { const auto nameText = [&]() -> const Ui::Text::String * {
if (from) { if (from) {
return &from->nameText(); return &from->nameText();
} else if (const auto info = item->hiddenForwardedInfo()) { } 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 breakEverywhere = (forwarded->text.countHeight(trect.width()) > 2 * st::semiboldFont->height);
auto textRequest = request.forText(); auto textRequest = request.forText();
if (breakEverywhere) { if (breakEverywhere) {
textRequest.flags |= Text::StateRequest::Flag::BreakEverywhere; textRequest.flags |= Ui::Text::StateRequest::Flag::BreakEverywhere;
} }
*outResult = TextState(item, forwarded->text.getState( *outResult = TextState(item, forwarded->text.getState(
point - trect.topLeft(), point - trect.topLeft(),
@ -1561,7 +1561,7 @@ void Message::fromNameUpdated(int width) const {
item->_fromNameVersion = from ? from->nameVersion : 1; item->_fromNameVersion = from ? from->nameVersion : 1;
if (const auto via = item->Get<HistoryMessageVia>()) { if (const auto via = item->Get<HistoryMessageVia>()) {
if (!displayForwardedFrom()) { if (!displayForwardedFrom()) {
const auto nameText = [&]() -> const Text* { const auto nameText = [&]() -> const Ui::Text::String * {
if (from) { if (from) {
return &from->nameText(); return &from->nameText();
} else if (const auto info = item->hiddenForwardedInfo()) { } else if (const auto info = item->hiddenForwardedInfo()) {

View file

@ -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); 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(); createCircleMasks();
auto lineWidths = countLineWidths(text, textRect); auto lineWidths = countLineWidths(text, textRect);
@ -259,7 +259,7 @@ void ServiceMessagePainter::paintComplexBubble(Painter &p, int left, int width,
} }
} }
QVector<int> ServiceMessagePainter::countLineWidths(const Text &text, const QRect &textRect) { QVector<int> ServiceMessagePainter::countLineWidths(const Ui::Text::String &text, const QRect &textRect) {
int linesCount = qMax(textRect.height() / st::msgServiceFont->height, 1); int linesCount = qMax(textRect.height() / st::msgServiceFont->height, 1);
QVector<int> lineWidths; QVector<int> lineWidths;
lineWidths.reserve(linesCount); lineWidths.reserve(linesCount);
@ -553,7 +553,7 @@ void EmptyPainter::fillAboutGroup() {
lang(lng_group_about3), lang(lng_group_about3),
lang(lng_group_about4), lang(lng_group_about4),
}; };
const auto setText = [](Text &text, const QString &content) { const auto setText = [](Ui::Text::String &text, const QString &content) {
text.setText( text.setText(
st::serviceTextStyle, st::serviceTextStyle,
content, content,
@ -575,7 +575,7 @@ void EmptyPainter::paint(Painter &p, int width, int height) {
const auto maxPhraseWidth = ranges::max_element( const auto maxPhraseWidth = ranges::max_element(
_phrases, _phrases,
ranges::less(), ranges::less(),
&Text::maxWidth &Ui::Text::String::maxWidth
)->maxWidth(); )->maxWidth();
const auto &font = st::serviceTextStyle.font; const auto &font = st::serviceTextStyle.font;
@ -589,7 +589,7 @@ void EmptyPainter::paint(Painter &p, int width, int height) {
_header.maxWidth(), _header.maxWidth(),
_text.maxWidth() }) + padding.left() + padding.right()); _text.maxWidth() }) + padding.left() + padding.right());
const auto innerWidth = bubbleWidth - 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( return std::min(
text.countHeight(innerWidth), text.countHeight(innerWidth),
kMaxTextLines * font->height); kMaxTextLines * font->height);

View file

@ -67,10 +67,10 @@ public:
static void paintBubble(Painter &p, int x, int y, int w, int h); 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: private:
static QVector<int> countLineWidths(const Text &text, const QRect &textRect); static QVector<int> countLineWidths(const Ui::Text::String &text, const QRect &textRect);
}; };
@ -84,9 +84,9 @@ private:
void fillAboutGroup(); void fillAboutGroup();
not_null<History*> _history; not_null<History*> _history;
Text _header = { st::msgMinWidth }; Ui::Text::String _header = { st::msgMinWidth };
Text _text = { st::msgMinWidth }; Ui::Text::String _text = { st::msgMinWidth };
std::vector<Text> _phrases; std::vector<Ui::Text::String> _phrases;
}; };

View file

@ -132,7 +132,7 @@ private:
object_ptr<TWidget> _membersShowArea = { nullptr }; object_ptr<TWidget> _membersShowArea = { nullptr };
rpl::event_stream<bool> _membersShowAreaActive; rpl::event_stream<bool> _membersShowAreaActive;
Text _titlePeerText; Ui::Text::String _titlePeerText;
bool _titlePeerTextOnline = false; bool _titlePeerTextOnline = false;
int _leftTaken = 0; int _leftTaken = 0;
int _rightTaken = 0; int _rightTaken = 0;

View file

@ -142,7 +142,7 @@ private:
void refreshHeight(); void refreshHeight();
Type _type = Type::Photo; Type _type = Type::Photo;
Text _header; Ui::Text::String _header;
Items _items; Items _items;
int _itemsLeft = 0; int _itemsLeft = 0;
int _itemsTop = 0; int _itemsTop = 0;
@ -1452,7 +1452,7 @@ void ListWidget::switchToWordSelection() {
Expects(_overLayout != nullptr); Expects(_overLayout != nullptr);
StateRequest request; StateRequest request;
request.flags |= Text::StateRequest::Flag::LookupSymbol; request.flags |= Ui::Text::StateRequest::Flag::LookupSymbol;
auto dragState = _overLayout->getState(_pressState.cursor, request); auto dragState = _overLayout->getState(_pressState.cursor, request);
if (dragState.cursor != CursorState::Text) { if (dragState.cursor != CursorState::Text) {
return; return;
@ -1665,7 +1665,7 @@ void ListWidget::mouseActionUpdate(const QPoint &globalPosition) {
} }
StateRequest request; StateRequest request;
if (_mouseAction == MouseAction::Selecting) { if (_mouseAction == MouseAction::Selecting) {
request.flags |= Text::StateRequest::Flag::LookupSymbol; request.flags |= Ui::Text::StateRequest::Flag::LookupSymbol;
} else { } else {
inTextSelection = false; inTextSelection = false;
} }
@ -1830,7 +1830,7 @@ void ListWidget::mouseActionStart(
auto validStartPoint = startDistance < QApplication::startDragDistance(); auto validStartPoint = startDistance < QApplication::startDragDistance();
if (_trippleClickStartTime != 0 && validStartPoint) { if (_trippleClickStartTime != 0 && validStartPoint) {
StateRequest request; StateRequest request;
request.flags = Text::StateRequest::Flag::LookupSymbol; request.flags = Ui::Text::StateRequest::Flag::LookupSymbol;
dragState = pressLayout->getState(_pressState.cursor, request); dragState = pressLayout->getState(_pressState.cursor, request);
if (dragState.cursor == CursorState::Text) { if (dragState.cursor == CursorState::Text) {
TextSelection selStatus = { dragState.symbol, dragState.symbol }; TextSelection selStatus = { dragState.symbol, dragState.symbol };
@ -1846,7 +1846,7 @@ void ListWidget::mouseActionStart(
} }
} else { } else {
StateRequest request; StateRequest request;
request.flags = Text::StateRequest::Flag::LookupSymbol; request.flags = Ui::Text::StateRequest::Flag::LookupSymbol;
dragState = pressLayout->getState(_pressState.cursor, request); dragState = pressLayout->getState(_pressState.cursor, request);
} }
if (_mouseSelectType != TextSelectType::Paragraphs) { if (_mouseSelectType != TextSelectType::Paragraphs) {
@ -1901,7 +1901,7 @@ void ListWidget::performDrag() {
} else if (auto pressLayout = getExistingLayout( } else if (auto pressLayout = getExistingLayout(
_pressState.itemId)) { _pressState.itemId)) {
StateRequest request; StateRequest request;
request.flags |= Text::StateRequest::Flag::LookupSymbol; request.flags |= Ui::Text::StateRequest::Flag::LookupSymbol;
auto dragState = pressLayout->getState( auto dragState = pressLayout->getState(
_pressState.cursor, _pressState.cursor,
request); request);

View file

@ -24,6 +24,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "boxes/peer_list_controllers.h" #include "boxes/peer_list_controllers.h"
#include "boxes/add_contact_box.h" #include "boxes/add_contact_box.h"
#include "boxes/report_box.h" #include "boxes/report_box.h"
#include "boxes/generic_box.h"
#include "lang/lang_keys.h" #include "lang/lang_keys.h"
#include "info/info_controller.h" #include "info/info_controller.h"
#include "info/info_memento.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 "info/profile/info_profile_text.h"
#include "support/support_helper.h" #include "support/support_helper.h"
#include "window/window_session_controller.h" #include "window/window_session_controller.h"
#include "window/window_controller.h"
#include "window/window_peer_menu.h" #include "window/window_peer_menu.h"
#include "mainwidget.h" #include "mainwidget.h"
#include "mainwindow.h" // MainWindow::controller.
#include "auth_session.h" #include "auth_session.h"
#include "core/application.h" #include "core/application.h"
#include "apiwrap.h" #include "apiwrap.h"
@ -566,6 +569,8 @@ void ActionsFiller::addReportAction() {
} }
void ActionsFiller::addBlockAction(not_null<UserData*> user) { void ActionsFiller::addBlockAction(not_null<UserData*> user) {
const auto window = &_controller->parentController()->window()->controller();
auto text = Notify::PeerUpdateValue( auto text = Notify::PeerUpdateValue(
user, user,
Notify::PeerUpdate::Flag::UserIsBlocked Notify::PeerUpdate::Flag::UserIsBlocked
@ -591,12 +596,14 @@ void ActionsFiller::addBlockAction(not_null<UserData*> user) {
}); });
auto callback = [=] { auto callback = [=] {
if (user->isBlocked()) { if (user->isBlocked()) {
Auth().api().unblockUser(user); user->session().api().unblockUser(user);
if (user->botInfo) { if (user->botInfo) {
Ui::showPeerHistory(user, ShowAtUnreadMsgId); Ui::showPeerHistory(user, ShowAtUnreadMsgId);
} }
} else if (user->isBot()) {
user->session().api().blockUser(user);
} else { } else {
Auth().api().blockUser(user); window->show(Box(Window::PeerMenuBlockUserBox, user, window));
} }
}; };
AddActionButton( AddActionButton(

View file

@ -199,7 +199,7 @@ private:
ClickHandlerPtr _link; ClickHandlerPtr _link;
mutable QPixmap _thumb; mutable QPixmap _thumb;
Text _title, _description; Ui::Text::String _title, _description;
QString _duration; QString _duration;
int _durationWidth = 0; int _durationWidth = 0;
@ -286,7 +286,7 @@ private:
}; };
mutable std::unique_ptr<AnimationData> _animation; mutable std::unique_ptr<AnimationData> _animation;
Text _title, _description; Ui::Text::String _title, _description;
ClickHandlerPtr _open, _cancel; ClickHandlerPtr _open, _cancel;
// >= 0 will contain download / upload string, _statusSize = loaded bytes // >= 0 will contain download / upload string, _statusSize = loaded bytes
@ -317,7 +317,7 @@ public:
private: private:
mutable QPixmap _thumb; mutable QPixmap _thumb;
Text _title, _description; Ui::Text::String _title, _description;
void prepareThumbnail(int width, int height) const; void prepareThumbnail(int width, int height) const;
@ -340,7 +340,7 @@ private:
bool _withThumb; bool _withThumb;
mutable QPixmap _thumb; mutable QPixmap _thumb;
Text _title, _description; Ui::Text::String _title, _description;
QString _thumbLetter, _urlText; QString _thumbLetter, _urlText;
int32 _urlWidth; int32 _urlWidth;
@ -375,7 +375,7 @@ private:
mutable QPixmap _thumb; mutable QPixmap _thumb;
mutable bool _thumbGood = false; mutable bool _thumbGood = false;
mutable std::unique_ptr<Ui::RadialAnimation> _radial; mutable std::unique_ptr<Ui::RadialAnimation> _radial;
Text _title, _description; Ui::Text::String _title, _description;
QSize _frameSize; QSize _frameSize;

View file

@ -1607,7 +1607,7 @@ void OverlayWidget::refreshFromLabel(HistoryItem *item) {
} }
void OverlayWidget::refreshCaption(HistoryItem *item) { void OverlayWidget::refreshCaption(HistoryItem *item) {
_caption = Text(); _caption = Ui::Text::String();
if (!item) { if (!item) {
return; return;
} else if (const auto media = item->media()) { } else if (const auto media = item->media()) {
@ -1625,7 +1625,7 @@ void OverlayWidget::refreshCaption(HistoryItem *item) {
} }
return false; return false;
}(); }();
_caption = Text(st::msgMinWidth); _caption = Ui::Text::String(st::msgMinWidth);
_caption.setMarkedText( _caption.setMarkedText(
st::mediaviewCaptionStyle, st::mediaviewCaptionStyle,
caption, caption,

View file

@ -348,7 +348,7 @@ private:
int _groupThumbsAvailableWidth = 0; int _groupThumbsAvailableWidth = 0;
int _groupThumbsLeft = 0; int _groupThumbsLeft = 0;
int _groupThumbsTop = 0; int _groupThumbsTop = 0;
Text _caption; Ui::Text::String _caption;
QRect _captionRect; QRect _captionRect;
int _width = 0; int _width = 0;
@ -394,7 +394,7 @@ private:
PeerData *_from = nullptr; PeerData *_from = nullptr;
QString _fromName; QString _fromName;
Text _fromNameLabel; Ui::Text::String _fromNameLabel;
std::optional<int> _index; // Index in current _sharedMedia data. std::optional<int> _index; // Index in current _sharedMedia data.
std::optional<int> _fullIndex; // Index in full shared media. std::optional<int> _fullIndex; // Index in full shared media.
@ -448,7 +448,7 @@ private:
anim::value _saveMsgOpacity; anim::value _saveMsgOpacity;
QRect _saveMsg; QRect _saveMsg;
QTimer _saveMsgUpdater; QTimer _saveMsgUpdater;
Text _saveMsgText; Ui::Text::String _saveMsgText;
base::flat_map<OverState, crl::time> _animations; base::flat_map<OverState, crl::time> _animations;
base::flat_map<OverState, anim::value> _animationOpacities; base::flat_map<OverState, anim::value> _animationOpacities;

View file

@ -282,7 +282,7 @@ private:
const style::OverviewFileLayout &_st; const style::OverviewFileLayout &_st;
Text _name, _details; Ui::Text::String _name, _details;
int _nameVersion; int _nameVersion;
void updateName(); void updateName();
@ -330,7 +330,7 @@ private:
bool _thumbLoaded = false; bool _thumbLoaded = false;
QPixmap _thumb; QPixmap _thumb;
Text _name; Ui::Text::String _name;
QString _date, _ext; QString _date, _ext;
int32 _datew, _extw; int32 _datew, _extw;
int32 _thumbw, _colorIndex; int32 _thumbw, _colorIndex;
@ -364,7 +364,7 @@ private:
WebPageData *_page = nullptr; WebPageData *_page = nullptr;
int _pixw = 0; int _pixw = 0;
int _pixh = 0; int _pixh = 0;
Text _text = { st::msgMinWidth }; Ui::Text::String _text = { st::msgMinWidth };
struct LinkEntry { struct LinkEntry {
LinkEntry() : width(0) { LinkEntry() : width(0) {

View file

@ -99,8 +99,8 @@ private:
int countAvailableWidth() const; int countAvailableWidth() const;
const style::PassportScanRow &_st; const style::PassportScanRow &_st;
Text _name; Ui::Text::String _name;
Text _status; Ui::Text::String _status;
int _nameHeight = 0; int _nameHeight = 0;
int _statusHeight = 0; int _statusHeight = 0;
bool _error = false; bool _error = false;

View file

@ -47,8 +47,8 @@ private:
int countAvailableWidth() const; int countAvailableWidth() const;
int countAvailableWidth(int newWidth) const; int countAvailableWidth(int newWidth) const;
Text _title; Ui::Text::String _title;
Text _description; Ui::Text::String _description;
int _titleHeight = 0; int _titleHeight = 0;
int _descriptionHeight = 0; int _descriptionHeight = 0;
bool _ready = false; bool _ready = false;

View file

@ -33,7 +33,7 @@ public:
~Item(); ~Item();
PeerData * const peer; PeerData * const peer;
Text name; Ui::Text::String name;
QString statusText; QString statusText;
bool statusHasOnlineColor = false; bool statusHasOnlineColor = false;
enum class AdminState { enum class AdminState {

View file

@ -54,9 +54,9 @@ protected:
private: private:
struct Row { struct Row {
Question data; Question data;
Text question = { st::windowMinWidth / 2 }; Ui::Text::String question = { st::windowMinWidth / 2 };
Text keys = { st::windowMinWidth / 2 }; Ui::Text::String keys = { st::windowMinWidth / 2 };
Text answer = { st::windowMinWidth / 2 }; Ui::Text::String answer = { st::windowMinWidth / 2 };
int top = 0; int top = 0;
int height = 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); Expects(text.style() != nullptr);
const auto st = text.style(); const auto st = text.style();
@ -179,7 +179,7 @@ void Inner::paintEvent(QPaintEvent *e) {
const auto padding = st::autocompleteRowPadding; const auto padding = st::autocompleteRowPadding;
const auto available = width() - padding.left() - padding.right(); const auto available = width() - padding.left() - padding.right();
auto top = padding.top(); auto top = padding.top();
const auto drawText = [&](const Text &text, int lines) { const auto drawText = [&](const Ui::Text::String &text, int lines) {
text.drawLeftElided( text.drawLeftElided(
p, p,
padding.left(), padding.left(),

View file

@ -18,14 +18,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "boxes/confirm_box.h" #include "boxes/confirm_box.h"
#include "mainwindow.h" #include "mainwindow.h"
namespace {
inline int32 countBlockHeight(const ITextBlock *b, const style::TextStyle *st) {
return (b->type() == TextBlockTSkip) ? static_cast<const SkipBlock*>(b)->height() : (st->lineHeight > st->font->height) ? st->lineHeight : st->font->height;
}
} // namespace
bool chIsBad(QChar ch) { bool chIsBad(QChar ch) {
return (ch == 0) return (ch == 0)
|| (ch >= 8232 && ch < 8237) || (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; 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: public:
static Qt::LayoutDirection stringDirection(const QString &str, int32 from, int32 to) { static Qt::LayoutDirection stringDirection(const QString &str, int32 from, int32 to) {
const ushort *p = reinterpret_cast<const ushort*>(str.unicode()) + from; const ushort *p = reinterpret_cast<const ushort*>(str.unicode()) + from;
@ -505,7 +514,7 @@ public:
emoji = e; 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 }, source { text },
rich(options.flags & TextParseRichText), rich(options.flags & TextParseRichText),
multiline(options.flags & TextParseMultiline), multiline(options.flags & TextParseMultiline),
@ -516,7 +525,7 @@ public:
parse(options); 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), source(textWithEntities),
rich(options.flags & TextParseRichText), rich(options.flags & TextParseRichText),
multiline(options.flags & TextParseMultiline), multiline(options.flags & TextParseMultiline),
@ -717,7 +726,7 @@ private:
*outDisplayStatus = (*outLinkText == readable) ? LinkDisplayedFull : LinkDisplayedElided; *outDisplayStatus = (*outLinkText == readable) ? LinkDisplayedFull : LinkDisplayedElided;
} }
Text *_t; String *_t;
TextWithEntities source; TextWithEntities source;
const QChar *start, *end, *ptr; const QChar *start, *end, *ptr;
bool rich, multiline; bool rich, multiline;
@ -749,6 +758,7 @@ private:
}; };
namespace { namespace {
// COPIED FROM qtextengine.cpp AND MODIFIED // COPIED FROM qtextengine.cpp AND MODIFIED
struct BidiStatus { struct BidiStatus {
@ -841,17 +851,21 @@ static void eAppendItems(QScriptAnalysis *analysis, int &start, int &stop, const
start = stop; start = stop;
} }
inline int32 countBlockHeight(const AbstractBlock *b, const style::TextStyle *st) {
return (b->type() == TextBlockTSkip) ? static_cast<const SkipBlock*>(b)->height() : (st->lineHeight > st->font->height) ? st->lineHeight : st->font->height;
}
} // namespace } // namespace
class TextPainter { class Renderer {
public: public:
TextPainter(Painter *p, const Text *t) Renderer(Painter *p, const String *t)
: _p(p) : _p(p)
, _t(t) , _t(t)
, _originalPen(p ? p->pen() : QPen()) { , _originalPen(p ? p->pen() : QPen()) {
} }
~TextPainter() { ~Renderer() {
restoreAfterElided(); restoreAfterElided();
if (_p) { if (_p) {
_p->setPen(_originalPen); _p->setPen(_originalPen);
@ -1071,15 +1085,15 @@ public:
draw(left, top, w, align, yFrom, yTo, selection); 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) { if (!_t->isNull() && point.y() >= 0) {
_lookupRequest = request; _lookupRequest = request;
_lookupX = point.x(); _lookupX = point.x();
_lookupY = point.y(); _lookupY = point.y();
_breakEverywhere = (_lookupRequest.flags & Text::StateRequest::Flag::BreakEverywhere); _breakEverywhere = (_lookupRequest.flags & StateRequest::Flag::BreakEverywhere);
_lookupSymbol = (_lookupRequest.flags & Text::StateRequest::Flag::LookupSymbol); _lookupSymbol = (_lookupRequest.flags & StateRequest::Flag::LookupSymbol);
_lookupLink = (_lookupRequest.flags & Text::StateRequest::Flag::LookupLink); _lookupLink = (_lookupRequest.flags & StateRequest::Flag::LookupLink);
if (_lookupSymbol || (_lookupX >= 0 && _lookupX < w)) { if (_lookupSymbol || (_lookupX >= 0 && _lookupX < w)) {
draw(0, 0, w, _lookupRequest.align, _lookupY, _lookupY + 1); draw(0, 0, w, _lookupRequest.align, _lookupY, _lookupY + 1);
} }
@ -1087,15 +1101,15 @@ public:
return _lookupResult; 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) { if (!_t->isNull() && point.y() >= 0 && request.lines > 0) {
_lookupRequest = request; _lookupRequest = request;
_lookupX = point.x(); _lookupX = point.x();
_lookupY = point.y(); _lookupY = point.y();
_breakEverywhere = (_lookupRequest.flags & Text::StateRequest::Flag::BreakEverywhere); _breakEverywhere = (_lookupRequest.flags & StateRequest::Flag::BreakEverywhere);
_lookupSymbol = (_lookupRequest.flags & Text::StateRequest::Flag::LookupSymbol); _lookupSymbol = (_lookupRequest.flags & StateRequest::Flag::LookupSymbol);
_lookupLink = (_lookupRequest.flags & Text::StateRequest::Flag::LookupLink); _lookupLink = (_lookupRequest.flags & StateRequest::Flag::LookupLink);
if (_lookupSymbol || (_lookupX >= 0 && _lookupX < w)) { if (_lookupSymbol || (_lookupX >= 0 && _lookupX < w)) {
int yTo = _lookupY + 1; int yTo = _lookupY + 1;
if (yTo < 0 || (request.lines - 1) * _t->_st->font->height < yTo) { if (yTo < 0 || (request.lines - 1) * _t->_st->font->height < yTo) {
@ -1110,9 +1124,9 @@ public:
} }
private: private:
void initNextParagraph(Text::TextBlocks::const_iterator i) { void initNextParagraph(String::TextBlocks::const_iterator i) {
_parStartBlock = i; _parStartBlock = i;
Text::TextBlocks::const_iterator e = _t->_blocks.cend(); const auto e = _t->_blocks.cend();
if (i == e) { if (i == e) {
_parStart = _t->_text.size(); _parStart = _t->_text.size();
_parLength = 0; _parLength = 0;
@ -1131,7 +1145,7 @@ private:
void initParagraphBidi() { void initParagraphBidi() {
if (!_parLength || !_parAnalysis.isEmpty()) return; 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 ignore = false;
bool rtl = (_parDirection == Qt::RightToLeft); 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; _yDelta = (_lineHeight - _fontHeight) / 2;
if (_yTo >= 0 && (_y + _yDelta >= _yTo || _y >= _yTo)) return false; if (_yTo >= 0 && (_y + _yDelta >= _yTo || _y >= _yTo)) return false;
if (_y + _yDelta + _fontHeight <= _yFrom) { if (_y + _yDelta + _fontHeight <= _yFrom) {
@ -1618,13 +1632,13 @@ private:
_p->fillRect(left, _y + _yDelta, width, _fontHeight, _textPalette->selectBg); _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) { if (_elideSavedBlock) {
restoreAfterElided(); restoreAfterElided();
} }
_elideSavedIndex = blockIndex; _elideSavedIndex = blockIndex;
auto mutableText = const_cast<Text*>(_t); auto mutableText = const_cast<String*>(_t);
_elideSavedBlock = std::move(mutableText->_blocks[blockIndex]); _elideSavedBlock = std::move(mutableText->_blocks[blockIndex]);
mutableText->_blocks[blockIndex] = std::make_unique<TextBlock>(_t->_st->font, _t->_text, QFIXED_MAX, elideStart, 0, _elideSavedBlock->flags(), _elideSavedBlock->lnkIndex()); mutableText->_blocks[blockIndex] = std::make_unique<TextBlock>(_t->_st->font, _t->_text, QFIXED_MAX, elideStart, 0, _elideSavedBlock->flags(), _elideSavedBlock->lnkIndex());
_blocksSize = blockIndex + 1; _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("..."); static const QString _Elide = qsl("...");
_f = _t->_st->font; _f = _t->_st->font;
@ -1751,7 +1765,7 @@ private:
void restoreAfterElided() { void restoreAfterElided() {
if (_elideSavedBlock) { if (_elideSavedBlock) {
const_cast<Text*>(_t)->_blocks[_elideSavedIndex] = std::move(_elideSavedBlock); const_cast<String*>(_t)->_blocks[_elideSavedIndex] = std::move(_elideSavedBlock);
} }
} }
@ -1807,7 +1821,7 @@ private:
return result; return result;
} }
void eSetFont(ITextBlock *block) { void eSetFont(AbstractBlock *block) {
style::font newFont = _t->_st->font; style::font newFont = _t->_st->font;
int flags = block->flags(); int flags = block->flags();
if (flags) { if (flags) {
@ -1931,8 +1945,8 @@ private:
QChar::Direction eSkipBoundryNeutrals(QScriptAnalysis *analysis, QChar::Direction eSkipBoundryNeutrals(QScriptAnalysis *analysis,
const ushort *unicode, const ushort *unicode,
int &sor, int &eor, BidiControl &control, int &sor, int &eor, BidiControl &control,
Text::TextBlocks::const_iterator i) { String::TextBlocks::const_iterator i) {
Text::TextBlocks::const_iterator e = _t->_blocks.cend(), n = i + 1; String::TextBlocks::const_iterator e = _t->_blocks.cend(), n = i + 1;
QChar::Direction dir = control.basicDirection(); QChar::Direction dir = control.basicDirection();
int level = sor > 0 ? analysis[sor - 1].bidiLevel : control.level; int level = sor > 0 ? analysis[sor - 1].bidiLevel : control.level;
@ -1980,7 +1994,7 @@ private:
QChar::Direction dir = rightToLeft ? QChar::DirR : QChar::DirL; QChar::Direction dir = rightToLeft ? QChar::DirR : QChar::DirL;
BidiStatus status; 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; QChar::Direction sdir;
TextBlockType _stype = (*_parStartBlock)->type(); TextBlockType _stype = (*_parStartBlock)->type();
@ -2389,7 +2403,7 @@ private:
} }
private: private:
void applyBlockProperties(ITextBlock *block) { void applyBlockProperties(AbstractBlock *block) {
eSetFont(block); eSetFont(block);
if (_p) { if (_p) {
if (block->lnkIndex()) { if (block->lnkIndex()) {
@ -2407,7 +2421,7 @@ private:
Painter *_p = nullptr; Painter *_p = nullptr;
const style::TextPalette *_textPalette = nullptr; const style::TextPalette *_textPalette = nullptr;
const Text *_t = nullptr; const String *_t = nullptr;
bool _elideLast = false; bool _elideLast = false;
bool _breakEverywhere = false; bool _breakEverywhere = false;
int _elideRemoveFromEnd = 0; int _elideRemoveFromEnd = 0;
@ -2424,7 +2438,7 @@ private:
const QChar *_str = nullptr; const QChar *_str = nullptr;
// current paragraph data // current paragraph data
Text::TextBlocks::const_iterator _parStartBlock; String::TextBlocks::const_iterator _parStartBlock;
Qt::LayoutDirection _parDirection; Qt::LayoutDirection _parDirection;
int _parStart = 0; int _parStart = 0;
int _parLength = 0; int _parLength = 0;
@ -2440,7 +2454,7 @@ private:
// elided hack support // elided hack support
int _blocksSize = 0; int _blocksSize = 0;
int _elideSavedIndex = 0; int _elideSavedIndex = 0;
std::unique_ptr<ITextBlock> _elideSavedBlock; std::unique_ptr<AbstractBlock> _elideSavedBlock;
int _lineStart = 0; int _lineStart = 0;
int _localFrom = 0; int _localFrom = 0;
@ -2451,29 +2465,15 @@ private:
int _lookupY = 0; int _lookupY = 0;
bool _lookupSymbol = false; bool _lookupSymbol = false;
bool _lookupLink = false; bool _lookupLink = false;
Text::StateRequest _lookupRequest; StateRequest _lookupRequest;
Text::StateResult _lookupResult; StateResult _lookupResult;
}; };
const TextParseOptions _defaultOptions = { String::String(int32 minResizeWidth) : _minResizeWidth(minResizeWidth) {
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) {
} }
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) { if (richText) {
setRichText(st, text, options); setRichText(st, text, options);
} else { } 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) : _minResizeWidth(other._minResizeWidth)
, _maxWidth(other._maxWidth) , _maxWidth(other._maxWidth)
, _minHeight(other._minHeight) , _minHeight(other._minHeight)
@ -2495,7 +2495,7 @@ Text::Text(const Text &other)
} }
} }
Text::Text(Text &&other) String::String(String &&other)
: _minResizeWidth(other._minResizeWidth) : _minResizeWidth(other._minResizeWidth)
, _maxWidth(other._maxWidth) , _maxWidth(other._maxWidth)
, _minHeight(other._minHeight) , _minHeight(other._minHeight)
@ -2507,7 +2507,7 @@ Text::Text(Text &&other)
other.clearFields(); other.clearFields();
} }
Text &Text::operator=(const Text &other) { String &String::operator=(const String &other) {
_minResizeWidth = other._minResizeWidth; _minResizeWidth = other._minResizeWidth;
_maxWidth = other._maxWidth; _maxWidth = other._maxWidth;
_minHeight = other._minHeight; _minHeight = other._minHeight;
@ -2522,7 +2522,7 @@ Text &Text::operator=(const Text &other) {
return *this; return *this;
} }
Text &Text::operator=(Text &&other) { String &String::operator=(String &&other) {
_minResizeWidth = other._minResizeWidth; _minResizeWidth = other._minResizeWidth;
_maxWidth = other._maxWidth; _maxWidth = other._maxWidth;
_minHeight = other._minHeight; _minHeight = other._minHeight;
@ -2535,16 +2535,16 @@ Text &Text::operator=(Text &&other) {
return *this; 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; _st = &st;
clear(); clear();
{ {
TextParser parser(this, text, options); Parser parser(this, text, options);
} }
recountNaturalSize(true, options.dir); recountNaturalSize(true, options.dir);
} }
void Text::recountNaturalSize(bool initial, Qt::LayoutDirection optionsDir) { void String::recountNaturalSize(bool initial, Qt::LayoutDirection optionsDir) {
NewlineBlock *lastNewline = 0; NewlineBlock *lastNewline = 0;
_maxWidth = _minHeight = 0; _maxWidth = _minHeight = 0;
@ -2560,7 +2560,7 @@ void Text::recountNaturalSize(bool initial, Qt::LayoutDirection optionsDir) {
if (initial) { if (initial) {
Qt::LayoutDirection dir = optionsDir; Qt::LayoutDirection dir = optionsDir;
if (dir == Qt::LayoutDirectionAuto) { if (dir == Qt::LayoutDirectionAuto) {
dir = TextParser::stringDirection(_text, lastNewlineStart, b->from()); dir = Parser::stringDirection(_text, lastNewlineStart, b->from());
} }
if (lastNewline) { if (lastNewline) {
lastNewline->_nextDir = dir; lastNewline->_nextDir = dir;
@ -2602,7 +2602,7 @@ void Text::recountNaturalSize(bool initial, Qt::LayoutDirection optionsDir) {
if (initial) { if (initial) {
Qt::LayoutDirection dir = optionsDir; Qt::LayoutDirection dir = optionsDir;
if (dir == Qt::LayoutDirectionAuto) { if (dir == Qt::LayoutDirectionAuto) {
dir = TextParser::stringDirection(_text, lastNewlineStart, _text.size()); dir = Parser::stringDirection(_text, lastNewlineStart, _text.size());
} }
if (lastNewline) { if (lastNewline) {
lastNewline->_nextDir = dir; 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; _st = &st;
clear(); clear();
{ {
@ -2645,14 +2645,14 @@ void Text::setMarkedText(const style::TextStyle &st, const TextWithEntities &tex
// } // }
// } // }
// newText.append("},\n\n").append(text); // 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); 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; QString parsed;
parsed.reserve(text.size()); parsed.reserve(text.size());
const QChar *s = text.constData(), *ch = s; 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); 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; if (!lnkIndex || lnkIndex > _links.size()) return;
_links[lnkIndex - 1] = lnk; _links[lnkIndex - 1] = lnk;
} }
bool Text::hasLinks() const { bool String::hasLinks() const {
return !_links.isEmpty(); return !_links.isEmpty();
} }
bool Text::hasSkipBlock() const { bool String::hasSkipBlock() const {
return _blocks.empty() ? false : _blocks.back()->type() == TextBlockTSkip; 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) { if (!_blocks.empty() && _blocks.back()->type() == TextBlockTSkip) {
const auto block = static_cast<SkipBlock*>(_blocks.back().get()); const auto block = static_cast<SkipBlock*>(_blocks.back().get());
if (block->width() == width && block->height() == height) { if (block->width() == width && block->height() == height) {
@ -2764,7 +2764,7 @@ bool Text::updateSkipBlock(int width, int height) {
return true; return true;
} }
bool Text::removeSkipBlock() { bool String::removeSkipBlock() {
if (_blocks.empty() || _blocks.back()->type() != TextBlockTSkip) { if (_blocks.empty() || _blocks.back()->type() != TextBlockTSkip) {
return false; return false;
} }
@ -2774,7 +2774,7 @@ bool Text::removeSkipBlock() {
return true; return true;
} }
int Text::countWidth(int width) const { int String::countWidth(int width) const {
if (QFixed(width) >= _maxWidth) { if (QFixed(width) >= _maxWidth) {
return _maxWidth.ceil().toInt(); return _maxWidth.ceil().toInt();
} }
@ -2788,7 +2788,7 @@ int Text::countWidth(int width) const {
return maxLineWidth.ceil().toInt(); return maxLineWidth.ceil().toInt();
} }
int Text::countHeight(int width) const { int String::countHeight(int width) const {
if (QFixed(width) >= _maxWidth) { if (QFixed(width) >= _maxWidth) {
return _minHeight; return _minHeight;
} }
@ -2799,14 +2799,14 @@ int Text::countHeight(int width) const {
return result; return result;
} }
void Text::countLineWidths(int width, QVector<int> *lineWidths) const { void String::countLineWidths(int width, QVector<int> *lineWidths) const {
enumerateLines(width, [lineWidths](QFixed lineWidth, int lineHeight) { enumerateLines(width, [lineWidths](QFixed lineWidth, int lineHeight) {
lineWidths->push_back(lineWidth.ceil().toInt()); lineWidths->push_back(lineWidth.ceil().toInt());
}); });
} }
template <typename Callback> template <typename Callback>
void Text::enumerateLines(int w, Callback callback) const { void String::enumerateLines(int w, Callback callback) const {
QFixed width = w; QFixed width = w;
if (width < _minResizeWidth) width = _minResizeWidth; 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 // 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); 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 // 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); p.drawElided(left, top, w, align, lines, yFrom, yTo, removeFromEnd, breakEverywhere, selection);
} }
Text::StateResult Text::getState(QPoint point, int width, StateRequest request) const { StateResult String::getState(QPoint point, int width, StateRequest request) const {
return TextPainter(nullptr, this).getState(point, width, request); return Renderer(nullptr, this).getState(point, width, request);
} }
Text::StateResult Text::getStateElided(QPoint point, int width, StateRequestElided request) const { StateResult String::getStateElided(QPoint point, int width, StateRequestElided request) const {
return TextPainter(nullptr, this).getStateElided(point, width, request); 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; uint16 from = selection.from, to = selection.to;
if (from < _text.size() && from <= to) { if (from < _text.size() && from <= to) {
if (to > _text.size()) to = _text.size(); if (to > _text.size()) to = _text.size();
@ -2974,20 +2974,20 @@ TextSelection Text::adjustSelection(TextSelection selection, TextSelectType sele
return { from, to }; return { from, to };
} }
bool Text::isEmpty() const { bool String::isEmpty() const {
return _blocks.empty() || _blocks[0]->type() == TextBlockTSkip; 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(); 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(); return countBlockEnd(i, e) - (*i)->from();
} }
template <typename AppendPartCallback, typename ClickHandlerStartCallback, typename ClickHandlerFinishCallback, typename FlagsChangeCallback> template <typename AppendPartCallback, typename ClickHandlerStartCallback, typename ClickHandlerFinishCallback, typename FlagsChangeCallback>
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()) { if (isEmpty() || selection.empty()) {
return; 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; 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; return toText(selection, false, true).rich;
} }
TextForMimeData Text::toTextForMimeData(TextSelection selection) const { TextForMimeData String::toTextForMimeData(TextSelection selection) const {
return toText(selection, true, true); return toText(selection, true, true);
} }
TextForMimeData Text::toText( TextForMimeData String::toText(
TextSelection selection, TextSelection selection,
bool composeExpanded, bool composeExpanded,
bool composeEntities) const { bool composeEntities) const {
@ -3143,16 +3143,19 @@ TextForMimeData Text::toText(
return result; return result;
} }
void Text::clear() { void String::clear() {
clearFields(); clearFields();
_text.clear(); _text.clear();
} }
void Text::clearFields() { void String::clearFields() {
_blocks.clear(); _blocks.clear();
_links.clear(); _links.clear();
_maxWidth = _minHeight = 0; _maxWidth = _minHeight = 0;
_startDir = Qt::LayoutDirectionAuto; _startDir = Qt::LayoutDirectionAuto;
} }
Text::~Text() = default; String::~String() = default;
} // namespace Text
} // namespace Ui

View file

@ -67,15 +67,52 @@ static constexpr TextSelection AllTextSelection = { 0, 0xFFFF };
typedef QPair<QString, QString> TextCustomTag; // open str and close str typedef QPair<QString, QString> TextCustomTag; // open str and close str
typedef QMap<QChar, TextCustomTag> TextCustomTagsMap; typedef QMap<QChar, TextCustomTag> TextCustomTagsMap;
class ITextBlock; namespace Ui {
class Text { 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<Flag>;
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: public:
Text(int32 minResizeWidth = QFIXED_MAX); String(int32 minResizeWidth = QFIXED_MAX);
Text(const style::TextStyle &st, const QString &text, const TextParseOptions &options = _defaultOptions, int32 minResizeWidth = QFIXED_MAX, bool richText = false); String(const style::TextStyle &st, const QString &text, const TextParseOptions &options = _defaultOptions, int32 minResizeWidth = QFIXED_MAX, bool richText = false);
Text(const Text &other); String(const String &other);
Text(Text &&other); String(String &&other);
Text &operator=(const Text &other); String &operator=(const String &other);
Text &operator=(Text &&other); String &operator=(String &&other);
int countWidth(int width) const; int countWidth(int width) const;
int countHeight(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); 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<Flag>;
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 getState(QPoint point, int width, StateRequest request = StateRequest()) const;
StateResult getStateLeft(QPoint point, int width, int outerw, StateRequest request = StateRequest()) const { StateResult getStateLeft(QPoint point, int width, int outerw, StateRequest request = StateRequest()) const {
return getState(rtlpoint(point, outerw), width, request); 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 getStateElided(QPoint point, int width, StateRequestElided request = StateRequestElided()) const;
StateResult getStateElidedLeft(QPoint point, int width, int outerw, StateRequestElided request = StateRequestElided()) const { StateResult getStateElidedLeft(QPoint point, int width, int outerw, StateRequestElided request = StateRequestElided()) const {
return getStateElided(rtlpoint(point, outerw), width, request); return getStateElided(rtlpoint(point, outerw), width, request);
@ -195,14 +202,14 @@ public:
} }
void clear(); void clear();
~Text(); ~String();
private: private:
using TextBlocks = std::vector<std::unique_ptr<ITextBlock>>; using TextBlocks = std::vector<std::unique_ptr<AbstractBlock>>;
using TextLinks = QVector<ClickHandlerPtr>; using TextLinks = QVector<ClickHandlerPtr>;
uint16 countBlockEnd(const TextBlocks::const_iterator &i, const TextBlocks::const_iterator &e) const; 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 method for originalText(), originalTextWithEntities().
template <typename AppendPartCallback, typename ClickHandlerStartCallback, typename ClickHandlerFinishCallback, typename FlagsChangeCallback> template <typename AppendPartCallback, typename ClickHandlerStartCallback, typename ClickHandlerFinishCallback, typename FlagsChangeCallback>
@ -237,10 +244,14 @@ private:
Qt::LayoutDirection _startDir = Qt::LayoutDirectionAuto; Qt::LayoutDirection _startDir = Qt::LayoutDirectionAuto;
friend class TextParser; friend class Parser;
friend class TextPainter; friend class Renderer;
}; };
} // namespace Text
} // namespace Ui
inline TextSelection snapSelection(int from, int to) { inline TextSelection snapSelection(int from, int to) {
return { static_cast<uint16>(snap(from, 0, 0xFFFF)), static_cast<uint16>(snap(to, 0, 0xFFFF)) }; return { static_cast<uint16>(snap(from, 0, 0xFFFF)), static_cast<uint16>(snap(to, 0, 0xFFFF)) };
} }
@ -250,10 +261,10 @@ inline TextSelection shiftSelection(TextSelection selection, uint16 byLength) {
inline TextSelection unshiftSelection(TextSelection selection, uint16 byLength) { inline TextSelection unshiftSelection(TextSelection selection, uint16 byLength) {
return snapSelection(int(selection.from) - int(byLength), int(selection.to) - int(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()); 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()); return unshiftSelection(selection, byText.length());
} }

View file

@ -10,6 +10,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "core/crash_reports.h" #include "core/crash_reports.h"
// COPIED FROM qtextlayout.cpp AND MODIFIED // COPIED FROM qtextlayout.cpp AND MODIFIED
namespace Ui {
namespace Text {
namespace { namespace {
struct ScriptLine { struct ScriptLine {
@ -154,17 +156,17 @@ public:
void parseWords(QFixed minResizeWidth, int32 blockFrom) { void parseWords(QFixed minResizeWidth, int32 blockFrom) {
LineBreakHelper lbh; LineBreakHelper lbh;
// Helper for debugging crashes in text processing. // Helper for debugging crashes in text processing.
// //
// auto debugChars = QString(); // auto debugChars = QString();
// debugChars.reserve(str.size() * 7); // debugChars.reserve(str.size() * 7);
// for (const auto ch : str) { // for (const auto ch : str) {
// debugChars.append( // debugChars.append(
// "0x").append( // "0x").append(
// QString::number(ch.unicode(), 16).toUpper()).append( // QString::number(ch.unicode(), 16).toUpper()).append(
// ' '); // ' ');
// } // }
// LOG(("Text: %1, chars: %2").arg(str).arg(debugChars)); // LOG(("Text: %1, chars: %2").arg(str).arg(debugChars));
int item = -1; int item = -1;
int newItem = eng->findItem(0); 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<const TextBlock*>(this)->real_f_rbearing() : 0; return (type() == TextBlockTText) ? static_cast<const TextBlock*>(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); _flags |= ((TextBlockTText & 0x0F) << 8);
if (length) { if (length) {
style::font blockFont = font; 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) { , emoji(emoji) {
_flags |= ((TextBlockTEmoji & 0x0F) << 8); _flags |= ((TextBlockTEmoji & 0x0F) << 8);
_width = int(st::emojiSize + 2 * st::emojiPadding); _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); _flags |= ((TextBlockTSkip & 0x0F) << 8);
_width = w; _width = w;
} }
} // namespace Text
} // namespace Ui

View file

@ -9,6 +9,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "private/qfontengine_p.h" #include "private/qfontengine_p.h"
namespace Ui {
namespace Text {
enum TextBlockType { enum TextBlockType {
TextBlockTNewline = 0x01, TextBlockTNewline = 0x01,
TextBlockTText = 0x02, TextBlockTText = 0x02,
@ -26,9 +29,9 @@ enum TextBlockFlags {
TextBlockFPre = 0x40, TextBlockFPre = 0x40,
}; };
class ITextBlock { class AbstractBlock {
public: 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 { uint16 from() const {
@ -64,8 +67,8 @@ public:
return (_flags & 0xFF); return (_flags & 0xFF);
} }
virtual std::unique_ptr<ITextBlock> clone() const = 0; virtual std::unique_ptr<AbstractBlock> clone() const = 0;
virtual ~ITextBlock() { virtual ~AbstractBlock() {
} }
protected: protected:
@ -84,9 +87,9 @@ protected:
}; };
class NewlineBlock : public ITextBlock { class NewlineBlock : public AbstractBlock {
public: 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); _flags |= ((TextBlockTNewline & 0x0F) << 8);
} }
@ -94,17 +97,16 @@ public:
return _nextDir; return _nextDir;
} }
std::unique_ptr<ITextBlock> clone() const override { std::unique_ptr<AbstractBlock> clone() const override {
return std::make_unique<NewlineBlock>(*this); return std::make_unique<NewlineBlock>(*this);
} }
private: private:
Qt::LayoutDirection _nextDir; Qt::LayoutDirection _nextDir;
friend class Text; friend class String;
friend class TextParser; friend class Parser;
friend class Renderer;
friend class TextPainter;
}; };
@ -140,50 +142,48 @@ private:
}; };
class TextBlock : public ITextBlock { class TextBlock : public AbstractBlock {
public: public:
TextBlock(const style::font &font, const QString &str, QFixed minResizeWidth, uint16 from, uint16 length, uchar flags, uint16 lnkIndex); TextBlock(const style::font &font, const QString &str, QFixed minResizeWidth, uint16 from, uint16 length, uchar flags, uint16 lnkIndex);
std::unique_ptr<ITextBlock> clone() const override { std::unique_ptr<AbstractBlock> clone() const override {
return std::make_unique<TextBlock>(*this); return std::make_unique<TextBlock>(*this);
} }
private: private:
friend class ITextBlock; friend class AbstractBlock;
QFixed real_f_rbearing() const { QFixed real_f_rbearing() const {
return _words.isEmpty() ? 0 : _words.back().f_rbearing(); return _words.isEmpty() ? 0 : _words.back().f_rbearing();
} }
typedef QVector<TextWord> TextWords; using TextWords = QVector<TextWord>;
TextWords _words; TextWords _words;
friend class Text; friend class String;
friend class TextParser; friend class Parser;
friend class Renderer;
friend class BlockParser; friend class BlockParser;
friend class TextPainter;
}; };
class EmojiBlock : public ITextBlock { class EmojiBlock : public AbstractBlock {
public: public:
EmojiBlock(const style::font &font, const QString &str, uint16 from, uint16 length, uchar flags, uint16 lnkIndex, EmojiPtr emoji); EmojiBlock(const style::font &font, const QString &str, uint16 from, uint16 length, uchar flags, uint16 lnkIndex, EmojiPtr emoji);
std::unique_ptr<ITextBlock> clone() const { std::unique_ptr<AbstractBlock> clone() const override {
return std::make_unique<EmojiBlock>(*this); return std::make_unique<EmojiBlock>(*this);
} }
private: private:
EmojiPtr emoji = nullptr; EmojiPtr emoji = nullptr;
friend class Text; friend class String;
friend class TextParser; friend class Parser;
friend class Renderer;
friend class TextPainter;
}; };
class SkipBlock : public ITextBlock { class SkipBlock : public AbstractBlock {
public: public:
SkipBlock(const style::font &font, const QString &str, uint16 from, int32 w, int32 h, uint16 lnkIndex); SkipBlock(const style::font &font, const QString &str, uint16 from, int32 w, int32 h, uint16 lnkIndex);
@ -191,16 +191,18 @@ public:
return _height; return _height;
} }
std::unique_ptr<ITextBlock> clone() const override { std::unique_ptr<AbstractBlock> clone() const override {
return std::make_unique<SkipBlock>(*this); return std::make_unique<SkipBlock>(*this);
} }
private: private:
int32 _height; int32 _height;
friend class Text; friend class String;
friend class TextParser; friend class Parser;
friend class Renderer;
friend class TextPainter;
}; };
} // namespace Text
} // namespace Ui

View file

@ -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

View file

@ -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

View file

@ -35,7 +35,7 @@ private:
int _maxTextWidth = 0; int _maxTextWidth = 0;
int _textWidth = 0; int _textWidth = 0;
Text _text; Text::String _text;
}; };

View file

@ -198,7 +198,7 @@ private:
rpl::event_stream<bool> _checkedChanges; rpl::event_stream<bool> _checkedChanges;
QPixmap _checkCache; QPixmap _checkCache;
Text _text; Text::String _text;
style::align _checkAlignment = style::al_left; style::align _checkAlignment = style::al_left;
bool _allowMultiline = false; bool _allowMultiline = false;

View file

@ -306,7 +306,7 @@ void FlatLabel::mousePressEvent(QMouseEvent *e) {
dragActionStart(e->globalPos(), e->button()); 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; _lastMousePos = p;
auto state = dragActionUpdate(); auto state = dragActionUpdate();
@ -359,7 +359,7 @@ Text::StateResult FlatLabel::dragActionStart(const QPoint &p, Qt::MouseButton bu
return state; 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; _lastMousePos = p;
auto state = dragActionUpdate(); auto state = dragActionUpdate();
@ -715,7 +715,7 @@ std::unique_ptr<CrossFadeAnimation> FlatLabel::CrossFade(
return result; return result;
} }
Text::StateResult FlatLabel::dragActionUpdate() { Ui::Text::StateResult FlatLabel::dragActionUpdate() {
auto m = mapFromGlobal(_lastMousePos); auto m = mapFromGlobal(_lastMousePos);
auto state = getTextState(m); auto state = getTextState(m);
updateHover(state); updateHover(state);
@ -728,7 +728,7 @@ Text::StateResult FlatLabel::dragActionUpdate() {
return state; return state;
} }
void FlatLabel::updateHover(const Text::StateResult &state) { void FlatLabel::updateHover(const Ui::Text::StateResult &state) {
bool lnkChanged = ClickHandler::setActive(state.link, this); bool lnkChanged = ClickHandler::setActive(state.link, this);
if (!_selectable) { if (!_selectable) {
@ -791,15 +791,15 @@ void FlatLabel::refreshCursor(bool uponSymbol) {
} }
} }
Text::StateResult FlatLabel::getTextState(const QPoint &m) const { Ui::Text::StateResult FlatLabel::getTextState(const QPoint &m) const {
Text::StateRequestElided request; Ui::Text::StateRequestElided request;
request.align = _st.align; request.align = _st.align;
if (_selectable) { if (_selectable) {
request.flags |= Text::StateRequest::Flag::LookupSymbol; request.flags |= Ui::Text::StateRequest::Flag::LookupSymbol;
} }
int textWidth = width() - _st.margin.left() - _st.margin.right(); 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 heightExceeded = _st.maxHeight && (_st.maxHeight < _fullTextHeight || textWidth < _text.maxWidth());
bool renderElided = _breakEverywhere || heightExceeded; bool renderElided = _breakEverywhere || heightExceeded;
if (renderElided) { 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); auto lines = _st.maxHeight ? qMax(_st.maxHeight / lineHeight, 1) : ((height() / lineHeight) + 2);
request.lines = lines; request.lines = lines;
if (_breakEverywhere) { 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); state = _text.getStateElided(m - QPoint(_st.margin.left(), _st.margin.top()), textWidth, request);
} else { } else {

View file

@ -157,11 +157,11 @@ private:
void init(); void init();
void textUpdated(); void textUpdated();
Text::StateResult dragActionUpdate(); Ui::Text::StateResult dragActionUpdate();
Text::StateResult dragActionStart(const QPoint &p, Qt::MouseButton button); Ui::Text::StateResult dragActionStart(const QPoint &p, Qt::MouseButton button);
Text::StateResult dragActionFinish(const QPoint &p, Qt::MouseButton button); Ui::Text::StateResult dragActionFinish(const QPoint &p, Qt::MouseButton button);
void updateHover(const Text::StateResult &state); void updateHover(const Ui::Text::StateResult &state);
Text::StateResult getTextState(const QPoint &m) const; Ui::Text::StateResult getTextState(const QPoint &m) const;
void refreshCursor(bool uponSymbol); void refreshCursor(bool uponSymbol);
int countTextWidth() const; int countTextWidth() const;
@ -174,7 +174,7 @@ private:
}; };
void showContextMenu(QContextMenuEvent *e, ContextMenuReason reason); void showContextMenu(QContextMenuEvent *e, ContextMenuReason reason);
Text _text; Text::String _text;
const style::FlatLabel &_st; const style::FlatLabel &_st;
std::optional<QColor> _textColorOverride; std::optional<QColor> _textColorOverride;
float64 _opacity = 1.; float64 _opacity = 1.;

View file

@ -230,7 +230,7 @@ private:
int _x = -1; int _x = -1;
int _y = -1; int _y = -1;
int _width = 0; int _width = 0;
Text _text; Text::String _text;
style::color _color; style::color _color;
bool _over = false; bool _over = false;
QPixmap _cache; QPixmap _cache;

View file

@ -88,7 +88,7 @@ void Tooltip::popup(const QPoint &m, const QString &text, const style::Tooltip *
_point = m; _point = m;
_st = st; _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); _useTransparency = Platform::TranslucentWindowsSupported(_point);
setAttribute(Qt::WA_OpaquePaintEvent, !_useTransparency); setAttribute(Qt::WA_OpaquePaintEvent, !_useTransparency);

View file

@ -51,7 +51,7 @@ private:
const AbstractTooltipShower *_shower = nullptr; const AbstractTooltipShower *_shower = nullptr;
base::Timer _showTimer; base::Timer _showTimer;
Text _text; Text::String _text;
QPoint _point; QPoint _point;
const style::Tooltip *_st = nullptr; const style::Tooltip *_st = nullptr;

View file

@ -245,8 +245,10 @@ private:
}; };
template <typename BoxType, typename ...Args> class GenericBox;
template <typename BoxType = GenericBox, typename ...Args>
inline object_ptr<BoxType> Box(Args&&... args) { inline object_ptr<BoxType> Box(Args&&... args) {
auto parent = static_cast<QWidget*>(nullptr); const auto parent = static_cast<QWidget*>(nullptr);
return object_ptr<BoxType>(parent, std::forward<Args>(args)...); return object_ptr<BoxType>(parent, std::forward<Args>(args)...);
} }

View file

@ -684,7 +684,7 @@ void Notification::updateNotifyDisplay() {
if (!options.hideMessageText) { if (!options.hideMessageText) {
const HistoryItem *textCachedFor = nullptr; 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); QRect r(st::notifyPhotoPos.x() + st::notifyPhotoSize + st::notifyTextLeft, st::notifyItemTop + st::msgNameFont->height, itemWidth, 2 * st::dialogsTextFont->height);
if (_item) { if (_item) {
auto active = false, selected = false; auto active = false, selected = false;

View file

@ -45,7 +45,7 @@ public:
QString description() const { QString description() const {
return _description.toString(); return _description.toString();
} }
const Text &descriptionText() const { const Ui::Text::String &descriptionText() const {
return _description; return _description;
} }
void setDescription(const QString &description) { void setDescription(const QString &description) {
@ -102,7 +102,7 @@ private:
QString _copyOf; QString _copyOf;
QColor _value; QColor _value;
QString _valueString; QString _valueString;
Text _description = { st::windowMinWidth / 2 }; Ui::Text::String _description = { st::windowMinWidth / 2 };
OrderedSet<QString> _searchWords; OrderedSet<QString> _searchWords;
OrderedSet<QChar> _searchStartChars; OrderedSet<QChar> _searchStartChars;

View file

@ -94,7 +94,7 @@ private:
Received Received
}; };
struct Row { struct Row {
Text name; Ui::Text::String name;
QString letters; QString letters;
enum class Type { enum class Type {
User, User,
@ -107,7 +107,7 @@ private:
bool muted = false; bool muted = false;
bool pinned = false; bool pinned = false;
QString date; QString date;
Text text; Ui::Text::String text;
Status status = Status::None; Status status = Status::None;
bool selected = false; bool selected = false;
bool active = false; bool active = false;
@ -120,15 +120,15 @@ private:
QString date; QString date;
bool attached = false; bool attached = false;
bool tail = true; bool tail = true;
Text text = { st::msgMinWidth }; Ui::Text::String text = { st::msgMinWidth };
QVector<int> waveform; QVector<int> waveform;
int waveactive = 0; int waveactive = 0;
QString wavestatus; QString wavestatus;
QImage photo; QImage photo;
int photoWidth = 0; int photoWidth = 0;
int photoHeight = 0; int photoHeight = 0;
Text replyName = { st::msgMinWidth }; Ui::Text::String replyName = { st::msgMinWidth };
Text replyText = { st::msgMinWidth }; Ui::Text::String replyText = { st::msgMinWidth };
}; };
void prepare(); void prepare();
@ -177,7 +177,7 @@ private:
int _rowsTop = 0; int _rowsTop = 0;
std::vector<Row> _rows; std::vector<Row> _rows;
Text _topBarName; Ui::Text::String _topBarName;
QString _topBarStatus; QString _topBarStatus;
bool _topBarStatusActive = false; bool _topBarStatusActive = false;

View file

@ -12,10 +12,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "boxes/mute_settings_box.h" #include "boxes/mute_settings_box.h"
#include "boxes/add_contact_box.h" #include "boxes/add_contact_box.h"
#include "boxes/report_box.h" #include "boxes/report_box.h"
#include "boxes/generic_box.h"
#include "boxes/create_poll_box.h" #include "boxes/create_poll_box.h"
#include "boxes/peers/add_participants_box.h" #include "boxes/peers/add_participants_box.h"
#include "boxes/peers/add_to_contacts_box.h" #include "boxes/peers/add_to_contacts_box.h"
#include "ui/toast/toast.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 "auth_session.h"
#include "apiwrap.h" #include "apiwrap.h"
#include "mainwidget.h" #include "mainwidget.h"
@ -23,6 +27,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "observer_peer.h" #include "observer_peer.h"
#include "history/history.h" #include "history/history.h"
#include "window/window_session_controller.h" #include "window/window_session_controller.h"
#include "window/window_controller.h"
#include "support/support_helper.h" #include "support/support_helper.h"
#include "info/info_memento.h" #include "info/info_memento.h"
#include "info/info_controller.h" #include "info/info_controller.h"
@ -248,9 +253,9 @@ void Filler::addTogglePin() {
} }
void Filler::addInfo() { void Filler::addInfo() {
auto controller = _controller; const auto controller = _controller;
auto peer = _peer; const auto peer = _peer;
auto infoKey = (peer->isChat() || peer->isMegagroup()) const auto infoKey = (peer->isChat() || peer->isMegagroup())
? lng_context_view_group ? lng_context_view_group
: (peer->isUser() : (peer->isUser()
? lng_context_view_profile ? lng_context_view_profile
@ -324,7 +329,8 @@ void Filler::addToggleArchive() {
} }
void Filler::addBlockUser(not_null<UserData*> user) { void Filler::addBlockUser(not_null<UserData*> user) {
auto blockText = [](not_null<UserData*> user) { const auto window = &_controller->window()->controller();
const auto blockText = [](not_null<UserData*> user) {
return lang(user->isBlocked() return lang(user->isBlocked()
? ((user->isBot() && !user->isSupport()) ? ((user->isBot() && !user->isSupport())
? lng_profile_restart_bot ? lng_profile_restart_bot
@ -333,11 +339,13 @@ void Filler::addBlockUser(not_null<UserData*> user) {
? lng_profile_block_bot ? lng_profile_block_bot
: lng_profile_block_user)); : lng_profile_block_user));
}; };
auto blockAction = _addAction(blockText(user), [=] { const auto blockAction = _addAction(blockText(user), [=] {
if (user->isBlocked()) { if (user->isBlocked()) {
Auth().api().unblockUser(user); user->session().api().unblockUser(user);
} else if (user->isBot()) {
user->session().api().blockUser(user);
} else { } else {
Auth().api().blockUser(user); window->show(Box(PeerMenuBlockUserBox, user, window));
} }
}); });
@ -696,6 +704,77 @@ void PeerMenuCreatePoll(not_null<PeerData*> peer) {
}, box->lifetime()); }, box->lifetime());
} }
void PeerMenuBlockUserBox(
not_null<GenericBox*> box,
not_null<UserData*> user,
not_null<Window::Controller*> window) {
using Flag = MTPDpeerSettings::Flag;
const auto settings = user->settings().value_or(Flag(0));
const auto name = user->shortName();
box->addRow(object_ptr<Ui::FlatLabel>(
box,
rpl::single(
lng_blocked_list_confirm_text__generic<TextWithEntities>(
lt_name,
Ui::Text::Bold(name))),
st::blockUserConfirmation));
box->addSkip(st::boxMediumSkip);
const auto report = (settings & Flag::f_report_spam)
? box->addRow(object_ptr<Ui::Checkbox>(
box,
lang(lng_report_spam),
true,
st::defaultBoxCheckbox))
: nullptr;
if (report) {
box->addSkip(st::boxMediumSkip);
}
const auto clear = box->addRow(object_ptr<Ui::Checkbox>(
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<Ui::RpWidget> ShowForwardMessagesBox( QPointer<Ui::RpWidget> ShowForwardMessagesBox(
MessageIdsList &&items, MessageIdsList &&items,
FnMut<void()> &&successCallback) { FnMut<void()> &&successCallback) {

View file

@ -7,6 +7,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/ */
#pragma once #pragma once
class GenericBox;
namespace Ui { namespace Ui {
class RpWidget; class RpWidget;
} // namespace Ui } // namespace Ui
@ -17,6 +19,7 @@ class Folder;
namespace Window { namespace Window {
class Controller;
class SessionController; class SessionController;
enum class PeerMenuSource { enum class PeerMenuSource {
@ -51,6 +54,10 @@ void PeerMenuAddContact(not_null<UserData*> user);
void PeerMenuAddChannelMembers(not_null<ChannelData*> channel); void PeerMenuAddChannelMembers(not_null<ChannelData*> channel);
//void PeerMenuUngroupFeed(not_null<Data::Feed*> feed); // #feed //void PeerMenuUngroupFeed(not_null<Data::Feed*> feed); // #feed
void PeerMenuCreatePoll(not_null<PeerData*> peer); void PeerMenuCreatePoll(not_null<PeerData*> peer);
void PeerMenuBlockUserBox(
not_null<GenericBox*> box,
not_null<UserData*> user,
not_null<Window::Controller*> window);
void ToggleHistoryArchived(not_null<History*> history, bool archived); void ToggleHistoryArchived(not_null<History*> history, bool archived);
Fn<void()> ClearHistoryHandler(not_null<PeerData*> peer); Fn<void()> ClearHistoryHandler(not_null<PeerData*> peer);

View file

@ -745,6 +745,8 @@
<(src_loc)/ui/text/text_block.h <(src_loc)/ui/text/text_block.h
<(src_loc)/ui/text/text_entity.cpp <(src_loc)/ui/text/text_entity.cpp
<(src_loc)/ui/text/text_entity.h <(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.cpp
<(src_loc)/ui/toast/toast.h <(src_loc)/ui/toast/toast.h
<(src_loc)/ui/toast/toast_manager.cpp <(src_loc)/ui/toast/toast_manager.cpp