#include "channellist.h" #include "channeldelegate.h" #include "../db/db_manager.h" #include #include #include #include #include static QIcon makeChannelIcon(const QColor &color, const QString &letter) { QPixmap pix(32, 32); pix.fill(Qt::transparent); QPainter p(&pix); p.setRenderHint(QPainter::Antialiasing); p.setBrush(color); p.setPen(Qt::NoPen); p.drawRoundedRect(0, 0, 32, 32, 8, 8); p.setPen(Qt::white); QFont f = p.font(); f.setBold(true); f.setPointSize(14); p.setFont(f); p.drawText(QRect(0, 0, 32, 32), Qt::AlignCenter, letter); p.end(); return QIcon(pix); } ChannelList::ChannelList(DbManager* db, QWidget *parent) : QWidget(parent) , m_listView(new QListView(this)) , m_model(new QStandardItemModel(this)) , m_db(db) { auto *layout = new QVBoxLayout(this); layout->setContentsMargins(0, 0, 0, 0); layout->setSpacing(0); auto *header = new QLabel("Channels", this); header->setAlignment(Qt::AlignCenter); header->setStyleSheet("font-weight: bold; padding: 8px; background: palette(window);"); layout->addWidget(header); m_listView->setModel(m_model); m_listView->setItemDelegate(new ChannelDelegate(this)); m_listView->setEditTriggers(QAbstractItemView::NoEditTriggers); m_listView->setSelectionMode(QAbstractItemView::SingleSelection); m_listView->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); m_listView->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); m_listView->setContextMenuPolicy(Qt::CustomContextMenu); layout->addWidget(m_listView); connect(m_listView->selectionModel(), &QItemSelectionModel::currentChanged, this, [this](const QModelIndex ¤t, const QModelIndex &) { if (current.isValid()) { QString cid = current.data(ChannelChannelIdRole).toString(); emit channelSelected(cid); } }); connect(m_listView, &QListView::customContextMenuRequested, this, &ChannelList::onContextMenu); } void ChannelList::loadChannels() { m_model->clear(); if (!m_db || !m_db->isOpen()) return; auto channels = m_db->getChannels(); static const QColor colors[] = { QColor(74,144,226), QColor(126,211,33), QColor(245,166,35), QColor(208,2,27), QColor(144,19,254), QColor(0,184,148) }; int ci = 0; for (const auto& ch : channels) { auto letter = ch.name.mid(0, 1).toUpper(); if (letter.isEmpty()) letter = "#"; auto *item = new QStandardItem(); item->setData(ch.name, ChannelNameRole); item->setData(ch.channelId, ChannelChannelIdRole); item->setData(QString(), ChannelLastMessageRole); item->setData(makeChannelIcon(colors[ci % 6], letter), ChannelIconRole); m_model->appendRow(item); ci++; } if (m_model->rowCount() > 0) m_listView->setCurrentIndex(m_model->index(0, 0)); } void ChannelList::selectChannel(const QString& channelId) { for (int row = 0; row < m_model->rowCount(); row++) { if (m_model->item(row)->data(ChannelChannelIdRole).toString() == channelId) { m_listView->setCurrentIndex(m_model->index(row, 0)); return; } } } void ChannelList::onContextMenu(const QPoint& pos) { QModelIndex index = m_listView->indexAt(pos); if (!index.isValid()) return; QString cid = index.data(ChannelChannelIdRole).toString(); QMenu menu(this); QAction *inviteAction = menu.addAction("Пригласить"); if (menu.exec(m_listView->viewport()->mapToGlobal(pos)) == inviteAction) emit inviteRequested(cid); }