Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Eric Kotato 2020-06-26 07:24:19 +03:00
commit 7afb927acf
17 changed files with 101 additions and 113 deletions

View file

@ -158,8 +158,10 @@ void ActivateClickHandler(
not_null<QWidget*> guard,
ClickHandlerPtr handler,
ClickContext context) {
crl::on_main(guard, [=] {
handler->onClick(context);
crl::on_main(guard, [=, weak = std::weak_ptr<ClickHandler>(handler)] {
if (const auto strong = weak.lock()) {
strong->onClick(context);
}
});
}

View file

@ -29,7 +29,7 @@ protected:
};
enum class EntityType;
enum class EntityType : uchar;
class ClickHandler {
public:
virtual ~ClickHandler() {

View file

@ -43,14 +43,19 @@ void Integration::startFontsEnd() {
}
std::shared_ptr<ClickHandler> Integration::createLinkHandler(
EntityType type,
const QString &text,
const QString &data,
const TextParseOptions &options) {
switch (type) {
const EntityLinkData &data,
const std::any &context) {
switch (data.type) {
case EntityType::CustomUrl:
return !data.isEmpty()
? std::make_shared<UrlClickHandler>(data, false)
return !data.data.isEmpty()
? std::make_shared<UrlClickHandler>(data.data, false)
: nullptr;
case EntityType::Email:
case EntityType::Url:
return !data.data.isEmpty()
? std::make_shared<UrlClickHandler>(
data.data,
data.shown == EntityLinkShown::Full)
: nullptr;
}
return nullptr;

View file

@ -8,6 +8,8 @@
#include "base/basic_types.h"
#include <any>
// Methods that must be implemented outside lib_ui.
class QString;
@ -16,7 +18,7 @@ class QVariant;
struct TextParseOptions;
class ClickHandler;
enum class EntityType;
struct EntityLinkData;
namespace Ui {
namespace Emoji {
@ -43,10 +45,8 @@ public:
virtual void startFontsEnd();
[[nodiscard]] virtual std::shared_ptr<ClickHandler> createLinkHandler(
EntityType type,
const QString &text,
const QString &data,
const TextParseOptions &options);
const EntityLinkData &data,
const std::any &context);
[[nodiscard]] virtual bool handleUrlClick(
const QString &url,
const QVariant &context);

View file

@ -101,7 +101,7 @@ void BoxContent::onScrollToY(int top, int bottom) {
}
}
void BoxContent::onDraggingScrollDelta(int delta) {
void BoxContent::scrollByDraggingDelta(int delta) {
_draggingScrollDelta = _scroll ? delta : 0;
if (_draggingScrollDelta) {
if (!_draggingScrollTimer) {

View file

@ -192,11 +192,11 @@ public:
getDelegate()->setNoContentMargin(noContentMargin);
}
void scrollByDraggingDelta(int delta);
public slots:
void onScrollToY(int top, int bottom = -1);
void onDraggingScrollDelta(int delta);
protected:
virtual void prepare() = 0;

View file

@ -473,7 +473,7 @@ void LayerStackWidget::closeLayer(not_null<LayerWidget*> layer) {
return;
}
if (layer == _specialLayer) {
if (layer == _specialLayer || layer == _mainMenu) {
hideAll(anim::type::normal);
} else if (layer == currentLayer()) {
if (_layers.size() == 1) {

View file

@ -37,8 +37,8 @@ void DrainMainQueue(); // Needed only if UseMainQueueGeneric() is false.
#ifdef Q_OS_MAC
#include "ui/platform/mac/ui_utility_mac.h"
#elif defined Q_OS_LINUX // Q_OS_MAC
#elif defined Q_OS_UNIX // Q_OS_MAC
#include "ui/platform/linux/ui_utility_linux.h"
#elif defined Q_OS_WINRT || defined Q_OS_WIN // Q_OS_MAC || Q_OS_LINUX
#elif defined Q_OS_WINRT || defined Q_OS_WIN // Q_OS_MAC || Q_OS_UNIX
#include "ui/platform/win/ui_utility_win.h"
#endif // Q_OS_MAC || Q_OS_LINUX || Q_OS_WINRT || Q_OS_WIN
#endif // Q_OS_MAC || Q_OS_UNIX || Q_OS_WINRT || Q_OS_WIN

View file

@ -25,9 +25,9 @@ void style_InitFontsResource() {
Q_INIT_RESOURCE(win);
#elif defined Q_OS_MAC // Q_OS_WIN
Q_INIT_RESOURCE(mac);
#elif defined Q_OS_LINUX && !defined DESKTOP_APP_USE_PACKAGED // Q_OS_WIN || Q_OS_MAC
#elif defined Q_OS_UNIX && !defined DESKTOP_APP_USE_PACKAGED // Q_OS_WIN || Q_OS_MAC
Q_INIT_RESOURCE(linux);
#endif // Q_OS_WIN || Q_OS_MAC || (Q_OS_LINUX && !DESKTOP_APP_USE_PACKAGED)
#endif // Q_OS_WIN || Q_OS_MAC || (Q_OS_UNIX && !DESKTOP_APP_USE_PACKAGED)
}
namespace style {

View file

@ -263,33 +263,18 @@ public:
Parser(
not_null<String*> string,
const QString &text,
const TextParseOptions &options);
const TextParseOptions &options,
const std::any &context);
Parser(
not_null<String*> string,
const TextWithEntities &textWithEntities,
const TextParseOptions &options);
const TextParseOptions &options,
const std::any &context);
private:
struct ReadyToken {
};
enum LinkDisplayStatus {
LinkDisplayedFull,
LinkDisplayedElided,
};
struct TextLinkData {
TextLinkData() = default;
TextLinkData(
EntityType type,
const QString &text,
const QString &data,
LinkDisplayStatus displayStatus);
EntityType type = EntityType::Invalid;
QString text, data;
LinkDisplayStatus displayStatus = LinkDisplayedFull;
};
class StartedEntity {
public:
explicit StartedEntity(TextBlockFlags flags);
@ -307,6 +292,7 @@ private:
not_null<String*> string,
TextWithEntities &&source,
const TextParseOptions &options,
const std::any &context,
ReadyToken);
void trimSourceRange();
@ -336,14 +322,11 @@ private:
void computeLinkText(
const QString &linkData,
QString *outLinkText,
LinkDisplayStatus *outDisplayStatus);
static ClickHandlerPtr CreateHandlerForLink(
const TextLinkData &link,
const TextParseOptions &options);
EntityLinkShown *outShown);
const not_null<String*> _t;
const TextWithEntities _source;
const std::any &_context;
const QChar * const _start = nullptr;
const QChar *_end = nullptr; // mutable, because we trim by decrementing.
const QChar *_ptr = nullptr;
@ -355,7 +338,7 @@ private:
const QFixed _stopAfterWidth; // summary width of all added words
const bool _checkTilde = false; // do we need a special text block for tilde symbol
std::vector<TextLinkData> _links;
std::vector<EntityLinkData> _links;
base::flat_map<
const QChar*,
std::vector<StartedEntity>> _startedEntities;
@ -379,17 +362,6 @@ private:
};
Parser::TextLinkData::TextLinkData(
EntityType type,
const QString &text,
const QString &data,
LinkDisplayStatus displayStatus)
: type(type)
, text(text)
, data(data)
, displayStatus(displayStatus) {
}
Parser::StartedEntity::StartedEntity(TextBlockFlags flags) : _value(flags) {
Expects(_value >= 0 && _value < int(kStringLinkIndexShift));
}
@ -415,22 +387,26 @@ std::optional<uint16> Parser::StartedEntity::lnkIndex() const {
Parser::Parser(
not_null<String*> string,
const QString &text,
const TextParseOptions &options)
const TextParseOptions &options,
const std::any &context)
: Parser(
string,
PrepareRichFromPlain(text, options),
options,
context,
ReadyToken()) {
}
Parser::Parser(
not_null<String*> string,
const TextWithEntities &textWithEntities,
const TextParseOptions &options)
const TextParseOptions &options,
const std::any &context)
: Parser(
string,
PrepareRichFromRich(textWithEntities, options),
options,
context,
ReadyToken()) {
}
@ -438,9 +414,11 @@ Parser::Parser(
not_null<String*> string,
TextWithEntities &&source,
const TextParseOptions &options,
const std::any &context,
ReadyToken)
: _t(string)
, _source(std::move(source))
, _context(context)
, _start(_source.text.constData())
, _end(_start + _source.text.size())
, _ptr(_start)
@ -552,7 +530,7 @@ bool Parser::checkEntities() {
}
auto flags = TextBlockFlags();
auto link = TextLinkData();
auto link = EntityLinkData();
const auto entityType = _waitingEntity->type();
const auto entityLength = _waitingEntity->length();
const auto entityBegin = _start + _waitingEntity->offset();
@ -584,7 +562,7 @@ bool Parser::checkEntities() {
link.type = entityType;
link.data = QString(entityBegin, entityLength);
if (link.type == EntityType::Url) {
computeLinkText(link.data, &link.text, &link.displayStatus);
computeLinkText(link.data, &link.text, &link.shown);
} else {
link.text = link.data;
}
@ -745,7 +723,10 @@ bool Parser::readCommand() {
case TextCommandLinkText: {
createBlock();
int32 len = _ptr->unicode();
_links.emplace_back(EntityType::CustomUrl, QString(), QString(++_ptr, len), LinkDisplayedFull);
_links.push_back(EntityLinkData{
.data = QString(++_ptr, len),
.type = EntityType::CustomUrl
});
_lnkIndex = kStringLinkIndexShift + _links.size();
} break;
@ -942,9 +923,9 @@ void Parser::finalize(const TextParseOptions &options) {
}
_t->_links.resize(index);
const auto handler = CreateHandlerForLink(
const auto handler = Integration::Instance().createLinkHandler(
_links[realIndex - 1],
options);
_context);
if (handler) {
_t->setLink(index, handler);
}
@ -954,7 +935,10 @@ void Parser::finalize(const TextParseOptions &options) {
_t->_text.squeeze();
}
void Parser::computeLinkText(const QString &linkData, QString *outLinkText, LinkDisplayStatus *outDisplayStatus) {
void Parser::computeLinkText(
const QString &linkData,
QString *outLinkText,
EntityLinkShown *outShown) {
auto url = QUrl(linkData);
auto good = QUrl(url.isValid()
? url.toEncoded()
@ -963,28 +947,9 @@ void Parser::computeLinkText(const QString &linkData, QString *outLinkText, Link
? good.toDisplayString()
: linkData;
*outLinkText = _t->_st->font->elided(readable, st::linkCropLimit);
*outDisplayStatus = (*outLinkText == readable) ? LinkDisplayedFull : LinkDisplayedElided;
}
ClickHandlerPtr Parser::CreateHandlerForLink(
const TextLinkData &link,
const TextParseOptions &options) {
const auto result = Integration::Instance().createLinkHandler(
link.type,
link.text,
link.data,
options);
if (result) {
return result;
}
switch (link.type) {
case EntityType::Email:
case EntityType::Url:
return std::make_shared<UrlClickHandler>(
link.data,
link.displayStatus == LinkDisplayedFull);
}
return nullptr;
*outShown = (*outLinkText == readable)
? EntityLinkShown::Full
: EntityLinkShown::Partial;
}
namespace {
@ -2707,7 +2672,7 @@ void String::setText(const style::TextStyle &st, const QString &text, const Text
_st = &st;
clear();
{
Parser parser(this, text, options);
Parser parser(this, text, options, {});
}
recountNaturalSize(true, options.dir);
}
@ -2842,7 +2807,7 @@ int String::countMaxMonospaceWidth() const {
return result.ceil().toInt();
}
void String::setMarkedText(const style::TextStyle &st, const TextWithEntities &textWithEntities, const TextParseOptions &options) {
void String::setMarkedText(const style::TextStyle &st, const TextWithEntities &textWithEntities, const TextParseOptions &options, const std::any &context) {
_st = &st;
clear();
{
@ -2870,9 +2835,9 @@ void String::setMarkedText(const style::TextStyle &st, const TextWithEntities &t
// }
// }
// newText.append("},\n\n").append(text);
// Parser parser(this, { newText, EntitiesInText() }, options);
// Parser parser(this, { newText, EntitiesInText() }, options, context);
Parser parser(this, textWithEntities, options);
Parser parser(this, textWithEntities, options, context);
}
recountNaturalSize(true, options.dir);
}

View file

@ -13,6 +13,7 @@
#include "base/flags.h"
#include <private/qfixed_p.h>
#include <any>
static const QChar TextCommand(0x0010);
enum TextCommands {
@ -126,7 +127,7 @@ public:
void countLineWidths(int width, QVector<int> *lineWidths, bool breakEverywhere = false) const;
void setText(const style::TextStyle &st, const QString &text, const TextParseOptions &options = _defaultOptions);
void setRichText(const style::TextStyle &st, const QString &text, TextParseOptions options = _defaultOptions);
void setMarkedText(const style::TextStyle &st, const TextWithEntities &textWithEntities, const TextParseOptions &options = _defaultOptions);
void setMarkedText(const style::TextStyle &st, const TextWithEntities &textWithEntities, const TextParseOptions &options = _defaultOptions, const std::any &context = {});
void setLink(uint16 lnkIndex, const ClickHandlerPtr &lnk);
bool hasLinks() const;

View file

@ -12,7 +12,7 @@
#include <QtCore/QVector>
#include <QtGui/QClipboard>
enum class EntityType {
enum class EntityType : uchar {
Invalid = 0,
Url,
@ -33,6 +33,18 @@ enum class EntityType {
Pre, // block
};
enum class EntityLinkShown : uchar {
Full,
Partial,
};
struct EntityLinkData {
QString text;
QString data;
EntityType type = EntityType::Invalid;
EntityLinkShown shown = EntityLinkShown::Full;
};
class EntityInText;
using EntitiesInText = QList<EntityInText>;
@ -226,11 +238,6 @@ enum {
TextParseHashtags = 0x010,
TextParseBotCommands = 0x020,
TextParseMarkdown = 0x040,
TextTwitterMentions = 0x100,
TextTwitterHashtags = 0x200,
TextInstagramMentions = 0x400,
TextInstagramHashtags = 0x800,
};
struct TextWithTags {

View file

@ -58,11 +58,11 @@ public:
void clearState() override;
void paintRipple(QPainter &p, int x, int y, const QColor *colorOverride = nullptr);
~RippleButton();
protected:
void paintRipple(QPainter &p, int x, int y, const QColor *colorOverride = nullptr);
void onStateChanged(State was, StateChangeSource source) override;
virtual QImage prepareRippleMask() const;

View file

@ -247,15 +247,16 @@ void InnerDropdown::hideFinished() {
void InnerDropdown::prepareCache() {
if (_a_opacity.animating()) return;
const auto animating = _a_show.animating();
auto showAnimation = base::take(_a_show);
auto showAnimationData = base::take(_showAnimation);
showChildren();
_cache = GrabWidget(this);
_showAnimation = base::take(showAnimationData);
_a_show = base::take(showAnimation);
if (_a_show.animating()) {
if (animating) {
hideChildren();
}
_showAnimation = base::take(showAnimationData);
_a_show = base::take(showAnimation);
}
void InnerDropdown::startOpacityAnimation(bool hiding) {

View file

@ -2930,10 +2930,15 @@ void InputField::inputMethodEventInner(QInputMethodEvent *e) {
startPlaceholderAnimation();
}
_inputMethodCommit = e->commitString();
const auto weak = Ui::MakeWeak(this);
_inner->QTextEdit::inputMethodEvent(e);
const auto text = *base::take(_inputMethodCommit);
if (!processMarkdownReplaces(text)) {
processInstantReplaces(text);
if (weak) {
const auto text = *base::take(_inputMethodCommit);
if (!processMarkdownReplaces(text)) {
processInstantReplaces(text);
}
}
}

View file

@ -454,13 +454,13 @@ Text::StateResult FlatLabel::dragActionFinish(const QPoint &p, Qt::MouseButton b
}
}
#if defined Q_OS_LINUX32 || defined Q_OS_LINUX64
#if defined Q_OS_UNIX && !defined Q_OS_MAC
if (!_selection.empty()) {
TextUtilities::SetClipboardText(
_text.toTextForMimeData(_selection),
QClipboard::Selection);
}
#endif // Q_OS_LINUX32 || Q_OS_LINUX64
#endif // Q_OS_UNIX && !Q_OS_MAC
return state;
}

View file

@ -144,7 +144,6 @@ const style::icon &SideBarButton::computeIcon() const {
void SideBarButton::validateIconCache() {
Expects(_st.iconPosition.x() < 0);
Expects(_st.iconPosition.y() >= 0);
if (!(_active ? _iconCacheActive : _iconCache).isNull()) {
return;
@ -172,7 +171,10 @@ void SideBarButton::validateIconCache() {
- st::defaultScrollArea.width
- (width() / 2)
+ (icon.width() / 2)));
const auto y = _st.badgePosition.y() - _st.iconPosition.y();
const auto top = (_st.iconPosition.y() >= 0)
? _st.iconPosition.y()
: (height() - icon.height()) / 2;
const auto y = _st.badgePosition.y() - top;
const auto r = _st.badgeHeight / 2.;
p.drawRoundedRect(x, y, _iconCacheBadgeWidth, _st.badgeHeight, r, r);
}