|
|
|
@ -823,6 +823,9 @@ static void drawAnimatedEmojiOverlay(QPainter *p, const QFont &font, |
|
|
|
|
|
|
|
|
|
|
|
if (!para.isEmpty()) { |
|
|
|
if (!para.isEmpty()) { |
|
|
|
QTextLayout layout(para, font); |
|
|
|
QTextLayout layout(para, font); |
|
|
|
|
|
|
|
if (text.contains(QStringLiteral("utun://"))) { |
|
|
|
|
|
|
|
QTextOption wrap; wrap.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere); layout.setTextOption(wrap); |
|
|
|
|
|
|
|
} |
|
|
|
layout.beginLayout(); |
|
|
|
layout.beginLayout(); |
|
|
|
qreal localY = 0; |
|
|
|
qreal localY = 0; |
|
|
|
while (true) { |
|
|
|
while (true) { |
|
|
|
@ -839,7 +842,7 @@ static void drawAnimatedEmojiOverlay(QPainter *p, const QFont &font, |
|
|
|
const QString &unicode = it.key(); |
|
|
|
const QString &unicode = it.key(); |
|
|
|
int pos = text.indexOf(unicode, ls); |
|
|
|
int pos = text.indexOf(unicode, ls); |
|
|
|
while (pos >= 0 && pos + unicode.length() <= le) { |
|
|
|
while (pos >= 0 && pos + unicode.length() <= le) { |
|
|
|
int linePos = pos - globalChar - line.textStart(); |
|
|
|
int linePos = pos - globalChar; |
|
|
|
int cp1 = linePos, cp2 = linePos + unicode.length(); |
|
|
|
int cp1 = linePos, cp2 = linePos + unicode.length(); |
|
|
|
qreal x1 = line.cursorToX(&cp1); |
|
|
|
qreal x1 = line.cursorToX(&cp1); |
|
|
|
qreal x2 = line.cursorToX(&cp2); |
|
|
|
qreal x2 = line.cursorToX(&cp2); |
|
|
|
@ -1368,14 +1371,34 @@ void MessageDelegate::paint(QPainter *painter, const QStyleOptionViewItem &optio |
|
|
|
painter->setFont(textFont); |
|
|
|
painter->setFont(textFont); |
|
|
|
|
|
|
|
|
|
|
|
QString msgText = index.data(MsgTextRole).toString(); |
|
|
|
QString msgText = index.data(MsgTextRole).toString(); |
|
|
|
if (msgText.contains(QStringLiteral("utun://"))) { |
|
|
|
const bool hasInvite = msgText.contains(QStringLiteral("utun://")); |
|
|
|
|
|
|
|
if (hasInvite) { |
|
|
|
QString display = msgText; display.replace('\n', QChar(0x2028)); |
|
|
|
QString display = msgText; display.replace('\n', QChar(0x2028)); |
|
|
|
QTextLayout layout(display, textFont); |
|
|
|
QTextLayout layout(display, textFont); |
|
|
|
layoutInviteText(layout, L.textRect.width()); |
|
|
|
layoutInviteText(layout, L.textRect.width()); |
|
|
|
layout.draw(painter, L.textRect.topLeft()); |
|
|
|
QVector<QTextLayout::FormatRange> selections; |
|
|
|
|
|
|
|
if (singleTextSel && cv) { |
|
|
|
|
|
|
|
auto cursorAt = [&](const QPoint& point) { |
|
|
|
|
|
|
|
for (int i = 0; i < layout.lineCount(); ++i) { |
|
|
|
|
|
|
|
const auto line = layout.lineAt(i); |
|
|
|
|
|
|
|
if (point.y() < line.y() + line.height()) return line.xToCursor(point.x()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return msgText.length(); |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
const auto& selection = cv->textSelection(); |
|
|
|
|
|
|
|
int start = cursorAt(selection.clickPos - L.textRect.topLeft()); |
|
|
|
|
|
|
|
int end = cursorAt(selection.dragPos - L.textRect.topLeft()); |
|
|
|
|
|
|
|
if (start > end) qSwap(start, end); |
|
|
|
|
|
|
|
if (start == end && end < msgText.length()) ++end; |
|
|
|
|
|
|
|
const_cast<ChatView*>(cv)->setTextSelChars(start, end); |
|
|
|
|
|
|
|
QTextLayout::FormatRange range; |
|
|
|
|
|
|
|
range.start = start; range.length = end - start; range.format.setBackground(QColor(0x33, 0x90, 0xEC, 60)); |
|
|
|
|
|
|
|
selections.append(range); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
layout.draw(painter, L.textRect.topLeft(), selections); |
|
|
|
} else painter->drawText(L.textRect, Qt::AlignLeft | Qt::TextWordWrap, msgText); |
|
|
|
} else painter->drawText(L.textRect, Qt::AlignLeft | Qt::TextWordWrap, msgText); |
|
|
|
|
|
|
|
|
|
|
|
if (singleTextSel && cv) { |
|
|
|
if (singleTextSel && cv && !hasInvite) { |
|
|
|
const auto &ts = cv->textSelection(); |
|
|
|
const auto &ts = cv->textSelection(); |
|
|
|
QPoint localP1(ts.clickPos.x() - L.textRect.left(), |
|
|
|
QPoint localP1(ts.clickPos.x() - L.textRect.left(), |
|
|
|
ts.clickPos.y() - L.textRect.top()); |
|
|
|
ts.clickPos.y() - L.textRect.top()); |
|
|
|
|