You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
107 lines
3.7 KiB
107 lines
3.7 KiB
#include "channellist.h" |
|
#include "channeldelegate.h" |
|
#include "../db/db_manager.h" |
|
#include <QVBoxLayout> |
|
#include <QLabel> |
|
#include <QPainter> |
|
#include <QPixmap> |
|
#include <QMenu> |
|
|
|
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(ch.lastMessage, 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); |
|
}
|
|
|