refactor: STCP connections as ETCP links (is_tcp)
- Add is_tcp, tcp_link, tcp_reconnect_* fields to ETCP_LINK - Remove transport_link from ETCP_CONN, add tcp_link_count - stcp_link: replace embedded etcp_conn with pointer; add etcp_link backpointer - stcp_link: link_rx_cb routes ETCP data to etcp_conn_input - stcp_link: call on_close_cb in close - New TCP functions: etcp_link_enter_ready_tcp, etcp_tcp_link_start_connect, etcp_tcp_link_start_reconnect, tcp_link_close_cb, etcp_tcp_send - etcp_link_new: handle NULL conn for TCP links; skip enter_init for TCP - etcp_link_close: close stcp_link for TCP - etcp_encrypt_send: redirect TCP to etcp_tcp_send (skips AES-CCM) - tcp_server_on_link: create ETCP_LINK(is_tcp=1) + enter_ready_tcp - etcp_connect: TCP addrs -> etcp_tcp_link_start_connect - Remove ctx->tcp_link/tcp_ready - test_stcp_traffic: find stcp_link via links->is_tcp instead of transport_link - 66/68 tests pass; 2 STCP tests expected to fail (integration not complete)
This commit is contained in:
1 parent
937af4c26a
commit
d773f1724a
1705 files changed
+187
-1082154
No files matched your search
@@ -1,236 +0,0 @@
|
||||
#include "channeldelegate.h"
|
||||
#include <QPainter>
|
||||
#include <QApplication>
|
||||
|
||||
ChannelDelegate::ChannelDelegate(QObject *parent)
|
||||
: QStyledItemDelegate(parent) {}
|
||||
|
||||
QRect ChannelDelegate::inviteButtonRect(const QRect &itemRect) {
|
||||
const int margin = 6;
|
||||
return QRect(itemRect.right() - margin - InviteBtnSize,
|
||||
itemRect.bottom() - margin - InviteBtnSize,
|
||||
InviteBtnSize, InviteBtnSize);
|
||||
}
|
||||
|
||||
QRect ChannelDelegate::inviteByLinkButtonRect(const QRect &itemRect) {
|
||||
const int margin = 6;
|
||||
return QRect(itemRect.right() - margin - InviteBtnSize * 2 - InviteBtnGap,
|
||||
itemRect.bottom() - margin - InviteBtnSize,
|
||||
InviteBtnSize, InviteBtnSize);
|
||||
}
|
||||
|
||||
QRect ChannelDelegate::settingsButtonRect(const QRect &itemRect) {
|
||||
const int margin = 6;
|
||||
return QRect(itemRect.right() - margin - InviteBtnSize * 3 - InviteBtnGap * 2,
|
||||
itemRect.bottom() - margin - InviteBtnSize,
|
||||
InviteBtnSize, InviteBtnSize);
|
||||
}
|
||||
|
||||
void ChannelDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
|
||||
const QModelIndex &index) const {
|
||||
painter->save();
|
||||
|
||||
const int barWidth = 4;
|
||||
const int margin = 8;
|
||||
const int iconSize = 32;
|
||||
|
||||
int peersOnline = index.data(ChannelPeersOnlineRole).toInt();
|
||||
int autoActive = index.data(ChannelAutoConnectActiveRole).toInt();
|
||||
|
||||
/* ── background ── */
|
||||
if (option.state & QStyle::State_Selected) {
|
||||
painter->fillRect(option.rect, option.palette.highlight());
|
||||
} else if (option.state & QStyle::State_MouseOver) {
|
||||
painter->fillRect(option.rect, option.palette.light());
|
||||
} else {
|
||||
painter->fillRect(option.rect, option.palette.base());
|
||||
}
|
||||
|
||||
/* ── vertical status bar (left edge, over background) ── */
|
||||
QColor barColor = Qt::transparent;
|
||||
if (peersOnline > 0) barColor = QColor("#4CAF50");
|
||||
else if (autoActive && peersOnline == 0) barColor = QColor("#FFC107");
|
||||
if (barColor.alpha() > 0) {
|
||||
QRect barRect(option.rect.left(), option.rect.top(), barWidth, option.rect.height());
|
||||
painter->fillRect(barRect, barColor);
|
||||
}
|
||||
|
||||
QRect iconRect(option.rect.left() + margin + barWidth,
|
||||
option.rect.top() + (option.rect.height() - iconSize) / 2,
|
||||
iconSize, iconSize);
|
||||
|
||||
QIcon icon = qvariant_cast<QIcon>(index.data(ChannelIconRole));
|
||||
if (!icon.isNull()) {
|
||||
icon.paint(painter, iconRect);
|
||||
}
|
||||
|
||||
/* ── online count badge (top-left of avatar, above it) ── */
|
||||
if (peersOnline > 0) {
|
||||
int badgeSize = 16;
|
||||
QRect badgeRect(iconRect.left() - 4, iconRect.top() - 6, badgeSize, badgeSize);
|
||||
painter->setRenderHint(QPainter::Antialiasing);
|
||||
painter->setBrush(QColor("#4CAF50"));
|
||||
painter->setPen(QPen(Qt::white, 1.5));
|
||||
painter->drawEllipse(badgeRect);
|
||||
QFont badgeFont = option.font;
|
||||
badgeFont.setBold(true);
|
||||
badgeFont.setPixelSize(10);
|
||||
painter->setFont(badgeFont);
|
||||
painter->setPen(Qt::white);
|
||||
QString num = QString::number(peersOnline);
|
||||
if (peersOnline > 9) num = "9+";
|
||||
painter->drawText(badgeRect, Qt::AlignCenter, num);
|
||||
}
|
||||
|
||||
QRect textRect(iconRect.right() + margin, option.rect.top() + margin,
|
||||
option.rect.right() - iconRect.right() - 2 * margin,
|
||||
option.rect.height() - 2 * margin);
|
||||
|
||||
QString name = index.data(ChannelNameRole).toString();
|
||||
QFont nameFont = option.font;
|
||||
nameFont.setBold(true);
|
||||
nameFont.setPointSize(nameFont.pointSize() + 1);
|
||||
painter->setFont(nameFont);
|
||||
|
||||
QColor textColor = (option.state & QStyle::State_Selected)
|
||||
? option.palette.highlightedText().color()
|
||||
: option.palette.text().color();
|
||||
painter->setPen(textColor);
|
||||
|
||||
QRect nameRect = textRect;
|
||||
nameRect.setHeight(QFontMetrics(nameFont).height());
|
||||
painter->drawText(nameRect, Qt::AlignLeft | Qt::AlignTop,
|
||||
painter->fontMetrics().elidedText(name, Qt::ElideRight, nameRect.width()));
|
||||
|
||||
QString lastMsg = index.data(ChannelLastMessageRole).toString();
|
||||
if (!lastMsg.isEmpty()) {
|
||||
QFont msgFont = option.font;
|
||||
msgFont.setPointSize(msgFont.pointSize() - 1);
|
||||
QColor nickColor(0x33, 0x90, 0xEC);
|
||||
QColor msgColor = (option.state & QStyle::State_Selected)
|
||||
? option.palette.highlightedText().color().darker(120)
|
||||
: QColor(128, 128, 128);
|
||||
if (option.state & QStyle::State_Selected) nickColor = nickColor.lighter(140);
|
||||
|
||||
QRect msgRect(textRect.left(), nameRect.bottom() + 4,
|
||||
textRect.right() - InviteBtnSize - 6 - textRect.left(),
|
||||
option.rect.bottom() - nameRect.bottom() - margin);
|
||||
QFontMetrics msgFm(msgFont);
|
||||
|
||||
int colon = lastMsg.indexOf(QString::fromUtf8(": "));
|
||||
if (colon >= 0) {
|
||||
QString nick = lastMsg.left(colon + 1);
|
||||
QString body = lastMsg.mid(colon + 2);
|
||||
|
||||
painter->setFont(msgFont);
|
||||
painter->setPen(nickColor);
|
||||
QRect nickRect = msgRect;
|
||||
nickRect.setWidth(msgFm.horizontalAdvance(nick));
|
||||
painter->drawText(nickRect, Qt::AlignLeft | Qt::AlignTop, nick);
|
||||
|
||||
painter->setPen(msgColor);
|
||||
QRect bodyRect(msgRect.left() + nickRect.width(), msgRect.top(),
|
||||
msgRect.width() - nickRect.width(), msgRect.height());
|
||||
QString elidedBody = msgFm.elidedText(body, Qt::ElideRight, bodyRect.width());
|
||||
painter->drawText(bodyRect, Qt::AlignLeft | Qt::AlignTop | Qt::TextWordWrap, elidedBody);
|
||||
} else {
|
||||
painter->setFont(msgFont);
|
||||
painter->setPen(msgColor);
|
||||
QString elided = msgFm.elidedText(lastMsg, Qt::ElideRight, msgRect.width());
|
||||
painter->drawText(msgRect, Qt::AlignLeft | Qt::AlignTop | Qt::TextWordWrap, elided);
|
||||
}
|
||||
}
|
||||
|
||||
/* ── unread count badge (right of channel name) ── */
|
||||
int unread = index.data(ChannelUnreadCountRole).toInt();
|
||||
if (unread > 0) {
|
||||
QString unreadText = unread > 99 ? QStringLiteral("99+") : QString::number(unread);
|
||||
QFont badgeFont = option.font;
|
||||
badgeFont.setBold(true);
|
||||
badgeFont.setPixelSize(11);
|
||||
QFontMetrics badgeFm(badgeFont);
|
||||
int textW = badgeFm.horizontalAdvance(unreadText) + 8;
|
||||
int badgeH = 18;
|
||||
if (textW < badgeH) textW = badgeH;
|
||||
QRect badgeRect(textRect.right() - textW, nameRect.top(),
|
||||
textW, badgeH);
|
||||
painter->setRenderHint(QPainter::Antialiasing);
|
||||
painter->setBrush(QColor("#E53935"));
|
||||
painter->setPen(Qt::NoPen);
|
||||
painter->drawRoundedRect(badgeRect, badgeH / 2, badgeH / 2);
|
||||
painter->setFont(badgeFont);
|
||||
painter->setPen(Qt::white);
|
||||
painter->drawText(badgeRect, Qt::AlignCenter, unreadText);
|
||||
}
|
||||
|
||||
/* ── invite plus button (bottom-right) ── */
|
||||
QRect plusRect = inviteButtonRect(option.rect);
|
||||
bool plusHovered = index.data(ChannelInviteBtnHoveredRole).toInt() != 0;
|
||||
painter->setRenderHint(QPainter::Antialiasing);
|
||||
if (plusHovered) {
|
||||
painter->setBrush(QColor(0x33, 0x90, 0xEC));
|
||||
painter->setPen(Qt::NoPen);
|
||||
painter->drawEllipse(plusRect);
|
||||
painter->setPen(QPen(Qt::white, 2));
|
||||
} else {
|
||||
painter->setBrush(QColor(0x33, 0x90, 0xEC, 110));
|
||||
painter->setPen(Qt::NoPen);
|
||||
painter->drawEllipse(plusRect);
|
||||
painter->setPen(QPen(QColor(0x33, 0x90, 0xEC), 2));
|
||||
}
|
||||
painter->drawLine(plusRect.center().x(), plusRect.top() + 5,
|
||||
plusRect.center().x(), plusRect.bottom() - 5);
|
||||
painter->drawLine(plusRect.left() + 5, plusRect.center().y(),
|
||||
plusRect.right() - 5, plusRect.center().y());
|
||||
|
||||
/* ── invite-by-link button (left of plus, orange square with arrow) ── */
|
||||
QRect invRect = inviteByLinkButtonRect(option.rect);
|
||||
bool invHovered = index.data(ChannelInviteByLinkBtnHoveredRole).toInt() != 0;
|
||||
painter->setRenderHint(QPainter::Antialiasing);
|
||||
if (invHovered) {
|
||||
painter->setBrush(QColor(0xE6, 0x7E, 0x22));
|
||||
painter->setPen(Qt::NoPen);
|
||||
painter->drawRoundedRect(invRect, 3, 3);
|
||||
painter->setPen(QPen(Qt::white, 1.5));
|
||||
} else {
|
||||
painter->setBrush(QColor(0xE6, 0x7E, 0x22, 110));
|
||||
painter->setPen(Qt::NoPen);
|
||||
painter->drawRoundedRect(invRect, 3, 3);
|
||||
painter->setPen(QPen(QColor(0xE6, 0x7E, 0x22), 1.5));
|
||||
}
|
||||
/* arrow pointing into a box: →| or a simple arrow-left: ← */
|
||||
int cx = invRect.center().x(), cy = invRect.center().y();
|
||||
int dx = 3;
|
||||
painter->drawLine(cx + dx, cy - 3, cx - dx, cy);
|
||||
painter->drawLine(cx + dx, cy + 3, cx - dx, cy);
|
||||
painter->drawLine(cx + dx + 1, cy, cx + dx + 1, cy - 3 + 1);
|
||||
painter->drawLine(cx + dx + 1, cy, cx + dx + 1, cy + 3 - 1);
|
||||
|
||||
/* ── settings gear (left of invite-by-link button) ── */
|
||||
QRect gearRect = settingsButtonRect(option.rect);
|
||||
bool gearHovered = index.data(ChannelSettingsBtnHoveredRole).toInt() != 0;
|
||||
QColor gearColor = gearHovered ? QColor("#3390EC") : QColor("#888");
|
||||
painter->setPen(QPen(gearColor, 2));
|
||||
painter->setBrush(Qt::NoBrush);
|
||||
int gr = 5;
|
||||
painter->drawEllipse(gearRect.center(), gr, gr);
|
||||
painter->drawEllipse(gearRect.center(), gr / 2, gr / 2);
|
||||
int gcx = gearRect.center().x(), gcy = gearRect.center().y();
|
||||
painter->drawLine(gcx, gcy - gr, gcx, gcy - gr + 1);
|
||||
painter->drawLine(gcx, gcy + gr, gcx, gcy + gr - 1);
|
||||
painter->drawLine(gcx - gr, gcy, gcx - gr + 1, gcy);
|
||||
painter->drawLine(gcx + gr, gcy, gcx + gr - 1, gcy);
|
||||
painter->drawLine(gcx - 3, gcy - 4, gcx - 3, gcy - 5);
|
||||
painter->drawLine(gcx + 3, gcy + 4, gcx + 3, gcy + 5);
|
||||
painter->drawLine(gcx - 4, gcy - 3, gcx - 5, gcy - 3);
|
||||
painter->drawLine(gcx + 4, gcy + 3, gcx + 5, gcy + 3);
|
||||
|
||||
painter->restore();
|
||||
}
|
||||
|
||||
QSize ChannelDelegate::sizeHint(const QStyleOptionViewItem &option,
|
||||
const QModelIndex &index) const {
|
||||
Q_UNUSED(option);
|
||||
Q_UNUSED(index);
|
||||
return QSize(200, 56);
|
||||
}
|
||||
Reference in new issue
Block a user