Compare commits

2 Commits

Author SHA1 Message Date
PTyTb 5f53bdcf96 добавил установщик 2026-02-12 20:15:28 +03:00
PTyTb 76439727d2 Добавил "адаптивный" дизайн 2026-02-11 22:46:34 +03:00
4 changed files with 2267 additions and 2876 deletions
+3
View File
@@ -13,6 +13,9 @@
*.sln *.sln
*.vcxproj.* *.vcxproj.*
*.vcxproj.user *.vcxproj.user
*.iss
*.rtf
install.ico
# Собранные файлы и каталоги # Собранные файлы и каталоги
build-*/ build-*/
+110 -606
View File
File diff suppressed because it is too large Load Diff
+659 -719
View File
File diff suppressed because it is too large Load Diff
+84 -140
View File
@@ -17,16 +17,15 @@ UserWidget::UserWidget(UserManager* userManager, QWidget *parent)
connect(m_tableWidget, &QTableWidget::customContextMenuRequested, connect(m_tableWidget, &QTableWidget::customContextMenuRequested,
this, &UserWidget::showContextMenu); this, &UserWidget::showContextMenu);
setupContextMenu(); // Добавляем инициализацию контекстного меню setupContextMenu();
// Подключаем сигналы если менеджер уже есть
if (m_userManager) { if (m_userManager) {
connectSignals(); connectSignals();
} }
// Таймер для периодического обновления
m_refreshTimer = new QTimer(this); m_refreshTimer = new QTimer(this);
connect(m_refreshTimer, &QTimer::timeout, this, &UserWidget::onRefreshTimer); connect(m_refreshTimer, &QTimer::timeout, this, &UserWidget::onRefreshTimer);
m_refreshTimer->start(30000); // 30 секунд m_refreshTimer->start(30000);
refreshData(); refreshData();
} }
@@ -40,7 +39,6 @@ UserWidget::~UserWidget()
void UserWidget::setUserManager(UserManager* userManager) void UserWidget::setUserManager(UserManager* userManager)
{ {
// Отключаем старые соединения если были
if (m_userManager) { if (m_userManager) {
disconnectSignals(); disconnectSignals();
} }
@@ -76,14 +74,26 @@ void UserWidget::disconnectSignals()
void UserWidget::setupUI() void UserWidget::setupUI()
{ {
// ------------------------------------------------------------
// 1. Глобальные настройки самого виджета
// ------------------------------------------------------------
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
setMinimumSize(400, 300); // гарантия, что виджет не сожмётся до нуля
// ------------------------------------------------------------
// 2. Главный вертикальный layout
// ------------------------------------------------------------
QVBoxLayout* mainLayout = new QVBoxLayout(this); QVBoxLayout* mainLayout = new QVBoxLayout(this);
mainLayout->setContentsMargins(5, 5, 5, 5); mainLayout->setContentsMargins(5, 5, 5, 5);
mainLayout->setSpacing(5); mainLayout->setSpacing(5);
mainLayout->setSizeConstraint(QLayout::SetDefaultConstraint);
// Панель инструментов // ------------------------------------------------------------
// 3. Панель инструментов (фильтр, поиск, кнопка обновления)
// ------------------------------------------------------------
QHBoxLayout* toolbarLayout = new QHBoxLayout(); QHBoxLayout* toolbarLayout = new QHBoxLayout();
toolbarLayout->setSpacing(5);
// Фильтр
QLabel* filterLabel = new QLabel("Фильтр:", this); QLabel* filterLabel = new QLabel("Фильтр:", this);
m_filterCombo = new QComboBox(this); m_filterCombo = new QComboBox(this);
m_filterCombo->addItem("Все зрители", FilterAll); m_filterCombo->addItem("Все зрители", FilterAll);
@@ -91,70 +101,86 @@ void UserWidget::setupUI()
m_filterCombo->addItem("VIP", FilterVIPs); m_filterCombo->addItem("VIP", FilterVIPs);
m_filterCombo->addItem("Подписчики", FilterSubscribers); m_filterCombo->addItem("Подписчики", FilterSubscribers);
m_filterCombo->addItem("Активные (10 мин)", FilterActive); m_filterCombo->addItem("Активные (10 мин)", FilterActive);
m_filterCombo->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
connect(m_filterCombo, QOverload<int>::of(&QComboBox::currentIndexChanged), connect(m_filterCombo, QOverload<int>::of(&QComboBox::currentIndexChanged),
this, &UserWidget::onFilterChanged); this, &UserWidget::onFilterChanged);
// Поиск
QLabel* searchLabel = new QLabel("Поиск:", this); QLabel* searchLabel = new QLabel("Поиск:", this);
m_searchEdit = new QLineEdit(this); m_searchEdit = new QLineEdit(this);
m_searchEdit->setPlaceholderText("Введите имя зрителя..."); m_searchEdit->setPlaceholderText("Имя зрителя...");
m_searchEdit->setClearButtonEnabled(true); m_searchEdit->setClearButtonEnabled(true);
m_searchEdit->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
connect(m_searchEdit, &QLineEdit::textChanged, connect(m_searchEdit, &QLineEdit::textChanged,
this, &UserWidget::onSearchTextChanged); this, &UserWidget::onSearchTextChanged);
// Кнопка обновления
QPushButton* refreshBtn = new QPushButton("Обновить", this); QPushButton* refreshBtn = new QPushButton("Обновить", this);
refreshBtn->setFixedWidth(100); refreshBtn->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
refreshBtn->setMaximumWidth(100);
connect(refreshBtn, &QPushButton::clicked, connect(refreshBtn, &QPushButton::clicked,
this, &UserWidget::onRefreshButtonClicked); this, &UserWidget::onRefreshButtonClicked);
toolbarLayout->addWidget(filterLabel); toolbarLayout->addWidget(filterLabel);
toolbarLayout->addWidget(m_filterCombo); toolbarLayout->addWidget(m_filterCombo);
toolbarLayout->addWidget(searchLabel); toolbarLayout->addWidget(searchLabel);
toolbarLayout->addWidget(m_searchEdit); toolbarLayout->addWidget(m_searchEdit, 1);
toolbarLayout->addStretch(); toolbarLayout->addStretch();
toolbarLayout->addWidget(refreshBtn); toolbarLayout->addWidget(refreshBtn);
// Таблица // ------------------------------------------------------------
// 4. Таблица пользователей
// ------------------------------------------------------------
m_tableWidget = new QTableWidget(this); m_tableWidget = new QTableWidget(this);
m_tableWidget->setColumnCount(6); m_tableWidget->setColumnCount(6);
m_tableWidget->setHorizontalHeaderLabels( m_tableWidget->setHorizontalHeaderLabels(
QStringList() << "Имя" << "Сообщений" << "Статус" QStringList() << "Имя" << "Сообщений" << "Статус"
<< "VIP" << "Подписчик" << "Последняя активность"); << "VIP" << "Подписчик" << "Последняя активность");
// Настройка таблицы
m_tableWidget->setSortingEnabled(true); m_tableWidget->setSortingEnabled(true);
m_tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows); m_tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
m_tableWidget->setAlternatingRowColors(true); m_tableWidget->setAlternatingRowColors(true);
m_tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers); m_tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
m_tableWidget->setSelectionMode(QAbstractItemView::SingleSelection); m_tableWidget->setSelectionMode(QAbstractItemView::SingleSelection);
m_tableWidget->horizontalHeader()->setStretchLastSection(true);
m_tableWidget->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft);
m_tableWidget->verticalHeader()->setVisible(false); m_tableWidget->verticalHeader()->setVisible(false);
// Настройка ширины колонок // Политика размеров таблицы – активное расширение
m_tableWidget->setColumnWidth(0, 250); // Имя m_tableWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
m_tableWidget->setColumnWidth(1, 80); // Сообщений m_tableWidget->setMinimumHeight(200); // минимальная высота для отображения хоть чего-то
m_tableWidget->setColumnWidth(2, 100); // Статус
m_tableWidget->setColumnWidth(3, 50); // VIP // Настройка ширины колонок (интерактивно, последняя растягивается)
m_tableWidget->setColumnWidth(4, 80); // Подписчик QHeaderView* header = m_tableWidget->horizontalHeader();
// Последняя колонка растягивается header->setStretchLastSection(true);
header->setSectionResizeMode(QHeaderView::Interactive);
// Начальные предпочтительные ширины
m_tableWidget->setColumnWidth(0, 200);
m_tableWidget->setColumnWidth(1, 80);
m_tableWidget->setColumnWidth(2, 100);
m_tableWidget->setColumnWidth(3, 50);
m_tableWidget->setColumnWidth(4, 80);
connect(m_tableWidget, &QTableWidget::cellDoubleClicked, connect(m_tableWidget, &QTableWidget::cellDoubleClicked,
this, &UserWidget::onUserDoubleClicked); this, &UserWidget::onUserDoubleClicked);
// Статистика внизу // ------------------------------------------------------------
// 5. Панель статистики
// ------------------------------------------------------------
QHBoxLayout* statsLayout = new QHBoxLayout(); QHBoxLayout* statsLayout = new QHBoxLayout();
m_statsLabel = new QLabel(this); m_statsLabel = new QLabel(this);
m_statsLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
statsLayout->addWidget(m_statsLabel); statsLayout->addWidget(m_statsLabel);
statsLayout->addStretch(); statsLayout->addStretch();
// Добавляем всё на форму // ------------------------------------------------------------
// 6. Сборка интерфейса
// ------------------------------------------------------------
mainLayout->addLayout(toolbarLayout); mainLayout->addLayout(toolbarLayout);
mainLayout->addWidget(m_tableWidget); mainLayout->addWidget(m_tableWidget, 1); // растягиваем таблицу с коэффициентом 1
mainLayout->addLayout(statsLayout); mainLayout->addLayout(statsLayout);
setLayout(mainLayout); setLayout(mainLayout);
// Принудительно обновляем геометрию после установки layout
updateGeometry();
} }
void UserWidget::refreshData() void UserWidget::refreshData()
@@ -176,7 +202,6 @@ void UserWidget::populateTable()
QVector<User*> users; QVector<User*> users;
// Получаем пользователей в зависимости от фильтра
switch (m_currentFilter) { switch (m_currentFilter) {
case FilterAll: case FilterAll:
for (const User& user : m_userManager->getAllUsers()) { for (const User& user : m_userManager->getAllUsers()) {
@@ -197,11 +222,9 @@ void UserWidget::populateTable()
break; break;
} }
// Применяем поисковый фильтр
if (!m_searchText.isEmpty()) { if (!m_searchText.isEmpty()) {
QString searchLower = m_searchText.toLower(); QString searchLower = m_searchText.toLower();
QVector<User*> filteredUsers; QVector<User*> filteredUsers;
for (User* user : users) { for (User* user : users) {
if (user->displayName.toLower().contains(searchLower) || if (user->displayName.toLower().contains(searchLower) ||
user->login.toLower().contains(searchLower)) { user->login.toLower().contains(searchLower)) {
@@ -211,22 +234,18 @@ void UserWidget::populateTable()
users = filteredUsers; users = filteredUsers;
} }
// Заполняем таблицу
m_tableWidget->setRowCount(users.size()); m_tableWidget->setRowCount(users.size());
for (int i = 0; i < users.size(); ++i) { for (int i = 0; i < users.size(); ++i) {
User* user = users[i]; User* user = users[i];
// Имя
QTableWidgetItem* nameItem = new QTableWidgetItem(user->displayName); QTableWidgetItem* nameItem = new QTableWidgetItem(user->displayName);
nameItem->setData(Qt::UserRole, user->id); nameItem->setData(Qt::UserRole, user->id);
m_tableWidget->setItem(i, 0, nameItem); m_tableWidget->setItem(i, 0, nameItem);
// Количество сообщений
m_tableWidget->setItem(i, 1, m_tableWidget->setItem(i, 1,
new QTableWidgetItem(QString::number(user->messageCount))); new QTableWidgetItem(QString::number(user->messageCount)));
// Статус
QString status; QString status;
if (user->isModerator) status = "👑 Модератор"; if (user->isModerator) status = "👑 Модератор";
else if (user->isVIP) status = "⭐ VIP"; else if (user->isVIP) status = "⭐ VIP";
@@ -234,43 +253,35 @@ void UserWidget::populateTable()
else status = "👤 Зритель"; else status = "👤 Зритель";
m_tableWidget->setItem(i, 2, new QTableWidgetItem(status)); m_tableWidget->setItem(i, 2, new QTableWidgetItem(status));
// VIP
QTableWidgetItem* vipItem = new QTableWidgetItem(user->isVIP ? "Да" : "Нет"); QTableWidgetItem* vipItem = new QTableWidgetItem(user->isVIP ? "Да" : "Нет");
if (user->isVIP) { if (user->isVIP) vipItem->setForeground(Qt::darkGreen);
vipItem->setForeground(Qt::darkGreen);
}
m_tableWidget->setItem(i, 3, vipItem); m_tableWidget->setItem(i, 3, vipItem);
// Подписчик
QTableWidgetItem* subItem = new QTableWidgetItem(user->isSubscriber ? "Да" : "Нет"); QTableWidgetItem* subItem = new QTableWidgetItem(user->isSubscriber ? "Да" : "Нет");
if (user->isSubscriber) { if (user->isSubscriber) subItem->setForeground(Qt::darkBlue);
subItem->setForeground(Qt::darkBlue);
}
m_tableWidget->setItem(i, 4, subItem); m_tableWidget->setItem(i, 4, subItem);
// Последняя активность
QString lastActive; QString lastActive;
if (user->lastMessageTime.isValid()) { if (user->lastMessageTime.isValid()) {
QDateTime now = QDateTime::currentDateTime(); QDateTime now = QDateTime::currentDateTime();
qint64 secs = user->lastMessageTime.secsTo(now); qint64 secs = user->lastMessageTime.secsTo(now);
if (secs < 60) lastActive = "Только что";
if (secs < 60) { else if (secs < 3600) lastActive = QString("%1 мин назад").arg(secs / 60);
lastActive = "Только что"; else if (secs < 86400) lastActive = QString("%1 ч назад").arg(secs / 3600);
} else if (secs < 3600) { else lastActive = user->lastMessageTime.toString("dd.MM.yyyy hh:mm");
lastActive = QString("%1 мин назад").arg(secs / 60);
} else if (secs < 86400) {
lastActive = QString("%1 ч назад").arg(secs / 3600);
} else {
lastActive = user->lastMessageTime.toString("dd.MM.yyyy hh:mm");
}
} else { } else {
lastActive = "Никогда"; lastActive = "Никогда";
} }
m_tableWidget->setItem(i, 5, new QTableWidgetItem(lastActive)); m_tableWidget->setItem(i, 5, new QTableWidgetItem(lastActive));
} }
// Автоподгон ширины колонок после заполнения // Автоподгон ширины колонок с ограничением
m_tableWidget->resizeColumnsToContents(); m_tableWidget->resizeColumnsToContents();
for (int col = 0; col < m_tableWidget->columnCount() - 1; ++col) {
if (m_tableWidget->columnWidth(col) > 300) {
m_tableWidget->setColumnWidth(col, 300);
}
}
} }
void UserWidget::updateStatistics() void UserWidget::updateStatistics()
@@ -292,16 +303,13 @@ void UserWidget::addUserToTable(const User &user)
int row = m_tableWidget->rowCount(); int row = m_tableWidget->rowCount();
m_tableWidget->insertRow(row); m_tableWidget->insertRow(row);
// Имя
QTableWidgetItem* nameItem = new QTableWidgetItem(user.displayName); QTableWidgetItem* nameItem = new QTableWidgetItem(user.displayName);
nameItem->setData(Qt::UserRole, user.id); nameItem->setData(Qt::UserRole, user.id);
m_tableWidget->setItem(row, 0, nameItem); m_tableWidget->setItem(row, 0, nameItem);
// Количество сообщений
m_tableWidget->setItem(row, 1, m_tableWidget->setItem(row, 1,
new QTableWidgetItem(QString::number(user.messageCount))); new QTableWidgetItem(QString::number(user.messageCount)));
// Статус
QString status; QString status;
if (user.isModerator) status = "👑 Модератор"; if (user.isModerator) status = "👑 Модератор";
else if (user.isVIP) status = "⭐ VIP"; else if (user.isVIP) status = "⭐ VIP";
@@ -309,23 +317,15 @@ void UserWidget::addUserToTable(const User &user)
else status = "👤 Зритель"; else status = "👤 Зритель";
m_tableWidget->setItem(row, 2, new QTableWidgetItem(status)); m_tableWidget->setItem(row, 2, new QTableWidgetItem(status));
// VIP
QTableWidgetItem* vipItem = new QTableWidgetItem(user.isVIP ? "Да" : "Нет"); QTableWidgetItem* vipItem = new QTableWidgetItem(user.isVIP ? "Да" : "Нет");
if (user.isVIP) { if (user.isVIP) vipItem->setForeground(Qt::darkGreen);
vipItem->setForeground(Qt::darkGreen);
}
m_tableWidget->setItem(row, 3, vipItem); m_tableWidget->setItem(row, 3, vipItem);
// Подписчик
QTableWidgetItem* subItem = new QTableWidgetItem(user.isSubscriber ? "Да" : "Нет"); QTableWidgetItem* subItem = new QTableWidgetItem(user.isSubscriber ? "Да" : "Нет");
if (user.isSubscriber) { if (user.isSubscriber) subItem->setForeground(Qt::darkBlue);
subItem->setForeground(Qt::darkBlue);
}
m_tableWidget->setItem(row, 4, subItem); m_tableWidget->setItem(row, 4, subItem);
// Последняя активность m_tableWidget->setItem(row, 5, new QTableWidgetItem("Только что"));
QString lastActive = "Только что";
m_tableWidget->setItem(row, 5, new QTableWidgetItem(lastActive));
updateStatistics(); updateStatistics();
} }
@@ -335,11 +335,9 @@ void UserWidget::updateUserInTable(const User &user)
for (int row = 0; row < m_tableWidget->rowCount(); ++row) { for (int row = 0; row < m_tableWidget->rowCount(); ++row) {
QTableWidgetItem* item = m_tableWidget->item(row, 0); QTableWidgetItem* item = m_tableWidget->item(row, 0);
if (item && item->data(Qt::UserRole).toString() == user.id) { if (item && item->data(Qt::UserRole).toString() == user.id) {
// Обновляем данные
item->setText(user.displayName); item->setText(user.displayName);
m_tableWidget->item(row, 1)->setText( m_tableWidget->item(row, 1)->setText(QString::number(user.messageCount));
QString::number(user.messageCount));
QString status; QString status;
if (user.isModerator) status = "👑 Модератор"; if (user.isModerator) status = "👑 Модератор";
@@ -349,34 +347,19 @@ void UserWidget::updateUserInTable(const User &user)
m_tableWidget->item(row, 2)->setText(status); m_tableWidget->item(row, 2)->setText(status);
m_tableWidget->item(row, 3)->setText(user.isVIP ? "Да" : "Нет"); m_tableWidget->item(row, 3)->setText(user.isVIP ? "Да" : "Нет");
if (user.isVIP) { m_tableWidget->item(row, 3)->setForeground(user.isVIP ? Qt::darkGreen : Qt::black);
m_tableWidget->item(row, 3)->setForeground(Qt::darkGreen);
} else {
m_tableWidget->item(row, 3)->setForeground(Qt::black);
}
m_tableWidget->item(row, 4)->setText(user.isSubscriber ? "Да" : "Нет"); m_tableWidget->item(row, 4)->setText(user.isSubscriber ? "Да" : "Нет");
if (user.isSubscriber) { m_tableWidget->item(row, 4)->setForeground(user.isSubscriber ? Qt::darkBlue : Qt::black);
m_tableWidget->item(row, 4)->setForeground(Qt::darkBlue);
} else {
m_tableWidget->item(row, 4)->setForeground(Qt::black);
}
// Обновляем время активности
QString lastActive; QString lastActive;
if (user.lastMessageTime.isValid()) { if (user.lastMessageTime.isValid()) {
QDateTime now = QDateTime::currentDateTime(); QDateTime now = QDateTime::currentDateTime();
qint64 secs = user.lastMessageTime.secsTo(now); qint64 secs = user.lastMessageTime.secsTo(now);
if (secs < 60) lastActive = "Только что";
if (secs < 60) { else if (secs < 3600) lastActive = QString("%1 мин назад").arg(secs / 60);
lastActive = "Только что"; else if (secs < 86400) lastActive = QString("%1 ч назад").arg(secs / 3600);
} else if (secs < 3600) { else lastActive = user.lastMessageTime.toString("dd.MM hh:mm");
lastActive = QString("%1 мин назад").arg(secs / 60);
} else if (secs < 86400) {
lastActive = QString("%1 ч назад").arg(secs / 3600);
} else {
lastActive = user.lastMessageTime.toString("dd.MM hh:mm");
}
} }
m_tableWidget->item(row, 5)->setText(lastActive); m_tableWidget->item(row, 5)->setText(lastActive);
@@ -388,7 +371,6 @@ void UserWidget::updateUserInTable(const User &user)
void UserWidget::removeUserFromTable(const QString &displayName) void UserWidget::removeUserFromTable(const QString &displayName)
{ {
// Ищем пользователя по displayName
for (int row = 0; row < m_tableWidget->rowCount(); ++row) { for (int row = 0; row < m_tableWidget->rowCount(); ++row) {
QTableWidgetItem* item = m_tableWidget->item(row, 0); QTableWidgetItem* item = m_tableWidget->item(row, 0);
if (item && item->text() == displayName) { if (item && item->text() == displayName) {
@@ -417,19 +399,12 @@ void UserWidget::onRefreshTimer()
User* user = m_userManager->findUserById(userId); User* user = m_userManager->findUserById(userId);
if (user && user->lastMessageTime.isValid()) { if (user && user->lastMessageTime.isValid()) {
qint64 secs = user->lastMessageTime.secsTo(now); qint64 secs = user->lastMessageTime.secsTo(now);
QString lastActive; QString lastActive;
if (secs < 60) { if (secs < 60) lastActive = "Только что";
lastActive = "Только что"; else if (secs < 3600) lastActive = QString("%1 мин назад").arg(secs / 60);
} else if (secs < 3600) { else if (secs < 86400) lastActive = QString("%1 ч назад").arg(secs / 3600);
lastActive = QString("%1 мин назад").arg(secs / 60); else lastActive = user->lastMessageTime.toString("dd.MM hh:mm");
} else if (secs < 86400) {
lastActive = QString("%1 ч назад").arg(secs / 3600);
} else {
lastActive = user->lastMessageTime.toString("dd.MM hh:mm");
}
// Проверяем, существует ли ячейка
if (m_tableWidget->item(row, 5)) { if (m_tableWidget->item(row, 5)) {
m_tableWidget->item(row, 5)->setText(lastActive); m_tableWidget->item(row, 5)->setText(lastActive);
} }
@@ -442,27 +417,17 @@ bool UserWidget::userMatchesFilter(const User* user) const
{ {
if (!user) return false; if (!user) return false;
// Проверка фильтра
switch (m_currentFilter) { switch (m_currentFilter) {
case FilterAll: case FilterAll: break;
break; case FilterModerators: if (!user->isModerator) return false; break;
case FilterModerators: case FilterVIPs: if (!user->isVIP) return false; break;
if (!user->isModerator) return false; case FilterSubscribers: if (!user->isSubscriber) return false; break;
break;
case FilterVIPs:
if (!user->isVIP) return false;
break;
case FilterSubscribers:
if (!user->isSubscriber) return false;
break;
case FilterActive: case FilterActive:
// Активные за последние 10 минут if (user->lastMessageTime.secsTo(QDateTime::currentDateTime()) > 10 * 60)
if (user->lastMessageTime.secsTo(QDateTime::currentDateTime()) > 10*60)
return false; return false;
break; break;
} }
// Проверка поиска
if (!m_searchText.isEmpty()) { if (!m_searchText.isEmpty()) {
QString searchLower = m_searchText.toLower(); QString searchLower = m_searchText.toLower();
if (!user->displayName.toLower().contains(searchLower) && if (!user->displayName.toLower().contains(searchLower) &&
@@ -476,7 +441,6 @@ bool UserWidget::userMatchesFilter(const User* user) const
void UserWidget::onUserAdded(const User &user) void UserWidget::onUserAdded(const User &user)
{ {
// Проверяем, проходит ли пользователь текущий фильтр и поиск
if (userMatchesFilter(&user)) { if (userMatchesFilter(&user)) {
addUserToTable(user); addUserToTable(user);
} }
@@ -484,22 +448,16 @@ void UserWidget::onUserAdded(const User &user)
void UserWidget::onUserUpdated(const User &user) void UserWidget::onUserUpdated(const User &user)
{ {
// Ищем пользователя в таблице
int row = findRowByUserId(user.id); int row = findRowByUserId(user.id);
if (row >= 0) { if (row >= 0) {
// Пользователь уже в таблице
if (userMatchesFilter(&user)) { if (userMatchesFilter(&user)) {
// Обновляем существующую запись
updateUserInTable(user); updateUserInTable(user);
} else { } else {
// Удаляем, так как пользователь больше не проходит фильтр
removeUserFromTableByUserId(user.id); removeUserFromTableByUserId(user.id);
} }
} else { } else {
// Пользователя нет в таблице
if (userMatchesFilter(&user)) { if (userMatchesFilter(&user)) {
// Добавляем, так как пользователь теперь проходит фильтр
addUserToTable(user); addUserToTable(user);
} }
} }
@@ -534,7 +492,6 @@ void UserWidget::onUserRemoved(const QString &userId, const QString &displayName
void UserWidget::onUserDoubleClicked(int row, int column) void UserWidget::onUserDoubleClicked(int row, int column)
{ {
Q_UNUSED(column); Q_UNUSED(column);
if (!m_userManager) return; if (!m_userManager) return;
QTableWidgetItem* item = m_tableWidget->item(row, 0); QTableWidgetItem* item = m_tableWidget->item(row, 0);
@@ -551,9 +508,6 @@ void UserWidget::onUserDoubleClicked(int row, int column)
<< "\nVIP:" << user->isVIP << "\nVIP:" << user->isVIP
<< "\nПодписчик:" << user->isSubscriber << "\nПодписчик:" << user->isSubscriber
<< "\nПоследнее сообщение:" << user->lastMessageTime.toString(); << "\nПоследнее сообщение:" << user->lastMessageTime.toString();
// Здесь можно открыть диалог с детальной информацией
// или выполнить другие действия
} }
} }
} }
@@ -610,38 +564,29 @@ void UserWidget::setupContextMenu()
connect(m_infoAction, &QAction::triggered, this, &UserWidget::onShowUserInfo); connect(m_infoAction, &QAction::triggered, this, &UserWidget::onShowUserInfo);
} }
// Добавляем обработчик контекстного меню:
void UserWidget::showContextMenu(const QPoint &pos) void UserWidget::showContextMenu(const QPoint &pos)
{ {
QTableWidgetItem* item = m_tableWidget->itemAt(pos); QTableWidgetItem* item = m_tableWidget->itemAt(pos);
if (!item) return;
if (!item) {
return; // Клик был не по ячейке (например, по заголовку или пустой области)
}
int row = item->row(); int row = item->row();
QTableWidgetItem* nameItem = m_tableWidget->item(row, 0); QTableWidgetItem* nameItem = m_tableWidget->item(row, 0);
if (nameItem) { if (nameItem) {
m_selectedUserId = nameItem->data(Qt::UserRole).toString(); m_selectedUserId = nameItem->data(Qt::UserRole).toString();
m_selectedUserName = nameItem->text(); m_selectedUserName = nameItem->text();
// Получаем данные пользователя
User* user = m_userManager->findUserById(m_selectedUserId); User* user = m_userManager->findUserById(m_selectedUserId);
if (user) { if (user) {
// Обновляем состояние пунктов меню
m_setModAction->setEnabled(!user->isModerator); m_setModAction->setEnabled(!user->isModerator);
m_removeModAction->setEnabled(user->isModerator); m_removeModAction->setEnabled(user->isModerator);
m_setVIPAction->setEnabled(!user->isVIP); m_setVIPAction->setEnabled(!user->isVIP);
m_removeVIPAction->setEnabled(user->isVIP); m_removeVIPAction->setEnabled(user->isVIP);
// Показываем меню в позиции клика
m_contextMenu->exec(m_tableWidget->viewport()->mapToGlobal(pos)); m_contextMenu->exec(m_tableWidget->viewport()->mapToGlobal(pos));
} }
} }
} }
// Добавляем вспомогательный метод:
User* UserWidget::getSelectedUser() User* UserWidget::getSelectedUser()
{ {
if (!m_selectedUserId.isEmpty()) { if (!m_selectedUserId.isEmpty()) {
@@ -650,7 +595,6 @@ User* UserWidget::getSelectedUser()
return nullptr; return nullptr;
} }
// Добавляем слоты для обработки действий меню:
void UserWidget::onBanUser() void UserWidget::onBanUser()
{ {
if (!m_selectedUserId.isEmpty() && !m_selectedUserName.isEmpty()) { if (!m_selectedUserId.isEmpty() && !m_selectedUserName.isEmpty()) {