Handle mouse events in log entry message parts.

Also highlight mentions and hashtags in them.
This commit is contained in:
John Preston 2017-06-23 13:54:18 +03:00
parent 17e08f9291
commit 693c30d264
3 changed files with 69 additions and 33 deletions

View File

@ -40,6 +40,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
namespace {
constexpr auto kMaxGifForwardedBarLines = 4;
constexpr auto kMaxOriginalEntryLines = 8192;
TextParseOptions _webpageTitleOptions = {
TextParseMultiline | TextParseRichText, // flags
@ -48,7 +49,7 @@ TextParseOptions _webpageTitleOptions = {
Qt::LayoutDirectionAuto, // dir
};
TextParseOptions _webpageDescriptionOptions = {
TextParseLinks | TextParseMultiline | TextParseRichText, // flags
TextParseLinks | TextParseMentions | TextParseHashtags | TextParseMultiline | TextParseRichText, // flags
0, // maxw
0, // maxh
Qt::LayoutDirectionAuto, // dir
@ -3227,17 +3228,17 @@ void HistoryWebPage::initDimensions() {
}
// init dimensions
int32 l = st::msgPadding.left() + st::webPageLeft, r = st::msgPadding.right();
int32 skipBlockWidth = _parent->skipBlockWidth();
auto l = st::msgPadding.left() + st::webPageLeft, r = st::msgPadding.right();
auto skipBlockWidth = _parent->skipBlockWidth();
_maxw = skipBlockWidth;
_minh = 0;
int32 siteNameHeight = _data->siteName.isEmpty() ? 0 : lineHeight;
int32 titleMinHeight = _title.isEmpty() ? 0 : lineHeight;
int32 descMaxLines = (3 + (siteNameHeight ? 0 : 1) + (titleMinHeight ? 0 : 1));
int32 descriptionMinHeight = _description.isEmpty() ? 0 : qMin(_description.minHeight(), descMaxLines * lineHeight);
int32 articleMinHeight = siteNameHeight + titleMinHeight + descriptionMinHeight;
int32 articlePhotoMaxWidth = 0;
auto siteNameHeight = _data->siteName.isEmpty() ? 0 : lineHeight;
auto titleMinHeight = _title.isEmpty() ? 0 : lineHeight;
auto descMaxLines = isLogEntryOriginal() ? kMaxOriginalEntryLines : (3 + (siteNameHeight ? 0 : 1) + (titleMinHeight ? 0 : 1));
auto descriptionMinHeight = _description.isEmpty() ? 0 : qMin(_description.minHeight(), descMaxLines * lineHeight);
auto articleMinHeight = siteNameHeight + titleMinHeight + descriptionMinHeight;
auto articlePhotoMaxWidth = 0;
if (_asArticle) {
articlePhotoMaxWidth = st::webPagePhotoDelta + qMax(articleThumbWidth(_data->photo, articleMinHeight), lineHeight);
}
@ -3298,7 +3299,7 @@ int HistoryWebPage::resizeGetHeight(int width) {
width -= st::msgPadding.left() + st::webPageLeft + st::msgPadding.right();
auto lineHeight = unitedLineHeight();
auto linesMax = 5;
auto linesMax = isLogEntryOriginal() ? kMaxOriginalEntryLines : 5;
auto siteNameLines = _siteNameWidth ? 1 : 0;
auto siteNameHeight = _siteNameWidth ? lineHeight : 0;
if (_asArticle) {
@ -3322,11 +3323,13 @@ int HistoryWebPage::resizeGetHeight(int width) {
auto descriptionHeight = _description.countHeight(wleft);
if (descriptionHeight < (linesMax - siteNameLines - _titleLines) * st::webPageDescriptionFont->height) {
_descriptionLines = (descriptionHeight / st::webPageDescriptionFont->height);
// We have height for all the lines.
_descriptionLines = -1;
_height += descriptionHeight;
} else {
_descriptionLines = (linesMax - siteNameLines - _titleLines);
_height += _descriptionLines * lineHeight;
}
_height += _descriptionLines * lineHeight;
if (_height >= _pixh) {
break;
@ -3354,11 +3357,13 @@ int HistoryWebPage::resizeGetHeight(int width) {
} else {
auto descriptionHeight = _description.countHeight(width);
if (descriptionHeight < (linesMax - siteNameLines - _titleLines) * st::webPageDescriptionFont->height) {
_descriptionLines = (descriptionHeight / st::webPageDescriptionFont->height);
// We have height for all the lines.
_descriptionLines = -1;
_height += descriptionHeight;
} else {
_descriptionLines = (linesMax - siteNameLines - _titleLines);
_height += _descriptionLines * lineHeight;
}
_height += _descriptionLines * lineHeight;
}
if (_attach) {
@ -3455,8 +3460,13 @@ void HistoryWebPage::draw(Painter &p, const QRect &r, TextSelection selection, T
if (_description.hasSkipBlock()) {
endskip = _parent->skipBlockWidth();
}
_description.drawLeftElided(p, padding.left(), tshift, width, _width, _descriptionLines, style::al_left, 0, -1, endskip, false, toDescriptionSelection(selection));
tshift += _descriptionLines * lineHeight;
if (_descriptionLines > 0) {
_description.drawLeftElided(p, padding.left(), tshift, width, _width, _descriptionLines, style::al_left, 0, -1, endskip, false, toDescriptionSelection(selection));
tshift += _descriptionLines * lineHeight;
} else {
_description.drawLeft(p, padding.left(), tshift, width, _width, style::al_left, 0, -1, toDescriptionSelection(selection));
tshift += _description.countHeight(width);
}
}
if (_attach) {
auto attachAtTop = !_siteNameWidth && !_titleLines && !_descriptionLines;
@ -3543,14 +3553,19 @@ HistoryTextState HistoryWebPage::getState(QPoint point, HistoryStateRequest requ
tshift += _titleLines * lineHeight;
}
if (_descriptionLines) {
if (point.y() >= tshift && point.y() < tshift + _descriptionLines * lineHeight) {
Text::StateRequestElided descriptionRequest = request.forText();
descriptionRequest.lines = _descriptionLines;
result = _description.getStateElidedLeft(point - QPoint(padding.left(), tshift), width, _width, descriptionRequest);
} else if (point.y() >= tshift + _descriptionLines * lineHeight) {
auto descriptionHeight = (_descriptionLines > 0) ? _descriptionLines * lineHeight : _description.countHeight(width);
if (point.y() >= tshift && point.y() < tshift + descriptionHeight) {
if (_descriptionLines > 0) {
Text::StateRequestElided descriptionRequest = request.forText();
descriptionRequest.lines = _descriptionLines;
result = _description.getStateElidedLeft(point - QPoint(padding.left(), tshift), width, _width, descriptionRequest);
} else {
result = _description.getStateLeft(point - QPoint(padding.left(), tshift), width, _width, request.forText());
}
} else if (point.y() >= tshift + descriptionHeight) {
symbolAdd += _description.length();
}
tshift += _descriptionLines * lineHeight;
tshift += descriptionHeight;
}
if (inThumb) {
result.link = _openl;
@ -3647,12 +3662,16 @@ QMargins HistoryWebPage::inBubblePadding() const {
return QMargins(lshift, tshift, rshift, bshift);
}
bool HistoryWebPage::isLogEntryOriginal() const {
return _parent->isLogEntry() && _parent->getMedia() != this;
}
int HistoryWebPage::bottomInfoPadding() const {
if (!isBubbleBottom()) return 0;
auto result = st::msgDateFont->height;
// we use padding greater than st::msgPadding.bottom() in the
// We use padding greater than st::msgPadding.bottom() in the
// bottom of the bubble so that the left line looks pretty.
// but if we have bottom skip because of the info display
// we don't need that additional padding so we replace it

View File

@ -831,6 +831,7 @@ private:
}
QMargins inBubblePadding() const;
int bottomInfoPadding() const;
bool isLogEntryOriginal() const;
gsl::not_null<WebPageData*> _data;
ClickHandlerPtr _openl;

View File

@ -828,7 +828,7 @@ void HistoryMessage::initDimensions() {
auto mediaOnBottom = (mediaDisplayed && _media->isBubbleBottom()) || (entry/* && entry->_page->isBubbleBottom()*/);
auto mediaOnTop = (mediaDisplayed && _media->isBubbleTop()) || (entry && entry->_page->isBubbleTop());
if (mediaDisplayed && mediaOnBottom) {
if (mediaOnBottom) {
if (_text.hasSkipBlock()) {
_text.removeSkipBlock();
_textWidth = -1;
@ -1723,9 +1723,18 @@ HistoryTextState HistoryMessage::getState(QPoint point, HistoryStateRequest requ
}
if (drawBubble()) {
auto entry = Get<HistoryMessageLogEntryOriginal>();
auto mediaDisplayed = _media && _media->isDisplayed();
auto trect = g.marginsAdded(-st::msgPadding);
if (mediaDisplayed && _media->isBubbleTop()) {
// Entry page is always a bubble bottom.
auto mediaOnBottom = (mediaDisplayed && _media->isBubbleBottom()) || (entry/* && entry->_page->isBubbleBottom()*/);
auto mediaOnTop = (mediaDisplayed && _media->isBubbleTop()) || (entry && entry->_page->isBubbleTop());
auto trect = g.marginsRemoved(st::msgPadding);
if (mediaOnBottom) {
trect.setHeight(trect.height() + st::msgPadding.bottom());
}
if (mediaOnTop) {
trect.setY(trect.y() - st::msgPadding.top());
} else {
if (getStateFromName(point, trect, &result)) return result;
@ -1733,11 +1742,18 @@ HistoryTextState HistoryMessage::getState(QPoint point, HistoryStateRequest requ
if (getStateReplyInfo(point, trect, &result)) return result;
if (getStateViaBotIdInfo(point, trect, &result)) return result;
}
if (mediaDisplayed && _media->isBubbleBottom()) {
trect.setHeight(trect.height() + st::msgPadding.bottom());
if (entry) {
auto entryHeight = entry->_page->height();
trect.setHeight(trect.height() - entryHeight);
auto entryLeft = g.left();
auto entryTop = trect.y() + trect.height();
if (point.y() >= entryTop && point.y() < entryTop + entryHeight) {
result = entry->_page->getState(point - QPoint(entryLeft, entryTop), request);
result.symbol += _text.length();
}
}
auto needDateCheck = true;
auto needDateCheck = mediaOnBottom ? !(entry ? entry->_page->customInfoLayout() : _media->customInfoLayout()) : true;
if (mediaDisplayed) {
auto mediaAboveText = _media->isAboveMessage();
auto mediaHeight = _media->height();
@ -1751,11 +1767,11 @@ HistoryTextState HistoryMessage::getState(QPoint point, HistoryStateRequest requ
if (mediaAboveText) {
trect.setY(trect.y() + mediaHeight);
}
getStateText(point, trect, &result, request);
if (trect.contains(point)) {
getStateText(point, trect, &result, request);
}
}
needDateCheck = !_media->customInfoLayout();
} else {
} else if (trect.contains(point)) {
getStateText(point, trect, &result, request);
}
if (needDateCheck) {