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_report_spam" = "Report Spam";
"lng_report_spam_and_leave" = "Report spam and leave";
"lng_report_spam_done" = "Thank you for your report.";
"lng_report_spam_sure_group" = "Are you sure you want to report spam in this group?";
"lng_report_spam_sure_channel" = "Are you sure you want to report spam in this channel?";
"lng_report_spam_ok" = "Report";
"lng_new_contact_block" = "Block user";
"lng_new_contact_block_done" = "{user} is now blocked.";
"lng_new_contact_add" = "Add contact";
"lng_new_contact_share" = "Share my phone number";
"lng_new_contact_share_done" = "{user} can now see your phone number.";
"lng_new_contact_add_name" = "Add {user} to contacts";
"lng_new_contact_add_done" = "{user} is now in your contact list.";
"lng_cant_send_to_not_contact" = "Sorry, you can only send messages to\nmutual contacts at the moment.\n{more_info}";
"lng_cant_invite_not_contact" = "Sorry, you can only add mutual contacts\nto groups at the moment.\n{more_info}";
"lng_cant_more_info" = "More info »";

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -100,7 +100,7 @@ public:
}
void refreshName(const style::PeerListItem &st);
const Text &name() const {
const Ui::Text::String &name() const {
return _name;
}
@ -203,8 +203,8 @@ private:
not_null<PeerData*> _peer;
std::unique_ptr<Ui::RippleAnimation> _ripple;
std::unique_ptr<Ui::RoundImageCheckbox> _checkbox;
Text _name;
Text _status;
Ui::Text::String _name;
Ui::Text::String _status;
StatusType _statusType = StatusType::Online;
crl::time _statusValidTill = 0;
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/widgets/labels.h"
#include "ui/widgets/input_fields.h"
#include "ui/text/text_utilities.h"
#include "info/profile/info_profile_cover.h"
#include "lang/lang_keys.h"
#include "window/window_controller.h"
#include "ui/toast/toast.h"
#include "auth_session.h"
#include "apiwrap.h"
#include "styles/style_boxes.h"
@ -29,12 +31,6 @@ QString UserPhone(not_null<UserData*> user) {
: phone;
}
TextWithEntities BoldText(const QString &text) {
auto result = TextWithEntities{ text };
result.entities.push_back({ EntityType::Bold, 0, text.size() });
return result;
}
} // namespace
AddToContactsBox::AddToContactsBox(
@ -163,6 +159,7 @@ void AddToContactsBox::initNameFields(
if (box) {
box->closeBox();
}
Ui::Toast::Show(lng_new_contact_add_done(lt_user, firstValue));
}).fail([=](const RPCError &error) {
}).send();
};
@ -170,21 +167,19 @@ void AddToContactsBox::initNameFields(
void AddToContactsBox::setupWarning(
not_null<Ui::VerticalLayout*> container) {
const auto name = _user->firstName.isEmpty()
? _user->lastName
: _user->firstName;
const auto name = _user->shortName();
const auto nameWithEntities = TextWithEntities{ name };
const auto text = _phone.isEmpty()
? lng_contact_phone_after__generic<TextWithEntities>(
lt_user,
nameWithEntities,
lt_visible,
BoldText(lang(lng_contact_phone_visible)),
Ui::Text::Bold(lang(lng_contact_phone_visible)),
lt_name,
nameWithEntities)
: lng_contact_phone_show__generic<TextWithEntities>(
lt_button,
BoldText(lang(lng_box_done).toUpper()),
Ui::Text::Bold(lang(lng_box_done).toUpper()),
lt_user,
TextWithEntities{ name });
container->add(

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -592,7 +592,7 @@ not_null<const PeerData*> PeerData::migrateToOrMe() const {
return this;
}
const Text &PeerData::topBarNameText() const {
const Ui::Text::String &PeerData::topBarNameText() const {
if (const auto to = migrateTo()) {
return to->topBarNameText();
} else if (const auto user = asUser()) {
@ -603,7 +603,7 @@ const Text &PeerData::topBarNameText() const {
return _nameText;
}
const Text &PeerData::nameText() const {
const Ui::Text::String &PeerData::nameText() const {
if (const auto to = migrateTo()) {
return to->nameText();
}
@ -611,7 +611,10 @@ const Text &PeerData::nameText() const {
}
const QString &PeerData::shortName() const {
return isUser() ? asUser()->firstName : name;
if (const auto user = asUser()) {
return user->firstName.isEmpty() ? user->lastName : user->firstName;
}
return name;
}
QString PeerData::userName() const {

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -91,7 +91,7 @@ public:
uint64 sortKey() const;
void validateListEntryCache() const;
const Text &listEntryCache() const {
const Ui::Text::String &listEntryCache() const {
return _listEntryCache;
}
@ -104,7 +104,7 @@ private:
Key _id;
int _pos = 0;
mutable uint32 _listEntryCacheVersion = 0;
mutable Text _listEntryCache;
mutable Ui::Text::String _listEntryCache;
};
@ -125,7 +125,7 @@ private:
Key _searchInChat;
not_null<HistoryItem*> _item;
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());
if (((_mouseAction == MouseAction::Selecting && _selectedItem != nullptr) || (_mouseAction == MouseAction::None)) && _mouseSelectType == TextSelectType::Letters && _mouseActionItem) {
StateRequest request;
request.flags |= Text::StateRequest::Flag::LookupSymbol;
request.flags |= Ui::Text::StateRequest::Flag::LookupSymbol;
auto dragState = _mouseActionItem->textState(_dragStartPosition, request);
if (dragState.cursor == CursorState::Text) {
_mouseTextSymbol = dragState.symbol;
@ -968,7 +968,7 @@ void InnerWidget::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
mapFromGlobal(_mousePosition),
App::mousedItem());
StateRequest request;
request.flags |= Text::StateRequest::Flag::LookupSymbol;
request.flags |= Ui::Text::StateRequest::Flag::LookupSymbol;
auto dragState = App::mousedItem()->textState(mousePos, request);
if (dragState.cursor == CursorState::Text
&& base::in_range(dragState.symbol, selFrom, selTo)) {
@ -1308,7 +1308,7 @@ void InnerWidget::mouseActionStart(const QPoint &screenPos, Qt::MouseButton butt
TextState dragState;
if (_trippleClickTimer.isActive() && (screenPos - _trippleClickPoint).manhattanLength() < QApplication::startDragDistance()) {
StateRequest request;
request.flags = Text::StateRequest::Flag::LookupSymbol;
request.flags = Ui::Text::StateRequest::Flag::LookupSymbol;
dragState = _mouseActionItem->textState(_dragStartPosition, request);
if (dragState.cursor == CursorState::Text) {
auto selection = TextSelection { dragState.symbol, dragState.symbol };
@ -1322,7 +1322,7 @@ void InnerWidget::mouseActionStart(const QPoint &screenPos, Qt::MouseButton butt
}
} else if (App::pressedItem()) {
StateRequest request;
request.flags = Text::StateRequest::Flag::LookupSymbol;
request.flags = Ui::Text::StateRequest::Flag::LookupSymbol;
dragState = _mouseActionItem->textState(_dragStartPosition, request);
}
if (_mouseSelectType != TextSelectType::Paragraphs) {
@ -1455,7 +1455,7 @@ void InnerWidget::updateSelected() {
}
StateRequest request;
if (_mouseAction == MouseAction::Selecting) {
request.flags |= Text::StateRequest::Flag::LookupSymbol;
request.flags |= Ui::Text::StateRequest::Flag::LookupSymbol;
} else {
selectingText = false;
}
@ -1563,7 +1563,7 @@ void InnerWidget::performDrag() {
// uponSelected = _selected.contains(_mouseActionItem);
// } else {
// StateRequest request;
// request.flags |= Text::StateRequest::Flag::LookupSymbol;
// request.flags |= Ui::Text::StateRequest::Flag::LookupSymbol;
// auto dragState = _mouseActionItem->textState(_dragStartPosition.x(), _dragStartPosition.y(), request);
// uponSelected = (dragState.cursor == CursorState::Text);
// if (uponSelected) {

View File

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

View File

@ -360,7 +360,7 @@ public:
mtpRequestId sendRequestId = 0;
Text cloudDraftTextCache;
Ui::Text::String cloudDraftTextCache;
private:
friend class HistoryBlock;
@ -516,7 +516,7 @@ private:
base::flat_map<not_null<UserData*>, crl::time> _typing;
base::flat_map<not_null<UserData*>, SendAction> _sendActions;
QString _sendActionString;
Text _sendActionText;
Ui::Text::String _sendActionText;
Ui::SendActionAnimation _sendActionAnimation;
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;
if (_trippleClickTimer.isActive() && (screenPos - _trippleClickPoint).manhattanLength() < QApplication::startDragDistance()) {
StateRequest request;
request.flags = Text::StateRequest::Flag::LookupSymbol;
request.flags = Ui::Text::StateRequest::Flag::LookupSymbol;
dragState = mouseActionView->textState(_dragStartPosition, request);
if (dragState.cursor == CursorState::Text) {
TextSelection selStatus = { dragState.symbol, dragState.symbol };
@ -1060,7 +1060,7 @@ void HistoryInner::mouseActionStart(const QPoint &screenPos, Qt::MouseButton but
}
} else if (App::pressedItem()) {
StateRequest request;
request.flags = Text::StateRequest::Flag::LookupSymbol;
request.flags = Ui::Text::StateRequest::Flag::LookupSymbol;
dragState = mouseActionView->textState(_dragStartPosition, request);
}
if (_mouseSelectType != TextSelectType::Paragraphs) {
@ -1144,7 +1144,7 @@ std::unique_ptr<QMimeData> HistoryInner::prepareDrag() {
&& (_selected.find(_dragStateItem) != _selected.cend());
} else {
StateRequest request;
request.flags |= Text::StateRequest::Flag::LookupSymbol;
request.flags |= Ui::Text::StateRequest::Flag::LookupSymbol;
auto dragState = mouseActionView->textState(_dragStartPosition, request);
uponSelected = (dragState.cursor == CursorState::Text);
if (uponSelected) {
@ -1416,7 +1416,7 @@ void HistoryInner::mouseDoubleClickEvent(QMouseEvent *e) {
&& (_selected.empty()
|| _selected.cbegin()->second != FullSelection)))) {
StateRequest request;
request.flags |= Text::StateRequest::Flag::LookupSymbol;
request.flags |= Ui::Text::StateRequest::Flag::LookupSymbol;
auto dragState = mouseActionView->textState(_dragStartPosition, request);
if (dragState.cursor == CursorState::Text) {
_mouseTextSymbol = dragState.symbol;
@ -1478,7 +1478,7 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
if (App::mousedItem() && App::mousedItem() == App::hoveredItem()) {
auto mousePos = mapPointToItem(mapFromGlobal(_mousePosition), App::mousedItem());
StateRequest request;
request.flags |= Text::StateRequest::Flag::LookupSymbol;
request.flags |= Ui::Text::StateRequest::Flag::LookupSymbol;
auto dragState = App::mousedItem()->textState(mousePos, request);
if (dragState.cursor == CursorState::Text
&& dragState.symbol >= selFrom
@ -2556,7 +2556,7 @@ void HistoryInner::mouseActionUpdate() {
if (!dragState.link) {
StateRequest request;
if (_mouseAction == MouseAction::Selecting) {
request.flags |= Text::StateRequest::Flag::LookupSymbol;
request.flags |= Ui::Text::StateRequest::Flag::LookupSymbol;
} else {
selectingText = false;
}
@ -3142,7 +3142,7 @@ QString HistoryInner::tooltipText() const {
StateRequest request;
const auto local = mapFromGlobal(_mousePosition);
const auto point = _widget->clampMousePosition(local);
request.flags |= Text::StateRequest::Flag::LookupCustomTooltip;
request.flags |= Ui::Text::StateRequest::Flag::LookupCustomTooltip;
const auto state = view->textState(
mapPointToItem(point, view),
request);

View File

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

View File

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

View File

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

View File

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

View File

@ -37,14 +37,14 @@ QSize HistoryMedia::countCurrentSize(int newWidth) {
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()) {
return Text();
return {};
}
const auto minResizeWidth = st::minPhotoSize
- st::msgPadding.left()
- st::msgPadding.right();
auto result = Text(minResizeWidth);
auto result = Ui::Text::String(minResizeWidth);
result.setMarkedText(
st::messageTextStyle,
item->originalText(),

View File

@ -236,7 +236,7 @@ protected:
using InfoDisplayType = HistoryView::InfoDisplayType;
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) {
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -67,15 +67,52 @@ static constexpr TextSelection AllTextSelection = { 0, 0xFFFF };
typedef QPair<QString, QString> TextCustomTag; // open str and close str
typedef QMap<QChar, TextCustomTag> TextCustomTagsMap;
class ITextBlock;
class Text {
namespace Ui {
namespace Text {
class AbstractBlock;
struct StateRequest {
enum class Flag {
BreakEverywhere = (1 << 0),
LookupSymbol = (1 << 1),
LookupLink = (1 << 2),
LookupCustomTooltip = (1 << 3),
};
using Flags = base::flags<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:
Text(int32 minResizeWidth = QFIXED_MAX);
Text(const style::TextStyle &st, const QString &text, const TextParseOptions &options = _defaultOptions, int32 minResizeWidth = QFIXED_MAX, bool richText = false);
Text(const Text &other);
Text(Text &&other);
Text &operator=(const Text &other);
Text &operator=(Text &&other);
String(int32 minResizeWidth = QFIXED_MAX);
String(const style::TextStyle &st, const QString &text, const TextParseOptions &options = _defaultOptions, int32 minResizeWidth = QFIXED_MAX, bool richText = false);
String(const String &other);
String(String &&other);
String &operator=(const String &other);
String &operator=(String &&other);
int countWidth(int width) const;
int countHeight(int width) const;
@ -113,40 +150,10 @@ public:
drawElided(p, rtl() ? right : (outerw - right - width), top, width, lines, align, yFrom, yTo, removeFromEnd, breakEverywhere, selection);
}
struct StateRequest {
enum class Flag {
BreakEverywhere = (1 << 0),
LookupSymbol = (1 << 1),
LookupLink = (1 << 2),
LookupCustomTooltip = (1 << 3),
};
using Flags = base::flags<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 getStateLeft(QPoint point, int width, int outerw, StateRequest request = StateRequest()) const {
return getState(rtlpoint(point, outerw), width, request);
}
struct StateRequestElided : public StateRequest {
StateRequestElided() {
}
StateRequestElided(const StateRequest &other) : StateRequest(other) {
}
int lines = 1;
int removeFromEnd = 0;
};
StateResult getStateElided(QPoint point, int width, StateRequestElided request = StateRequestElided()) const;
StateResult getStateElidedLeft(QPoint point, int width, int outerw, StateRequestElided request = StateRequestElided()) const {
return getStateElided(rtlpoint(point, outerw), width, request);
@ -195,14 +202,14 @@ public:
}
void clear();
~Text();
~String();
private:
using TextBlocks = std::vector<std::unique_ptr<ITextBlock>>;
using TextBlocks = std::vector<std::unique_ptr<AbstractBlock>>;
using TextLinks = QVector<ClickHandlerPtr>;
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 <typename AppendPartCallback, typename ClickHandlerStartCallback, typename ClickHandlerFinishCallback, typename FlagsChangeCallback>
@ -237,10 +244,14 @@ private:
Qt::LayoutDirection _startDir = Qt::LayoutDirectionAuto;
friend class TextParser;
friend class TextPainter;
friend class Parser;
friend class Renderer;
};
} // namespace Text
} // namespace Ui
inline TextSelection snapSelection(int from, int to) {
return { static_cast<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) {
return snapSelection(int(selection.from) - int(byLength), int(selection.to) - int(byLength));
}
inline TextSelection shiftSelection(TextSelection selection, const Text &byText) {
inline TextSelection shiftSelection(TextSelection selection, const Ui::Text::String &byText) {
return shiftSelection(selection, byText.length());
}
inline TextSelection unshiftSelection(TextSelection selection, const Text &byText) {
inline TextSelection unshiftSelection(TextSelection selection, const Ui::Text::String &byText) {
return unshiftSelection(selection, byText.length());
}

View File

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

View File

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

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 _textWidth = 0;
Text _text;
Text::String _text;
};

View File

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

View File

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

View File

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

View File

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

View File

@ -88,7 +88,7 @@ void Tooltip::popup(const QPoint &m, const QString &text, const style::Tooltip *
_point = m;
_st = st;
_text = Text(_st->textStyle, text, _textPlainOptions, _st->widthMax, true);
_text = Text::String(_st->textStyle, text, _textPlainOptions, _st->widthMax, true);
_useTransparency = Platform::TranslucentWindowsSupported(_point);
setAttribute(Qt::WA_OpaquePaintEvent, !_useTransparency);

View File

@ -51,7 +51,7 @@ private:
const AbstractTooltipShower *_shower = nullptr;
base::Timer _showTimer;
Text _text;
Text::String _text;
QPoint _point;
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) {
auto parent = static_cast<QWidget*>(nullptr);
const auto parent = static_cast<QWidget*>(nullptr);
return object_ptr<BoxType>(parent, std::forward<Args>(args)...);
}

View File

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

View File

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

View File

@ -94,7 +94,7 @@ private:
Received
};
struct Row {
Text name;
Ui::Text::String name;
QString letters;
enum class Type {
User,
@ -107,7 +107,7 @@ private:
bool muted = false;
bool pinned = false;
QString date;
Text text;
Ui::Text::String text;
Status status = Status::None;
bool selected = false;
bool active = false;
@ -120,15 +120,15 @@ private:
QString date;
bool attached = false;
bool tail = true;
Text text = { st::msgMinWidth };
Ui::Text::String text = { st::msgMinWidth };
QVector<int> waveform;
int waveactive = 0;
QString wavestatus;
QImage photo;
int photoWidth = 0;
int photoHeight = 0;
Text replyName = { st::msgMinWidth };
Text replyText = { st::msgMinWidth };
Ui::Text::String replyName = { st::msgMinWidth };
Ui::Text::String replyText = { st::msgMinWidth };
};
void prepare();
@ -177,7 +177,7 @@ private:
int _rowsTop = 0;
std::vector<Row> _rows;
Text _topBarName;
Ui::Text::String _topBarName;
QString _topBarStatus;
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/add_contact_box.h"
#include "boxes/report_box.h"
#include "boxes/generic_box.h"
#include "boxes/create_poll_box.h"
#include "boxes/peers/add_participants_box.h"
#include "boxes/peers/add_to_contacts_box.h"
#include "ui/toast/toast.h"
#include "ui/text/text_utilities.h"
#include "ui/widgets/labels.h"
#include "ui/widgets/checkbox.h"
#include "auth_session.h"
#include "apiwrap.h"
#include "mainwidget.h"
@ -23,6 +27,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "observer_peer.h"
#include "history/history.h"
#include "window/window_session_controller.h"
#include "window/window_controller.h"
#include "support/support_helper.h"
#include "info/info_memento.h"
#include "info/info_controller.h"
@ -248,9 +253,9 @@ void Filler::addTogglePin() {
}
void Filler::addInfo() {
auto controller = _controller;
auto peer = _peer;
auto infoKey = (peer->isChat() || peer->isMegagroup())
const auto controller = _controller;
const auto peer = _peer;
const auto infoKey = (peer->isChat() || peer->isMegagroup())
? lng_context_view_group
: (peer->isUser()
? lng_context_view_profile
@ -324,7 +329,8 @@ void Filler::addToggleArchive() {
}
void Filler::addBlockUser(not_null<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()
? ((user->isBot() && !user->isSupport())
? lng_profile_restart_bot
@ -333,11 +339,13 @@ void Filler::addBlockUser(not_null<UserData*> user) {
? lng_profile_block_bot
: lng_profile_block_user));
};
auto blockAction = _addAction(blockText(user), [=] {
const auto blockAction = _addAction(blockText(user), [=] {
if (user->isBlocked()) {
Auth().api().unblockUser(user);
user->session().api().unblockUser(user);
} else if (user->isBot()) {
user->session().api().blockUser(user);
} else {
Auth().api().blockUser(user);
window->show(Box(PeerMenuBlockUserBox, user, window));
}
});
@ -696,6 +704,77 @@ void PeerMenuCreatePoll(not_null<PeerData*> peer) {
}, 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(
MessageIdsList &&items,
FnMut<void()> &&successCallback) {

View File

@ -7,6 +7,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
class GenericBox;
namespace Ui {
class RpWidget;
} // namespace Ui
@ -17,6 +19,7 @@ class Folder;
namespace Window {
class Controller;
class SessionController;
enum class PeerMenuSource {
@ -51,6 +54,10 @@ void PeerMenuAddContact(not_null<UserData*> user);
void PeerMenuAddChannelMembers(not_null<ChannelData*> channel);
//void PeerMenuUngroupFeed(not_null<Data::Feed*> feed); // #feed
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);
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_entity.cpp
<(src_loc)/ui/text/text_entity.h
<(src_loc)/ui/text/text_utilities.cpp
<(src_loc)/ui/text/text_utilities.h
<(src_loc)/ui/toast/toast.cpp
<(src_loc)/ui/toast/toast.h
<(src_loc)/ui/toast/toast_manager.cpp