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);
|
||||
}
|
||||
recountNaturalSize(true, options.dir);
|
||||
}
|
||||
|
||||
void Text::recountNaturalSize(bool initial, Qt::LayoutDirection optionsDir) {
|
||||
NewlineBlock *lastNewline = 0;
|
||||
|
||||
int32 lineHeight = 0;
|
||||
|
@ -2313,14 +2316,16 @@ void Text::setText(style::font font, const QString &text, const TextParseOptions
|
|||
|
||||
if (_btype == TextBlockNewline) {
|
||||
if (!lineHeight) lineHeight = blockHeight;
|
||||
Qt::LayoutDirection dir = options.dir;
|
||||
if (dir == Qt::LayoutDirectionAuto) {
|
||||
dir = TextParser::stringDirection(_text, lastNewlineStart, b->from());
|
||||
}
|
||||
if (lastNewline) {
|
||||
lastNewline->_nextDir = dir;
|
||||
} else {
|
||||
_startDir = dir;
|
||||
if (initial) {
|
||||
Qt::LayoutDirection dir = optionsDir;
|
||||
if (dir == Qt::LayoutDirectionAuto) {
|
||||
dir = TextParser::stringDirection(_text, lastNewlineStart, b->from());
|
||||
}
|
||||
if (lastNewline) {
|
||||
lastNewline->_nextDir = dir;
|
||||
} else {
|
||||
_startDir = dir;
|
||||
}
|
||||
}
|
||||
lastNewlineStart = b->from();
|
||||
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();
|
||||
continue;
|
||||
}
|
||||
Qt::LayoutDirection dir = options.dir;
|
||||
if (dir == Qt::LayoutDirectionAuto) {
|
||||
dir = TextParser::stringDirection(_text, lastNewlineStart, _text.size());
|
||||
}
|
||||
if (lastNewline) {
|
||||
lastNewline->_nextDir = dir;
|
||||
} else {
|
||||
_startDir = dir;
|
||||
if (initial) {
|
||||
Qt::LayoutDirection dir = optionsDir;
|
||||
if (dir == Qt::LayoutDirectionAuto) {
|
||||
dir = TextParser::stringDirection(_text, lastNewlineStart, _text.size());
|
||||
}
|
||||
if (lastNewline) {
|
||||
lastNewline->_nextDir = dir;
|
||||
} else {
|
||||
_startDir = dir;
|
||||
}
|
||||
}
|
||||
if (_width > 0) {
|
||||
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) {
|
||||
QString parsed;
|
||||
parsed.reserve(text.size());
|
||||
|
@ -2449,6 +2460,18 @@ bool Text::hasLinks() const {
|
|||
return !_links.isEmpty();
|
||||
}
|
||||
|
||||
void Text::setSkipBlock(int32 width) {
|
||||
|
||||
}
|
||||
|
||||
void Text::removeSkipBlock() {
|
||||
|
||||
}
|
||||
|
||||
LinksInText Text::calcLinksInText() const {
|
||||
return LinksInText();
|
||||
}
|
||||
|
||||
int32 Text::countHeight(int32 w) const {
|
||||
QFixed width = w;
|
||||
if (width < _minResizeWidth) width = _minResizeWidth;
|
||||
|
|
|
@ -464,6 +464,23 @@ enum TextSelectType {
|
|||
typedef QPair<QString, QString> TextCustomTag; // open str and close str
|
||||
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 {
|
||||
public:
|
||||
|
||||
|
@ -475,6 +492,7 @@ public:
|
|||
int32 countHeight(int32 width) const;
|
||||
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 setMarkedText(style::font font, const QString &text, const LinksInText &links);
|
||||
|
||||
void setLink(uint16 lnkIndex, const TextLinkPtr &lnk);
|
||||
bool hasLinks() const;
|
||||
|
@ -482,6 +500,9 @@ public:
|
|||
bool hasSkipBlock() const {
|
||||
return _blocks.isEmpty() ? false : _blocks.back()->type() == TextBlockSkip;
|
||||
}
|
||||
void setSkipBlock(int32 width);
|
||||
void removeSkipBlock();
|
||||
LinksInText calcLinksInText() const;
|
||||
|
||||
int32 maxWidth() const {
|
||||
return _maxWidth.ceil().toInt();
|
||||
|
@ -534,6 +555,8 @@ public:
|
|||
|
||||
private:
|
||||
|
||||
void recountNaturalSize(bool initial, Qt::LayoutDirection optionsDir = Qt::LayoutDirectionAuto);
|
||||
|
||||
QFixed _minResizeWidth, _maxWidth;
|
||||
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 (peer->chat) {
|
||||
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 (lastAuthors) { // chats
|
||||
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) {
|
||||
|
@ -1760,6 +1785,9 @@ void HistoryItem::destroy() {
|
|||
history()->eraseFromOverview(OverviewAudioDocuments, id);
|
||||
}
|
||||
}
|
||||
if (hasTextLinks()) {
|
||||
history()->eraseFromOverview(OverviewLinks, id);
|
||||
}
|
||||
delete this;
|
||||
}
|
||||
|
||||
|
@ -4994,13 +5022,14 @@ HistoryMessage::HistoryMessage(History *history, HistoryBlock *block, const MTPD
|
|||
, _textHeight(0)
|
||||
, _media(0)
|
||||
{
|
||||
//if (msg.has_entities()) msg.ventities.c_vector().v.size()
|
||||
QString text(textClean(qs(msg.vmessage)));
|
||||
initTime();
|
||||
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)
|
||||
, _text(st::msgMinWidth)
|
||||
, _textWidth(0)
|
||||
|
@ -5010,10 +5039,10 @@ HistoryItem(history, block, msgId, flags, date, from)
|
|||
QString text(msg);
|
||||
initTime();
|
||||
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)
|
||||
, _text(st::msgMinWidth)
|
||||
, _textWidth(0)
|
||||
|
@ -5025,7 +5054,7 @@ HistoryItem(history, block, msgId, flags, date, from)
|
|||
_media = fromMedia->clone();
|
||||
_media->regItem(this);
|
||||
}
|
||||
initDimensions(msg);
|
||||
initDimensions(msg, links);
|
||||
}
|
||||
|
||||
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();
|
||||
initMediaFromDocument(doc);
|
||||
initDimensions(QString());
|
||||
initDimensions(QString(), LinksInText());
|
||||
}
|
||||
|
||||
void HistoryMessage::initTime() {
|
||||
|
@ -5125,12 +5154,18 @@ void HistoryMessage::initMediaFromDocument(DocumentData *doc) {
|
|||
_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 && _media->isDisplayed()) {
|
||||
_text.setText(st::msgFont, text, itemTextParseOptions(this));
|
||||
_text.setMarkedText(st::msgFont, text, links, itemTextParseOptions(this));
|
||||
} 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,
|
||||
OverviewAudios,
|
||||
OverviewAudioDocuments,
|
||||
OverviewLinks,
|
||||
|
||||
OverviewCount
|
||||
};
|
||||
|
@ -116,7 +117,7 @@ inline MediaOverviewType mediaToOverviewType(HistoryMediaType t) {
|
|||
case MediaTypePhoto: return OverviewPhotos;
|
||||
case MediaTypeVideo: return OverviewVideos;
|
||||
case MediaTypeDocument: return OverviewDocuments;
|
||||
// case MediaTypeSticker: return OverviewDocuments;
|
||||
// case MediaTypeSticker: return OverviewDocuments;
|
||||
case MediaTypeAudio: return OverviewAudios;
|
||||
}
|
||||
return OverviewCount;
|
||||
|
@ -129,6 +130,7 @@ inline MTPMessagesFilter typeToMediaFilter(MediaOverviewType &type) {
|
|||
case OverviewDocuments: return MTP_inputMessagesFilterDocument();
|
||||
case OverviewAudios: return MTP_inputMessagesFilterAudio();
|
||||
case OverviewAudioDocuments: return MTP_inputMessagesFilterAudioDocuments();
|
||||
case OverviewLinks: return MTP_inputMessagesFilterUrl();
|
||||
default: type = OverviewCount; break;
|
||||
}
|
||||
return MTPMessagesFilter();
|
||||
|
@ -723,6 +725,9 @@ public:
|
|||
bool hasReplyMarkup() const {
|
||||
return _flags & MTPDmessage::flag_reply_markup;
|
||||
}
|
||||
bool hasTextLinks() const {
|
||||
return _flags & MTPDmessage_flag_HAS_TEXT_LINKS;
|
||||
}
|
||||
virtual bool needCheck() const {
|
||||
return true;
|
||||
}
|
||||
|
@ -1274,8 +1279,8 @@ class HistoryMessage : public HistoryItem {
|
|||
public:
|
||||
|
||||
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, HistoryMedia *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, const LinksInText &links, HistoryMedia *media);
|
||||
HistoryMessage(History *history, HistoryBlock *block, MsgId msgId, int32 flags, QDateTime date, int32 from, DocumentData *doc);
|
||||
|
||||
void initTime();
|
||||
|
@ -1283,7 +1288,7 @@ public:
|
|||
void initMediaFromText(QString ¤tText);
|
||||
void initMediaFromDocument(DocumentData *doc);
|
||||
void initDimensions(const HistoryItem *parent = 0);
|
||||
void initDimensions(const QString &text);
|
||||
void initDimensions(const QString &text, const LinksInText &links);
|
||||
void fromNameUpdated() const;
|
||||
|
||||
bool justMedia() const {
|
||||
|
|
|
@ -25,6 +25,7 @@ enum {
|
|||
MTPDmessage_flag_out = (1 << 1),
|
||||
MTPDmessage_flag_notify_by_from = (1 << 4),
|
||||
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),
|
||||
|
||||
|
|
Loading…
Reference in New Issue