- CategoryPanel: the left tree — All Downloads / Unfinished / Finished, then Categories and Queues populated from category.list / queue.list, with per-node task counts. Selecting a node emits a TaskSelection. - DownloadFilterProxy: QSortFilterProxyModel keyed off that selection. Client-side for M1 (the whole list fits); asTaskFilter() exposes the equivalent TaskFilter for a server-side download.list once paging lands. - MainWindow: menu bar (Tasks / Downloads / View / Help) sharing QAction objects with the toolbar; QSplitter [panel | table]; Delete with a confirm; Resume/Pause All; View menu toggles the panel. Actions disabled while offline. - Counts are computed off a throttled 400 ms timer, not the 4 Hz progress path. Fixed a debounce-vs-throttle bug found in the first screenshot: restarting the timer on every progress tick meant it never fired and the status bar sat at "0 of 0 downloads". - First-run column widths that fit the content. - tst_downloadfilterproxy: nodes filter to their own rows, the Finished/Unfinished split is correct, and the filter is dynamic (a row that finishes leaves the Unfinished node with no re-list). Verified against mockd --tasks 400 (screenshot: tree counts 75/84/89/83/69 sum to 400, status bar "400 of 400, 21 active"). Co-Authored-By: Claude Sonnet 5 <[email protected]> Claude-Session: https://claude.ai/code/session_016Ne28kx4VreeBWZv82Nksd
48 lines
1.4 KiB
C++
48 lines
1.4 KiB
C++
// The left-hand category tree. Lane GUI.
|
|
//
|
|
// docs/03-gui-spec.md §1: All Downloads / Unfinished / Finished, then Categories and
|
|
// Queues from category.list / queue.list. Selecting a node emits the filter the table
|
|
// should apply. Per-node counts come later (they need the full task set, not just the
|
|
// filtered page).
|
|
|
|
#pragma once
|
|
|
|
#include <QHash>
|
|
#include <QJsonArray>
|
|
#include <QWidget>
|
|
|
|
#include "models/DownloadFilterProxy.hpp"
|
|
|
|
class QTreeWidget;
|
|
class QTreeWidgetItem;
|
|
|
|
namespace velox::gui {
|
|
|
|
class CategoryPanel : public QWidget {
|
|
Q_OBJECT
|
|
|
|
public:
|
|
explicit CategoryPanel(QWidget *parent = nullptr);
|
|
|
|
public slots:
|
|
void setCategories(const QJsonArray &items);
|
|
void setQueues(const QJsonArray &items);
|
|
/// Per-node task counts, keyed by the node's filter. Missing keys render no count.
|
|
void setCounts(int all, int unfinished, int finished, const QHash<QString, int> &byCategory,
|
|
const QHash<QString, int> &byQueue);
|
|
|
|
signals:
|
|
void selectionChanged(const velox::gui::TaskSelection &selection);
|
|
|
|
private:
|
|
QTreeWidgetItem *makeItem(QTreeWidgetItem *parent, const QString &label,
|
|
const TaskSelection &sel);
|
|
void onCurrentItemChanged(QTreeWidgetItem *current);
|
|
|
|
QTreeWidget *tree_;
|
|
QTreeWidgetItem *categoriesRoot_;
|
|
QTreeWidgetItem *queuesRoot_;
|
|
};
|
|
|
|
} // namespace velox::gui
|