links support started

This commit is contained in:
John Preston 2015-08-21 14:23:44 +03:00
parent 5a1079e367
commit 8dff205949
5 changed files with 116 additions and 29 deletions

View File

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

View File

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

View File

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

View File

@ -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 &currentText);
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 {

View File

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