From bcac630a9f792aa52a18e5cfdce2db72e388e529 Mon Sep 17 00:00:00 2001 From: Agoston Szepessy Date: Mon, 29 Dec 2025 02:44:56 -0800 Subject: [PATCH] Use `ReportsWidgetBase` for browser statistics --- src/gui/reports/ProxyModels.h | 13 +- src/gui/reports/ReportsWidgetBase.cpp | 13 ++ src/gui/reports/ReportsWidgetBase.h | 4 +- .../ReportsWidgetBrowserStatistics.cpp | 179 ++---------------- .../reports/ReportsWidgetBrowserStatistics.h | 13 +- src/gui/reports/ReportsWidgetHealthcheck.cpp | 2 +- src/gui/reports/ReportsWidgetHealthcheck.h | 6 +- 7 files changed, 42 insertions(+), 188 deletions(-) diff --git a/src/gui/reports/ProxyModels.h b/src/gui/reports/ProxyModels.h index a76f74f52..4d7481783 100644 --- a/src/gui/reports/ProxyModels.h +++ b/src/gui/reports/ProxyModels.h @@ -18,8 +18,8 @@ #ifndef KEEPASSXC_PROXYMODELS_H #define KEEPASSXC_PROXYMODELS_H -#include #include +#include enum class SortProxyModelKind { @@ -32,7 +32,9 @@ class HibpReportSortPoxyModel : public QSortFilterProxyModel { public: HibpReportSortPoxyModel(QObject* parent) - : QSortFilterProxyModel(parent){} + : QSortFilterProxyModel(parent) + { + } ~HibpReportSortPoxyModel() override = default; protected: @@ -40,8 +42,7 @@ protected: { // Sort count column by user data if (left.column() == 2) { - return sourceModel()->data(left, Qt::UserRole).toInt() - < sourceModel()->data(right, Qt::UserRole).toInt(); + return sourceModel()->data(left, Qt::UserRole).toInt() < sourceModel()->data(right, Qt::UserRole).toInt(); } // Otherwise use default sorting return QSortFilterProxyModel::lessThan(left, right); @@ -52,7 +53,9 @@ class HealthcheckReportSortProxyModel : public QSortFilterProxyModel { public: HealthcheckReportSortProxyModel(QObject* parent) - : QSortFilterProxyModel(parent){} + : QSortFilterProxyModel(parent) + { + } ~HealthcheckReportSortProxyModel() override = default; protected: diff --git a/src/gui/reports/ReportsWidgetBase.cpp b/src/gui/reports/ReportsWidgetBase.cpp index fd37f67cb..ac28af320 100644 --- a/src/gui/reports/ReportsWidgetBase.cpp +++ b/src/gui/reports/ReportsWidgetBase.cpp @@ -184,6 +184,19 @@ QMenu *ReportsWidgetBase::customMenuRequestedBase() return menu; } +QList ReportsWidgetBase::getSelectedEntries() const +{ + QList selectedEntries; + for (auto index : getTableView()->selectionModel()->selectedRows()) { + auto row = m_modelProxy->mapToSource(index).row(); + auto entry = m_rowToEntry[row].second; + if (entry) { + selectedEntries << entry; + } + } + return selectedEntries; +} + QList ReportsWidgetBase::getSelectedEntries() { QList selectedEntries; diff --git a/src/gui/reports/ReportsWidgetBase.h b/src/gui/reports/ReportsWidgetBase.h index 3208cf516..0fac24d34 100644 --- a/src/gui/reports/ReportsWidgetBase.h +++ b/src/gui/reports/ReportsWidgetBase.h @@ -44,9 +44,11 @@ public: virtual ~ReportsWidgetBase(); protected: - virtual QTableView *getTableView() = 0; + virtual QTableView *getTableView() const = 0; virtual void updateWidget() = 0; + QMenu *customMenuRequestedBase(); + QList getSelectedEntries() const; public slots: QList getSelectedEntries(); diff --git a/src/gui/reports/ReportsWidgetBrowserStatistics.cpp b/src/gui/reports/ReportsWidgetBrowserStatistics.cpp index 25f57aced..dfd56e9fc 100644 --- a/src/gui/reports/ReportsWidgetBrowserStatistics.cpp +++ b/src/gui/reports/ReportsWidgetBrowserStatistics.cpp @@ -93,10 +93,8 @@ BrowserStatistics::BrowserStatistics(QSharedPointer db) } ReportsWidgetBrowserStatistics::ReportsWidgetBrowserStatistics(QWidget* parent) - : QWidget(parent) + : ReportsWidgetBase(parent, SortProxyModelKind::Default) , m_ui(new Ui::ReportsWidgetBrowserStatistics()) - , m_referencesModel(new QStandardItemModel(this)) - , m_modelProxy(new QSortFilterProxyModel(this)) { m_ui->setupUi(this); @@ -265,35 +263,13 @@ void ReportsWidgetBrowserStatistics::emitEntryActivated(const QModelIndex& index void ReportsWidgetBrowserStatistics::customMenuRequested(QPoint pos) { - auto selected = m_ui->browserStatisticsTableView->selectionModel()->selectedRows(); - if (selected.isEmpty()) { + auto menu = customMenuRequestedBase(); + + if(!menu) { return; } - // Create the context menu - const auto menu = new QMenu(this); - - // Create the "edit entry" menu item (only if 1 row is selected) - if (selected.size() == 1) { - const auto edit = new QAction(icons()->icon("entry-edit"), tr("Edit Entry…"), this); - menu->addAction(edit); - connect(edit, &QAction::triggered, edit, [this, selected] { - auto row = m_modelProxy->mapToSource(selected[0]).row(); - auto entry = m_rowToEntry[row].second; - emit entryActivated(entry); - }); - } - - // Create the "expire entry" menu item - const auto expEntry = new QAction(icons()->icon("entry-expire"), tr("Expire Entry(s)…", "", selected.size()), this); - menu->addAction(expEntry); - connect(expEntry, &QAction::triggered, this, &ReportsWidgetBrowserStatistics::expireSelectedEntries); - - // Create the "delete entry" menu item - const auto deleteEntry = - new QAction(icons()->icon("entry-delete"), tr("Delete Entry(s)…", "", selected.size()), this); - menu->addAction(deleteEntry); - connect(deleteEntry, &QAction::triggered, this, &ReportsWidgetBrowserStatistics::deleteSelectedEntries); + auto selected = getTableView()->selectionModel()->selectedRows(); // Create the "delete plugin data" menu item const auto deletePluginData = @@ -304,99 +280,6 @@ void ReportsWidgetBrowserStatistics::customMenuRequested(QPoint pos) this, &ReportsWidgetBrowserStatistics::deletePluginDataFromSelectedEntries); - // Create the "exclude from reports" menu item - const auto excludeAction = new QAction(icons()->icon("reports-exclude"), tr("Exclude Entry(s) from reports"), this); - const auto excludeGroupsAction = - new QAction(icons()->icon("reports-exclude"), tr("Exclude Group(s) from reports"), this); - - bool isExcluded = false; - bool isGroupExcluded = false; - - for (auto index : selected) { - auto row = m_modelProxy->mapToSource(index).row(); - auto entry = m_rowToEntry[row].second; - if (entry) { - // If at least one entry is excluded switch to inclusion - if (entry->excludeFromReports() || entry->group()->excludeFromReports()) { - isExcluded = true; - } - if (entry->group()->excludeFromReports()) { - isGroupExcluded = true; - } - - break; - } - } - excludeAction->setCheckable(true); - excludeAction->setChecked(isExcluded); - - excludeGroupsAction->setCheckable(true); - excludeGroupsAction->setChecked(isGroupExcluded); - - menu->addAction(excludeAction); - connect(excludeAction, &QAction::toggled, excludeAction, [this, selected](bool checked) { - QSet groups; - - // If we are including entries (checked is false) but a group is excluded, ask the user if they - // would like to include the rest of the group as well (or keep it excluded). - // If they exclude it, we need to include the whole group, and then exclude - // the entries that aren't selected here. - if (!checked) { - for (const auto index : selected) { - auto row = m_modelProxy->mapToSource(index).row(); - auto entry = m_rowToEntry[row].second; - - if (entry) { - auto* group = entry->group(); - if (group->excludeFromReports() && !groups.contains(group)) { - QString msg = tr("The Group for \"%1\" is excluded. Would you like to include all Entries from " - "there as well?") - .arg(entry->title()); - auto response = MessageBox::question(this, - tr("Include Group?"), - msg, - MessageBox::Yes | MessageBox::No | MessageBox::Cancel, - MessageBox::No); - - if (response == MessageBox::Cancel) { - return; - } else if (response == MessageBox::Yes) { - group->setExcludeFromReports(false); - } else if (response == MessageBox::No) { - // We'll exclude all entries from the group here and then - // include the selected ones below - group->setExcludeFromReports(false); - group->markAllEntriesExcludedFromReports(); - } - - groups.insert(group); - } - } - } - } - - for (auto index : selected) { - auto row = m_modelProxy->mapToSource(index).row(); - auto entry = m_rowToEntry[row].second; - if (entry) { - entry->setExcludeFromReports(checked); - } - } - calculateBrowserStatistics(); - }); - - menu->addAction(excludeGroupsAction); - connect(excludeGroupsAction, &QAction::toggled, excludeGroupsAction, [this, selected](bool checked) { - for (const auto index : selected) { - auto row = m_modelProxy->mapToSource(index).row(); - auto entry = m_rowToEntry[row].second; - if (entry) { - entry->group()->setExcludeFromReports(checked); - } - } - calculateBrowserStatistics(); - }); - // Show the context menu menu->popup(m_ui->browserStatisticsTableView->viewport()->mapToGlobal(pos)); } @@ -406,40 +289,6 @@ void ReportsWidgetBrowserStatistics::saveSettings() // Nothing to do - the tab is passive } -QList ReportsWidgetBrowserStatistics::getSelectedEntries() -{ - QList selectedEntries; - for (auto index : m_ui->browserStatisticsTableView->selectionModel()->selectedRows()) { - auto row = m_modelProxy->mapToSource(index).row(); - auto entry = m_rowToEntry[row].second; - if (entry) { - selectedEntries << entry; - } - } - return selectedEntries; -} - -void ReportsWidgetBrowserStatistics::expireSelectedEntries() -{ - for (auto entry : getSelectedEntries()) { - entry->expireNow(); - } - - calculateBrowserStatistics(); -} - -void ReportsWidgetBrowserStatistics::deleteSelectedEntries() -{ - const auto& selectedEntries = getSelectedEntries(); - bool permanent = !m_db->metadata()->recycleBinEnabled(); - - if (GuiTools::confirmDeleteEntries(this, selectedEntries, permanent)) { - GuiTools::deleteEntriesResolveReferences(this, selectedEntries, permanent); - } - - calculateBrowserStatistics(); -} - void ReportsWidgetBrowserStatistics::deletePluginDataFromSelectedEntries() { const auto& selectedEntries = getSelectedEntries(); @@ -488,16 +337,12 @@ QMap ReportsWidgetBrowserStatistics::getBrowserConfigFromE return configList; } -QList ReportsWidgetBrowserStatistics::getSelectedEntries() const +QTableView *ReportsWidgetBrowserStatistics::getTableView() const { - QList selectedEntries; - for (auto index : m_ui->browserStatisticsTableView->selectionModel()->selectedRows()) { - auto row = m_modelProxy->mapToSource(index).row(); - auto entry = m_rowToEntry[row].second; - if (entry) { - selectedEntries << entry; - } - } - - return selectedEntries; + return m_ui->browserStatisticsTableView; +} + +void ReportsWidgetBrowserStatistics::updateWidget() +{ + calculateBrowserStatistics(); } diff --git a/src/gui/reports/ReportsWidgetBrowserStatistics.h b/src/gui/reports/ReportsWidgetBrowserStatistics.h index 9b1cc7d60..845aaa83a 100644 --- a/src/gui/reports/ReportsWidgetBrowserStatistics.h +++ b/src/gui/reports/ReportsWidgetBrowserStatistics.h @@ -19,6 +19,7 @@ #define KEEPASSXC_REPORTSWIDGETBROWSERSTATISTICS_H #include "gui/entry/EntryModel.h" +#include "gui/reports/ReportsWidgetBase.h" #include class Database; @@ -33,7 +34,7 @@ namespace Ui class ReportsWidgetBrowserStatistics; } -class ReportsWidgetBrowserStatistics : public QWidget +class ReportsWidgetBrowserStatistics : public ReportsWidgetBase { Q_OBJECT public: @@ -45,6 +46,8 @@ public: protected: void showEvent(QShowEvent* event) override; + void updateWidget() override; + QTableView *getTableView() const override; signals: void entryActivated(Entry*); @@ -53,23 +56,15 @@ public slots: void calculateBrowserStatistics(); void emitEntryActivated(const QModelIndex& index); void customMenuRequested(QPoint); - QList getSelectedEntries(); - void expireSelectedEntries(); - void deleteSelectedEntries(); void deletePluginDataFromSelectedEntries(); private: void addStatisticsRow(bool hasUrls, bool hasSettings, Group*, Entry*, bool); - QList getSelectedEntries() const; QMap getBrowserConfigFromEntry(Entry* entry) const; QScopedPointer m_ui; bool m_statisticsCalculated = false; - QScopedPointer m_referencesModel; - QScopedPointer m_modelProxy; - QSharedPointer m_db; - QList> m_rowToEntry; }; #endif // KEEPASSXC_REPORTSWIDGETBROWSERSTATISTICS_H diff --git a/src/gui/reports/ReportsWidgetHealthcheck.cpp b/src/gui/reports/ReportsWidgetHealthcheck.cpp index 92edb0e2f..a4debf7c7 100644 --- a/src/gui/reports/ReportsWidgetHealthcheck.cpp +++ b/src/gui/reports/ReportsWidgetHealthcheck.cpp @@ -343,7 +343,7 @@ void ReportsWidgetHealthcheck::updateWidget() calculateHealth(); } -QTableView *ReportsWidgetHealthcheck::getTableView() +QTableView *ReportsWidgetHealthcheck::getTableView() const { return m_ui->healthcheckTableView; } diff --git a/src/gui/reports/ReportsWidgetHealthcheck.h b/src/gui/reports/ReportsWidgetHealthcheck.h index cbe0e9d55..fd0c53c24 100644 --- a/src/gui/reports/ReportsWidgetHealthcheck.h +++ b/src/gui/reports/ReportsWidgetHealthcheck.h @@ -48,7 +48,7 @@ public: protected: void showEvent(QShowEvent* event) override; void updateWidget() override; - QTableView *getTableView() override; + QTableView *getTableView() const override; signals: void entryActivated(Entry*); @@ -65,10 +65,6 @@ private: QScopedPointer m_ui; bool m_healthCalculated = false; - // QScopedPointer m_referencesModel; - // QScopedPointer m_modelProxy; - // QSharedPointer m_db; - // QList> m_rowToEntry; }; #endif // KEEPASSXC_REPORTSWIDGETHEALTHCHECK_H