Document channel list lifetime and validate row counters
This commit is contained in:
1 parent
8552cf8316
commit
1e3633ee56
2 files changed
+41
-11
No files matched your search
@@ -453,6 +453,9 @@ void ChannelList::selectChannel(const QString& channelId) {
|
||||
}
|
||||
|
||||
void ChannelList::setChannelPeersOnline(const QString& channelId, int count) {
|
||||
if (count < 0) {
|
||||
DEBUG_WARN(DEBUG_CATEGORY_CHAT, "ChannelList: invalid online count=%d channel=%s", count, qPrintable(channelId)); return;
|
||||
}
|
||||
int found = 0;
|
||||
for (int row = 0; row < m_model->rowCount(); row++) {
|
||||
QStandardItem* item = m_model->item(row);
|
||||
@@ -480,6 +483,9 @@ void ChannelList::setAutoConnectActive(bool active) {
|
||||
}
|
||||
|
||||
void ChannelList::setChannelUnreadCount(const QString& channelId, int count) {
|
||||
if (count < 0) {
|
||||
DEBUG_WARN(DEBUG_CATEGORY_CHAT, "ChannelList: invalid unread count=%d channel=%s", count, qPrintable(channelId)); return;
|
||||
}
|
||||
for (int row = 0; row < m_model->rowCount(); row++) {
|
||||
QStandardItem* item = m_model->item(row);
|
||||
if (item && item->data(ChannelChannelIdRole).toString() == channelId) {
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
/* Список каналов и PM с unread/online; загружает данные DbManager и принимает обновления bridge.
|
||||
* Выбор и действия пользователя передаёт наружу signals; виджет используется в GUI-потоке. */
|
||||
/* Список каналов и PM с unread/online; все методы и события используются в GUI-потоке.
|
||||
* DbManager заимствуется через QPointer; setDb/закрытие SQLite остаются обязанностью владельца БД.
|
||||
* loadChannels() читает самостоятельные снимки БД, bridge-события передаёт сюда внешний контроллер.
|
||||
* Собственные дочерние model/view/timer принадлежат виджету. Изменения ядра запрашиваются signals.
|
||||
* Контекстное меню хранит ID цели и проверяет наличие строки/поколение PM после вложенного event loop. */
|
||||
#pragma once
|
||||
|
||||
#include <QWidget>
|
||||
@@ -18,43 +21,64 @@ class CpuLoadIndicator;
|
||||
class ChannelList : public QWidget {
|
||||
Q_OBJECT
|
||||
public:
|
||||
/* Создаёт виджет с необязательной БД (без неё список пуст); parent владеет виджетом. */
|
||||
explicit ChannelList(DbManager* db = nullptr, QWidget *parent = nullptr);
|
||||
|
||||
/* Перечитывает список/непрочитанные из БД. Сохраняет выбор и онлайн-счётчики существующих групп;
|
||||
* если выбранная строка исчезла, выбирает первую доступную группу/PM. Выбор испускает channelSelected. */
|
||||
void loadChannels();
|
||||
/* Объединяет запросы в один запуск через 50 мс; таймер не периодический.
|
||||
* Отправляет owned-команды маршрута для видимых в БД PM; при недоступном ядре сбрасывает их online. */
|
||||
void refreshDmPresence();
|
||||
/* Принимает заимствованный снимок [conv_len:1][UTF-8 conv][peer:8][group:8], числа native-endian.
|
||||
* Проверяет точную длину; online = ненулевые peer и group, это доступность BGP-маршрута. */
|
||||
void onDmCallRoute(const uint8_t* data, int len);
|
||||
/* Останавливает отложенный запрос и сбрасывает кеш/точки доступности PM; не отменяет уже отправленные команды. */
|
||||
void clearDmPresence();
|
||||
/* Отмечает ожидающее удаление поколения PM; повторное действие в меню недоступно до результата. */
|
||||
void setDmDeleting(const QString& convId, quint64 generation, bool deleting);
|
||||
/* Выбирает существующий ID группы или "dm:<conv_id>"; пустой/неизвестный ID сохраняет текущий выбор. */
|
||||
void selectChannel(const QString& channelId);
|
||||
/* Обновляет онлайн-счётчик существующей строки; отрицательное count отклоняется с предупреждением. */
|
||||
void setChannelPeersOnline(const QString& channelId, int count);
|
||||
/* Задаёт общий индикатор автоподключения для существующих и последующих строк групп. */
|
||||
void setAutoConnectActive(bool active);
|
||||
/* Показывает процент CPU, ограниченный диапазоном 0..100. */
|
||||
void setCpuLoad(int percent);
|
||||
/* Задаёт unread существующей строки; отрицательное count отклоняется, изменившаяся роль уведомляется один раз. */
|
||||
void setChannelUnreadCount(const QString& channelId, int count);
|
||||
/* Возвращает unread строки либо 0, если ID отсутствует. */
|
||||
int getChannelUnreadCount(const QString& channelId) const;
|
||||
|
||||
signals:
|
||||
/* Выбрана строка (также после loadChannels); ID для PM имеет префикс "dm:". */
|
||||
void channelSelected(const QString& channelId);
|
||||
/* Запрос контроллеру подтвердить/удалить поколение PM; convId без префикса. */
|
||||
void dmDeleteRequested(const QString& convId, quint64 generation, const QString& name);
|
||||
/* Открыть файлы захваченной меню группы, если она по-прежнему присутствует в списке. */
|
||||
void filesRequested(const QString& channelId);
|
||||
/* Приняты локальные пути с CopyAction для выбранной числовой группы при готовом ядре/своём node ID.
|
||||
* Сигнал отложен до следующей итерации Qt, paths копируются; проверка файлов/загрузка — у получателя. */
|
||||
void ownFilesDropped(const QString& channelId, const QStringList& paths);
|
||||
/* Кнопки footer: присоединиться, создать группу, настройки и монитор соединений. */
|
||||
void joinRequested();
|
||||
void createGroupRequested();
|
||||
void settingsRequested();
|
||||
void connMonitorRequested();
|
||||
|
||||
protected:
|
||||
/* Принимает drag/drop в footer; фильтры устанавливаются на него и его кнопки/подписи. */
|
||||
bool eventFilter(QObject* target, QEvent* event) override;
|
||||
|
||||
private:
|
||||
QListView *m_listView;
|
||||
QStandardItemModel *m_model;
|
||||
QPointer<DbManager> m_db;
|
||||
QWidget *m_footer;
|
||||
QLabel *m_dropHint;
|
||||
bool m_autoConnectActive = false;
|
||||
QHash<QString, bool> m_dmOnline;
|
||||
QListView *m_listView; /* Дочерний view; секции не выбираются мышью. */
|
||||
QStandardItemModel *m_model; /* Дочерняя плоская модель, роли из channeldelegate.h. */
|
||||
QPointer<DbManager> m_db; /* Не владеет БД; обнуляется при уничтожении QObject. */
|
||||
QWidget *m_footer; /* Дочерняя панель действий и приёма файлов. */
|
||||
QLabel *m_dropHint; /* Дочерняя footer-подсказка, не перехватывает мышь. */
|
||||
bool m_autoConnectActive = false; /* Общее состояние автоподключения групп. */
|
||||
QHash<QString, bool> m_dmOnline; /* Последние снимки доступности conv_id, сохраняются при reload. */
|
||||
QHash<QString, quint64> m_dmDeleting; /* conv_id → поколение ожидающего удаления */
|
||||
QTimer* m_dmPresenceTimer;
|
||||
CpuLoadIndicator* m_cpuLoad;
|
||||
QTimer* m_dmPresenceTimer; /* Дочерний single-shot, debounce 50 мс. */
|
||||
CpuLoadIndicator* m_cpuLoad; /* Дочерний индикатор CPU 0..100. */
|
||||
};
|
||||
Reference in new issue
Block a user