diff --git a/share/translations/keepassxc_en.ts b/share/translations/keepassxc_en.ts index 952e491ae6..6bb5ae88d3 100644 --- a/share/translations/keepassxc_en.ts +++ b/share/translations/keepassxc_en.ts @@ -8902,6 +8902,17 @@ This option is deprecated, use --set-key-file instead. Cannot generate valid passphrases because the wordlist is too short + + Delete plugin data? + + + + Delete plugin data from Entry(s)? + + + + + QtIOCompressor @@ -9053,6 +9064,13 @@ This option is deprecated, use --set-key-file instead. (Expired) + + Delete plugin data from Entry(s)… + + + + + ReportsWidgetHealthcheck diff --git a/src/browser/BrowserService.cpp b/src/browser/BrowserService.cpp index 67e4b9c101..064b5fa508 100644 --- a/src/browser/BrowserService.cpp +++ b/src/browser/BrowserService.cpp @@ -977,6 +977,15 @@ bool BrowserService::deleteEntry(const QString& uuid) return true; } +void BrowserService::removePluginData(Entry* entry) const +{ + if (entry) { + entry->beginUpdate(); + entry->customData()->remove(BrowserService::KEEPASSXCBROWSER_NAME); + entry->endUpdate(); + } +} + QList BrowserService::searchEntries(const QSharedPointer& db, const QString& siteUrl, const QString& formUrl, diff --git a/src/browser/BrowserService.h b/src/browser/BrowserService.h index 943e8bac1e..801fd2ed3c 100644 --- a/src/browser/BrowserService.h +++ b/src/browser/BrowserService.h @@ -118,6 +118,7 @@ class BrowserService : public QObject const QSharedPointer& selectedDb = {}); bool updateEntry(const EntryParameters& entryParameters, const QString& uuid); bool deleteEntry(const QString& uuid); + void removePluginData(Entry* entry) const; QJsonArray findEntries(const EntryParameters& entryParameters, const StringPairList& keyList, bool* entriesFound); void requestGlobalAutoType(const QString& search); diff --git a/src/gui/GuiTools.cpp b/src/gui/GuiTools.cpp index 30963b3741..b2dfa63f3a 100644 --- a/src/gui/GuiTools.cpp +++ b/src/gui/GuiTools.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021 KeePassXC Team + * Copyright (C) 2024 KeePassXC Team * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -66,6 +66,21 @@ namespace GuiTools } } + bool confirmDeletePluginData(QWidget* parent, const QList& entries) + { + if (!parent || entries.isEmpty()) { + return false; + } + + auto answer = MessageBox::question(parent, + QObject::tr("Delete plugin data?"), + QObject::tr("Delete plugin data from Entry(s)?", "", entries.size()), + MessageBox::Delete | MessageBox::Cancel, + MessageBox::Cancel); + + return answer == MessageBox::Delete; + } + size_t deleteEntriesResolveReferences(QWidget* parent, const QList& entries, bool permanent) { if (!parent || entries.isEmpty()) { diff --git a/src/gui/GuiTools.h b/src/gui/GuiTools.h index 814537382b..c5e7108964 100644 --- a/src/gui/GuiTools.h +++ b/src/gui/GuiTools.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021 KeePassXC Team + * Copyright (C) 2024 KeePassXC Team * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -26,6 +26,7 @@ class Entry; namespace GuiTools { bool confirmDeleteEntries(QWidget* parent, const QList& entries, bool permanent); + bool confirmDeletePluginData(QWidget* parent, const QList& entries); size_t deleteEntriesResolveReferences(QWidget* parent, const QList& entries, bool permanent); } // namespace GuiTools #endif // KEEPASSXC_GUITOOLS_H diff --git a/src/gui/dbsettings/DatabaseSettingsWidgetBrowser.cpp b/src/gui/dbsettings/DatabaseSettingsWidgetBrowser.cpp index 7be2177109..7658475b3d 100644 --- a/src/gui/dbsettings/DatabaseSettingsWidgetBrowser.cpp +++ b/src/gui/dbsettings/DatabaseSettingsWidgetBrowser.cpp @@ -214,9 +214,7 @@ void DatabaseSettingsWidgetBrowser::removeStoredPermissions() } if (entry->customData()->contains(BrowserService::KEEPASSXCBROWSER_NAME)) { - entry->beginUpdate(); - entry->customData()->remove(BrowserService::KEEPASSXCBROWSER_NAME); - entry->endUpdate(); + browserService()->removePluginData(entry); ++counter; } progress.setValue(progress.value() + 1); diff --git a/src/gui/reports/ReportsWidgetBrowserStatistics.cpp b/src/gui/reports/ReportsWidgetBrowserStatistics.cpp index a7724a7e41..579840a24d 100644 --- a/src/gui/reports/ReportsWidgetBrowserStatistics.cpp +++ b/src/gui/reports/ReportsWidgetBrowserStatistics.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021 KeePassXC Team + * Copyright (C) 2024 KeePassXC Team * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -27,7 +27,6 @@ #include "gui/styles/StateColorPalette.h" #include -#include #include #include #include @@ -277,9 +276,19 @@ void ReportsWidgetBrowserStatistics::customMenuRequested(QPoint pos) } // Create the "delete entry" menu item - const auto delEntry = new QAction(icons()->icon("entry-delete"), tr("Delete Entry(s)…", "", selected.size()), this); - menu->addAction(delEntry); - connect(delEntry, &QAction::triggered, this, &ReportsWidgetBrowserStatistics::deleteSelectedEntries); + 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); + + // Create the "delete plugin data" menu item + const auto deletePluginData = + new QAction(icons()->icon("entry-delete"), tr("Delete plugin data from Entry(s)…", "", selected.size()), this); + menu->addAction(deletePluginData); + connect(deletePluginData, + &QAction::triggered, + this, + &ReportsWidgetBrowserStatistics::deletePluginDataFromSelectedEntries); // Create the "exclude from reports" menu item const auto exclude = new QAction(icons()->icon("reports-exclude"), tr("Exclude from reports"), this); @@ -320,16 +329,9 @@ void ReportsWidgetBrowserStatistics::saveSettings() void ReportsWidgetBrowserStatistics::deleteSelectedEntries() { - 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; - } - } - + const auto& selectedEntries = getSelectedEntries(); bool permanent = !m_db->metadata()->recycleBinEnabled(); + if (GuiTools::confirmDeleteEntries(this, selectedEntries, permanent)) { GuiTools::deleteEntriesResolveReferences(this, selectedEntries, permanent); } @@ -337,6 +339,18 @@ void ReportsWidgetBrowserStatistics::deleteSelectedEntries() calculateBrowserStatistics(); } +void ReportsWidgetBrowserStatistics::deletePluginDataFromSelectedEntries() +{ + const auto& selectedEntries = getSelectedEntries(); + if (GuiTools::confirmDeletePluginData(this, selectedEntries)) { + for (auto& entry : selectedEntries) { + browserService()->removePluginData(entry); + } + } + + calculateBrowserStatistics(); +} + QMap ReportsWidgetBrowserStatistics::getBrowserConfigFromEntry(Entry* entry) const { QMap configList; @@ -372,3 +386,17 @@ QMap ReportsWidgetBrowserStatistics::getBrowserConfigFromE return configList; } + +QList ReportsWidgetBrowserStatistics::getSelectedEntries() 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; +} diff --git a/src/gui/reports/ReportsWidgetBrowserStatistics.h b/src/gui/reports/ReportsWidgetBrowserStatistics.h index 8aa6651eee..9de20086f9 100644 --- a/src/gui/reports/ReportsWidgetBrowserStatistics.h +++ b/src/gui/reports/ReportsWidgetBrowserStatistics.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2021 KeePassXC Team + * Copyright (C) 2024 KeePassXC Team * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -54,9 +54,11 @@ public slots: void emitEntryActivated(const QModelIndex& index); void customMenuRequested(QPoint); 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;