mirror of https://github.com/procxx/kepka.git
links support started
This commit is contained in:
parent
5a1079e367
commit
8dff205949
|
@ -2299,7 +2299,10 @@ void Text::setText(style::font font, const QString &text, const TextParseOptions
|
||||||
{
|
{
|
||||||
TextParser parser(this, text, options);
|
TextParser parser(this, text, options);
|
||||||
}
|
}
|
||||||
|
recountNaturalSize(true, options.dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Text::recountNaturalSize(bool initial, Qt::LayoutDirection optionsDir) {
|
||||||
NewlineBlock *lastNewline = 0;
|
NewlineBlock *lastNewline = 0;
|
||||||
|
|
||||||
int32 lineHeight = 0;
|
int32 lineHeight = 0;
|
||||||
|
@ -2313,14 +2316,16 @@ void Text::setText(style::font font, const QString &text, const TextParseOptions
|
||||||
|
|
||||||
if (_btype == TextBlockNewline) {
|
if (_btype == TextBlockNewline) {
|
||||||
if (!lineHeight) lineHeight = blockHeight;
|
if (!lineHeight) lineHeight = blockHeight;
|
||||||
Qt::LayoutDirection dir = options.dir;
|
if (initial) {
|
||||||
if (dir == Qt::LayoutDirectionAuto) {
|
Qt::LayoutDirection dir = optionsDir;
|
||||||
dir = TextParser::stringDirection(_text, lastNewlineStart, b->from());
|
if (dir == Qt::LayoutDirectionAuto) {
|
||||||
}
|
dir = TextParser::stringDirection(_text, lastNewlineStart, b->from());
|
||||||
if (lastNewline) {
|
}
|
||||||
lastNewline->_nextDir = dir;
|
if (lastNewline) {
|
||||||
} else {
|
lastNewline->_nextDir = dir;
|
||||||
_startDir = dir;
|
} else {
|
||||||
|
_startDir = dir;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
lastNewlineStart = b->from();
|
lastNewlineStart = b->from();
|
||||||
lastNewline = static_cast<NewlineBlock*>(b);
|
lastNewline = static_cast<NewlineBlock*>(b);
|
||||||
|
@ -2344,14 +2349,16 @@ void Text::setText(style::font font, const QString &text, const TextParseOptions
|
||||||
last_rPadding = b->f_rpadding();
|
last_rPadding = b->f_rpadding();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Qt::LayoutDirection dir = options.dir;
|
if (initial) {
|
||||||
if (dir == Qt::LayoutDirectionAuto) {
|
Qt::LayoutDirection dir = optionsDir;
|
||||||
dir = TextParser::stringDirection(_text, lastNewlineStart, _text.size());
|
if (dir == Qt::LayoutDirectionAuto) {
|
||||||
}
|
dir = TextParser::stringDirection(_text, lastNewlineStart, _text.size());
|
||||||
if (lastNewline) {
|
}
|
||||||
lastNewline->_nextDir = dir;
|
if (lastNewline) {
|
||||||
} else {
|
lastNewline->_nextDir = dir;
|
||||||
_startDir = dir;
|
} else {
|
||||||
|
_startDir = dir;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (_width > 0) {
|
if (_width > 0) {
|
||||||
if (!lineHeight) lineHeight = _blockHeight(_blocks.back(), _font);
|
if (!lineHeight) lineHeight = _blockHeight(_blocks.back(), _font);
|
||||||
|
@ -2362,6 +2369,10 @@ void Text::setText(style::font font, const QString &text, const TextParseOptions
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Text::setMarkedText(style::font font, const QString &text, const LinksInText &links) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void Text::setRichText(style::font font, const QString &text, TextParseOptions options, const TextCustomTagsMap &custom) {
|
void Text::setRichText(style::font font, const QString &text, TextParseOptions options, const TextCustomTagsMap &custom) {
|
||||||
QString parsed;
|
QString parsed;
|
||||||
parsed.reserve(text.size());
|
parsed.reserve(text.size());
|
||||||
|
@ -2449,6 +2460,18 @@ bool Text::hasLinks() const {
|
||||||
return !_links.isEmpty();
|
return !_links.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Text::setSkipBlock(int32 width) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Text::removeSkipBlock() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
LinksInText Text::calcLinksInText() const {
|
||||||
|
return LinksInText();
|
||||||
|
}
|
||||||
|
|
||||||
int32 Text::countHeight(int32 w) const {
|
int32 Text::countHeight(int32 w) const {
|
||||||
QFixed width = w;
|
QFixed width = w;
|
||||||
if (width < _minResizeWidth) width = _minResizeWidth;
|
if (width < _minResizeWidth) width = _minResizeWidth;
|
||||||
|
|
|
@ -464,6 +464,23 @@ enum TextSelectType {
|
||||||
typedef QPair<QString, QString> TextCustomTag; // open str and close str
|
typedef QPair<QString, QString> TextCustomTag; // open str and close str
|
||||||
typedef QMap<QChar, TextCustomTag> TextCustomTagsMap;
|
typedef QMap<QChar, TextCustomTag> TextCustomTagsMap;
|
||||||
|
|
||||||
|
enum LinkInTextType {
|
||||||
|
LinkInTextUrl,
|
||||||
|
LinkInTextCustomUrl,
|
||||||
|
LinkInTextEmail,
|
||||||
|
LinkInTextHashtag,
|
||||||
|
LinkInTextMention,
|
||||||
|
LinkInTextBotCommand,
|
||||||
|
};
|
||||||
|
struct LinkInText {
|
||||||
|
LinkInText(LinkInTextType type, int32 offset, int32 length, const QString &text = QString()) : type(type), offset(offset), length(length), text(text) {
|
||||||
|
}
|
||||||
|
LinkInTextType type;
|
||||||
|
int32 offset, length;
|
||||||
|
QString text;
|
||||||
|
};
|
||||||
|
typedef QList<LinkInText> LinksInText;
|
||||||
|
|
||||||
class Text {
|
class Text {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -475,6 +492,7 @@ public:
|
||||||
int32 countHeight(int32 width) const;
|
int32 countHeight(int32 width) const;
|
||||||
void setText(style::font font, const QString &text, const TextParseOptions &options = _defaultOptions);
|
void setText(style::font font, const QString &text, const TextParseOptions &options = _defaultOptions);
|
||||||
void setRichText(style::font font, const QString &text, TextParseOptions options = _defaultOptions, const TextCustomTagsMap &custom = TextCustomTagsMap());
|
void setRichText(style::font font, const QString &text, TextParseOptions options = _defaultOptions, const TextCustomTagsMap &custom = TextCustomTagsMap());
|
||||||
|
void setMarkedText(style::font font, const QString &text, const LinksInText &links);
|
||||||
|
|
||||||
void setLink(uint16 lnkIndex, const TextLinkPtr &lnk);
|
void setLink(uint16 lnkIndex, const TextLinkPtr &lnk);
|
||||||
bool hasLinks() const;
|
bool hasLinks() const;
|
||||||
|
@ -482,6 +500,9 @@ public:
|
||||||
bool hasSkipBlock() const {
|
bool hasSkipBlock() const {
|
||||||
return _blocks.isEmpty() ? false : _blocks.back()->type() == TextBlockSkip;
|
return _blocks.isEmpty() ? false : _blocks.back()->type() == TextBlockSkip;
|
||||||
}
|
}
|
||||||
|
void setSkipBlock(int32 width);
|
||||||
|
void removeSkipBlock();
|
||||||
|
LinksInText calcLinksInText() const;
|
||||||
|
|
||||||
int32 maxWidth() const {
|
int32 maxWidth() const {
|
||||||
return _maxWidth.ceil().toInt();
|
return _maxWidth.ceil().toInt();
|
||||||
|
@ -534,6 +555,8 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
void recountNaturalSize(bool initial, Qt::LayoutDirection optionsDir = Qt::LayoutDirectionAuto);
|
||||||
|
|
||||||
QFixed _minResizeWidth, _maxWidth;
|
QFixed _minResizeWidth, _maxWidth;
|
||||||
int32 _minHeight;
|
int32 _minHeight;
|
||||||
|
|
||||||
|
|
|
@ -943,6 +943,15 @@ HistoryItem *History::doAddToBack(HistoryBlock *to, bool newBlock, HistoryItem *
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (adding->hasTextLinks()) {
|
||||||
|
MediaOverviewType t = OverviewLinks;
|
||||||
|
if (_overviewIds[t].constFind(adding->id) == _overviewIds[t].cend()) {
|
||||||
|
_overview[t].push_back(adding->id);
|
||||||
|
_overviewIds[t].insert(adding->id, NullType());
|
||||||
|
if (_overviewCount[t] > 0) ++_overviewCount[t];
|
||||||
|
if (App::wnd()) App::wnd()->mediaOverviewUpdated(peer, t);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (adding->from()->id) {
|
if (adding->from()->id) {
|
||||||
if (peer->chat) {
|
if (peer->chat) {
|
||||||
QList<UserData*> *lastAuthors = &(peer->asChat()->lastAuthors);
|
QList<UserData*> *lastAuthors = &(peer->asChat()->lastAuthors);
|
||||||
|
@ -1098,6 +1107,14 @@ void History::addToFront(const QVector<MTPMessage> &slice) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (item->hasTextLinks()) {
|
||||||
|
MediaOverviewType t = OverviewLinks;
|
||||||
|
if (_overviewIds[t].constFind(item->id) == _overviewIds[t].cend()) {
|
||||||
|
_overview[t].push_front(item->id);
|
||||||
|
_overviewIds[t].insert(item->id, NullType());
|
||||||
|
mask |= (1 << t);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (item->from()->id) {
|
if (item->from()->id) {
|
||||||
if (lastAuthors) { // chats
|
if (lastAuthors) { // chats
|
||||||
if (!lastAuthors->contains(item->from())) {
|
if (!lastAuthors->contains(item->from())) {
|
||||||
|
@ -1249,6 +1266,14 @@ void History::addToBack(const QVector<MTPMessage> &slice) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (item->hasTextLinks()) {
|
||||||
|
MediaOverviewType t = OverviewLinks;
|
||||||
|
if (_overviewCount[t] != 0) {
|
||||||
|
_overview[t].push_back(item->id);
|
||||||
|
_overviewIds[t].insert(item->id, NullType());
|
||||||
|
mask |= (1 << t);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (int32 t = 0; t < OverviewCount; ++t) {
|
for (int32 t = 0; t < OverviewCount; ++t) {
|
||||||
|
@ -1760,6 +1785,9 @@ void HistoryItem::destroy() {
|
||||||
history()->eraseFromOverview(OverviewAudioDocuments, id);
|
history()->eraseFromOverview(OverviewAudioDocuments, id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (hasTextLinks()) {
|
||||||
|
history()->eraseFromOverview(OverviewLinks, id);
|
||||||
|
}
|
||||||
delete this;
|
delete this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4994,13 +5022,14 @@ HistoryMessage::HistoryMessage(History *history, HistoryBlock *block, const MTPD
|
||||||
, _textHeight(0)
|
, _textHeight(0)
|
||||||
, _media(0)
|
, _media(0)
|
||||||
{
|
{
|
||||||
|
//if (msg.has_entities()) msg.ventities.c_vector().v.size()
|
||||||
QString text(textClean(qs(msg.vmessage)));
|
QString text(textClean(qs(msg.vmessage)));
|
||||||
initTime();
|
initTime();
|
||||||
initMedia(msg.vmedia, text);
|
initMedia(msg.vmedia, text);
|
||||||
initDimensions(text);
|
initDimensions(text, msg.has_entities() ? linksFromMTP(msg.ventities.c_vector().v) : LinksInText());
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryMessage::HistoryMessage(History *history, HistoryBlock *block, MsgId msgId, int32 flags, QDateTime date, int32 from, const QString &msg, const MTPMessageMedia &media) :
|
HistoryMessage::HistoryMessage(History *history, HistoryBlock *block, MsgId msgId, int32 flags, QDateTime date, int32 from, const QString &msg, const LinksInText &links, const MTPMessageMedia &media) :
|
||||||
HistoryItem(history, block, msgId, flags, date, from)
|
HistoryItem(history, block, msgId, flags, date, from)
|
||||||
, _text(st::msgMinWidth)
|
, _text(st::msgMinWidth)
|
||||||
, _textWidth(0)
|
, _textWidth(0)
|
||||||
|
@ -5010,10 +5039,10 @@ HistoryItem(history, block, msgId, flags, date, from)
|
||||||
QString text(msg);
|
QString text(msg);
|
||||||
initTime();
|
initTime();
|
||||||
initMedia(media, text);
|
initMedia(media, text);
|
||||||
initDimensions(text);
|
initDimensions(text, links);
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryMessage::HistoryMessage(History *history, HistoryBlock *block, MsgId msgId, int32 flags, QDateTime date, int32 from, const QString &msg, HistoryMedia *fromMedia) :
|
HistoryMessage::HistoryMessage(History *history, HistoryBlock *block, MsgId msgId, int32 flags, QDateTime date, int32 from, const QString &msg, const LinksInText &links, HistoryMedia *fromMedia) :
|
||||||
HistoryItem(history, block, msgId, flags, date, from)
|
HistoryItem(history, block, msgId, flags, date, from)
|
||||||
, _text(st::msgMinWidth)
|
, _text(st::msgMinWidth)
|
||||||
, _textWidth(0)
|
, _textWidth(0)
|
||||||
|
@ -5025,7 +5054,7 @@ HistoryItem(history, block, msgId, flags, date, from)
|
||||||
_media = fromMedia->clone();
|
_media = fromMedia->clone();
|
||||||
_media->regItem(this);
|
_media->regItem(this);
|
||||||
}
|
}
|
||||||
initDimensions(msg);
|
initDimensions(msg, links);
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryMessage::HistoryMessage(History *history, HistoryBlock *block, MsgId msgId, int32 flags, QDateTime date, int32 from, DocumentData *doc) :
|
HistoryMessage::HistoryMessage(History *history, HistoryBlock *block, MsgId msgId, int32 flags, QDateTime date, int32 from, DocumentData *doc) :
|
||||||
|
@ -5037,7 +5066,7 @@ HistoryItem(history, block, msgId, flags, date, from)
|
||||||
{
|
{
|
||||||
initTime();
|
initTime();
|
||||||
initMediaFromDocument(doc);
|
initMediaFromDocument(doc);
|
||||||
initDimensions(QString());
|
initDimensions(QString(), LinksInText());
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryMessage::initTime() {
|
void HistoryMessage::initTime() {
|
||||||
|
@ -5125,12 +5154,18 @@ void HistoryMessage::initMediaFromDocument(DocumentData *doc) {
|
||||||
_media->regItem(this);
|
_media->regItem(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryMessage::initDimensions(const QString &text) {
|
void HistoryMessage::initDimensions(const QString &text, const LinksInText &links) {
|
||||||
if (!_media || !text.isEmpty()) { // !justMedia()
|
if (!_media || !text.isEmpty()) { // !justMedia()
|
||||||
if (_media && _media->isDisplayed()) {
|
if (_media && _media->isDisplayed()) {
|
||||||
_text.setText(st::msgFont, text, itemTextParseOptions(this));
|
_text.setMarkedText(st::msgFont, text, links, itemTextParseOptions(this));
|
||||||
} else {
|
} else {
|
||||||
_text.setText(st::msgFont, text + textcmdSkipBlock(timeWidth(true), st::msgDateFont->height - st::msgDateDelta.y()), itemTextParseOptions(this));
|
_text.setMarkedText(st::msgFont, text + textcmdSkipBlock(timeWidth(true), st::msgDateFont->height - st::msgDateDelta.y()), links, itemTextParseOptions(this));
|
||||||
|
}
|
||||||
|
for (int32 i = 0, l = links.size(); i != l; ++i) {
|
||||||
|
if (links.at(i).type == LinkInTextUrl || links.at(i).type == LinkInTextCustomUrl || links.at(i).type == LinkInTextEmail) {
|
||||||
|
_flags |= MTPDmessage_flag_HAS_TEXT_LINKS;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -107,6 +107,7 @@ enum MediaOverviewType {
|
||||||
OverviewDocuments,
|
OverviewDocuments,
|
||||||
OverviewAudios,
|
OverviewAudios,
|
||||||
OverviewAudioDocuments,
|
OverviewAudioDocuments,
|
||||||
|
OverviewLinks,
|
||||||
|
|
||||||
OverviewCount
|
OverviewCount
|
||||||
};
|
};
|
||||||
|
@ -116,7 +117,7 @@ inline MediaOverviewType mediaToOverviewType(HistoryMediaType t) {
|
||||||
case MediaTypePhoto: return OverviewPhotos;
|
case MediaTypePhoto: return OverviewPhotos;
|
||||||
case MediaTypeVideo: return OverviewVideos;
|
case MediaTypeVideo: return OverviewVideos;
|
||||||
case MediaTypeDocument: return OverviewDocuments;
|
case MediaTypeDocument: return OverviewDocuments;
|
||||||
// case MediaTypeSticker: return OverviewDocuments;
|
// case MediaTypeSticker: return OverviewDocuments;
|
||||||
case MediaTypeAudio: return OverviewAudios;
|
case MediaTypeAudio: return OverviewAudios;
|
||||||
}
|
}
|
||||||
return OverviewCount;
|
return OverviewCount;
|
||||||
|
@ -129,6 +130,7 @@ inline MTPMessagesFilter typeToMediaFilter(MediaOverviewType &type) {
|
||||||
case OverviewDocuments: return MTP_inputMessagesFilterDocument();
|
case OverviewDocuments: return MTP_inputMessagesFilterDocument();
|
||||||
case OverviewAudios: return MTP_inputMessagesFilterAudio();
|
case OverviewAudios: return MTP_inputMessagesFilterAudio();
|
||||||
case OverviewAudioDocuments: return MTP_inputMessagesFilterAudioDocuments();
|
case OverviewAudioDocuments: return MTP_inputMessagesFilterAudioDocuments();
|
||||||
|
case OverviewLinks: return MTP_inputMessagesFilterUrl();
|
||||||
default: type = OverviewCount; break;
|
default: type = OverviewCount; break;
|
||||||
}
|
}
|
||||||
return MTPMessagesFilter();
|
return MTPMessagesFilter();
|
||||||
|
@ -723,6 +725,9 @@ public:
|
||||||
bool hasReplyMarkup() const {
|
bool hasReplyMarkup() const {
|
||||||
return _flags & MTPDmessage::flag_reply_markup;
|
return _flags & MTPDmessage::flag_reply_markup;
|
||||||
}
|
}
|
||||||
|
bool hasTextLinks() const {
|
||||||
|
return _flags & MTPDmessage_flag_HAS_TEXT_LINKS;
|
||||||
|
}
|
||||||
virtual bool needCheck() const {
|
virtual bool needCheck() const {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1274,8 +1279,8 @@ class HistoryMessage : public HistoryItem {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
HistoryMessage(History *history, HistoryBlock *block, const MTPDmessage &msg);
|
HistoryMessage(History *history, HistoryBlock *block, const MTPDmessage &msg);
|
||||||
HistoryMessage(History *history, HistoryBlock *block, MsgId msgId, int32 flags, QDateTime date, int32 from, const QString &msg, const MTPMessageMedia &media);
|
HistoryMessage(History *history, HistoryBlock *block, MsgId msgId, int32 flags, QDateTime date, int32 from, const QString &msg, const LinksInText &links, const MTPMessageMedia &media);
|
||||||
HistoryMessage(History *history, HistoryBlock *block, MsgId msgId, int32 flags, QDateTime date, int32 from, const QString &msg, HistoryMedia *media);
|
HistoryMessage(History *history, HistoryBlock *block, MsgId msgId, int32 flags, QDateTime date, int32 from, const QString &msg, const LinksInText &links, HistoryMedia *media);
|
||||||
HistoryMessage(History *history, HistoryBlock *block, MsgId msgId, int32 flags, QDateTime date, int32 from, DocumentData *doc);
|
HistoryMessage(History *history, HistoryBlock *block, MsgId msgId, int32 flags, QDateTime date, int32 from, DocumentData *doc);
|
||||||
|
|
||||||
void initTime();
|
void initTime();
|
||||||
|
@ -1283,7 +1288,7 @@ public:
|
||||||
void initMediaFromText(QString ¤tText);
|
void initMediaFromText(QString ¤tText);
|
||||||
void initMediaFromDocument(DocumentData *doc);
|
void initMediaFromDocument(DocumentData *doc);
|
||||||
void initDimensions(const HistoryItem *parent = 0);
|
void initDimensions(const HistoryItem *parent = 0);
|
||||||
void initDimensions(const QString &text);
|
void initDimensions(const QString &text, const LinksInText &links);
|
||||||
void fromNameUpdated() const;
|
void fromNameUpdated() const;
|
||||||
|
|
||||||
bool justMedia() const {
|
bool justMedia() const {
|
||||||
|
|
|
@ -25,6 +25,7 @@ enum {
|
||||||
MTPDmessage_flag_out = (1 << 1),
|
MTPDmessage_flag_out = (1 << 1),
|
||||||
MTPDmessage_flag_notify_by_from = (1 << 4),
|
MTPDmessage_flag_notify_by_from = (1 << 4),
|
||||||
MTPDmessage_flag_media_unread = (1 << 5),
|
MTPDmessage_flag_media_unread = (1 << 5),
|
||||||
|
MTPDmessage_flag_HAS_TEXT_LINKS = (1 << 31), // client side flag for having links
|
||||||
|
|
||||||
MTPmessages_SendMessage_flag_skipWebPage = (1 << 1),
|
MTPmessages_SendMessage_flag_skipWebPage = (1 << 1),
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue