mirror of
https://github.com/keepassxreboot/keepassxc.git
synced 2025-01-15 17:27:43 -05:00
Add ability to delete groups via gui.
This commit is contained in:
parent
19bacd6737
commit
8467e7756d
@ -197,16 +197,21 @@ bool Database::hasKey()
|
|||||||
return m_hasKey;
|
return m_hasKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Database::recycleEntry(Entry* entry)
|
void Database::createRecycleBin()
|
||||||
{
|
{
|
||||||
if (m_metadata->recycleBinEnabled()) {
|
|
||||||
if (!m_metadata->recycleBin()) {
|
|
||||||
Group* recycleBin = new Group();
|
Group* recycleBin = new Group();
|
||||||
recycleBin->setUuid(Uuid::random());
|
recycleBin->setUuid(Uuid::random());
|
||||||
recycleBin->setName(tr("Recycle Bin"));
|
recycleBin->setName(tr("Recycle Bin"));
|
||||||
recycleBin->setIcon(43);
|
recycleBin->setIcon(43);
|
||||||
recycleBin->setParent(rootGroup());
|
recycleBin->setParent(rootGroup());
|
||||||
m_metadata->setRecycleBin(recycleBin);
|
m_metadata->setRecycleBin(recycleBin);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Database::recycleEntry(Entry* entry)
|
||||||
|
{
|
||||||
|
if (m_metadata->recycleBinEnabled()) {
|
||||||
|
if (!m_metadata->recycleBin()) {
|
||||||
|
createRecycleBin();
|
||||||
}
|
}
|
||||||
entry->setGroup(metadata()->recycleBin());
|
entry->setGroup(metadata()->recycleBin());
|
||||||
}
|
}
|
||||||
@ -214,3 +219,16 @@ void Database::recycleEntry(Entry* entry)
|
|||||||
delete entry;
|
delete entry;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Database::recycleGroup(Group* group)
|
||||||
|
{
|
||||||
|
if (m_metadata->recycleBinEnabled()) {
|
||||||
|
if (!m_metadata->recycleBin()) {
|
||||||
|
createRecycleBin();
|
||||||
|
}
|
||||||
|
group->setParent(metadata()->recycleBin());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
delete group;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -86,6 +86,7 @@ public:
|
|||||||
void updateKey(quint64 rounds);
|
void updateKey(quint64 rounds);
|
||||||
bool hasKey();
|
bool hasKey();
|
||||||
void recycleEntry(Entry* entry);
|
void recycleEntry(Entry* entry);
|
||||||
|
void recycleGroup(Group* group);
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void groupDataChanged(Group* group);
|
void groupDataChanged(Group* group);
|
||||||
@ -99,6 +100,8 @@ private:
|
|||||||
Entry* recFindEntry(const Uuid& uuid, Group* group);
|
Entry* recFindEntry(const Uuid& uuid, Group* group);
|
||||||
Group* recFindGroup(const Uuid& uuid, Group* group);
|
Group* recFindGroup(const Uuid& uuid, Group* group);
|
||||||
|
|
||||||
|
void createRecycleBin();
|
||||||
|
|
||||||
Metadata* m_metadata;
|
Metadata* m_metadata;
|
||||||
Group* m_rootGroup;
|
Group* m_rootGroup;
|
||||||
QList<DeletedObject> m_deletedObjects;
|
QList<DeletedObject> m_deletedObjects;
|
||||||
|
@ -44,6 +44,11 @@ Entry::~Entry()
|
|||||||
{
|
{
|
||||||
if (m_group) {
|
if (m_group) {
|
||||||
m_group->removeEntry(this);
|
m_group->removeEntry(this);
|
||||||
|
|
||||||
|
DeletedObject delEntry;
|
||||||
|
delEntry.deletionTime = QDateTime::currentDateTimeUtc();
|
||||||
|
delEntry.uuid = m_uuid;
|
||||||
|
m_group->addDeletedObject(delEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
qDeleteAll(m_history);
|
qDeleteAll(m_history);
|
||||||
@ -356,7 +361,14 @@ void Entry::setGroup(Group* group)
|
|||||||
{
|
{
|
||||||
if (m_group) {
|
if (m_group) {
|
||||||
m_group->removeEntry(this);
|
m_group->removeEntry(this);
|
||||||
|
if (m_group->database() != group->database()) {
|
||||||
|
DeletedObject delEntry;
|
||||||
|
delEntry.deletionTime = QDateTime::currentDateTimeUtc();
|
||||||
|
delEntry.uuid = m_uuid;
|
||||||
|
m_group->addDeletedObject(delEntry);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
group->addEntry(this);
|
group->addEntry(this);
|
||||||
m_group = group;
|
m_group = group;
|
||||||
QObject::setParent(group);
|
QObject::setParent(group);
|
||||||
|
@ -35,11 +35,30 @@ Group::Group()
|
|||||||
m_searchingEnabled = Inherit;
|
m_searchingEnabled = Inherit;
|
||||||
|
|
||||||
m_updateTimeinfo = true;
|
m_updateTimeinfo = true;
|
||||||
|
m_emitSignals = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Group::~Group()
|
Group::~Group()
|
||||||
{
|
{
|
||||||
cleanupParent();
|
cleanupParent();
|
||||||
|
m_emitSignals = false;
|
||||||
|
if (m_db && m_parent) {
|
||||||
|
|
||||||
|
QList<Entry*> entries = m_entries;
|
||||||
|
Q_FOREACH (Entry* entry, entries) {
|
||||||
|
delete entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<Group*> children = m_children;
|
||||||
|
Q_FOREACH (Group* group, children) {
|
||||||
|
delete group;
|
||||||
|
}
|
||||||
|
|
||||||
|
DeletedObject delGroup;
|
||||||
|
delGroup.deletionTime = QDateTime::currentDateTimeUtc();
|
||||||
|
delGroup.uuid = m_uuid;
|
||||||
|
m_db->addDeletedObject(delGroup);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class P, class V> bool Group::set(P& property, const V& value) {
|
template <class P, class V> bool Group::set(P& property, const V& value) {
|
||||||
@ -66,6 +85,11 @@ void Group::setUpdateTimeinfo(bool value) {
|
|||||||
m_updateTimeinfo = value;
|
m_updateTimeinfo = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Group::emitSignals()
|
||||||
|
{
|
||||||
|
return m_emitSignals;
|
||||||
|
}
|
||||||
|
|
||||||
Uuid Group::uuid() const
|
Uuid Group::uuid() const
|
||||||
{
|
{
|
||||||
return m_uuid;
|
return m_uuid;
|
||||||
@ -255,6 +279,7 @@ void Group::setParent(Group* parent, int index)
|
|||||||
m_parent = parent;
|
m_parent = parent;
|
||||||
|
|
||||||
if (m_db != parent->m_db) {
|
if (m_db != parent->m_db) {
|
||||||
|
recCreateDelObjects();
|
||||||
recSetDatabase(parent->m_db);
|
recSetDatabase(parent->m_db);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -342,19 +367,19 @@ void Group::addEntry(Entry *entry)
|
|||||||
|
|
||||||
void Group::removeEntry(Entry* entry)
|
void Group::removeEntry(Entry* entry)
|
||||||
{
|
{
|
||||||
|
if (m_emitSignals) {
|
||||||
Q_EMIT entryAboutToRemove(entry);
|
Q_EMIT entryAboutToRemove(entry);
|
||||||
|
}
|
||||||
|
|
||||||
entry->disconnect(this);
|
entry->disconnect(this);
|
||||||
if (m_db) {
|
if (m_db) {
|
||||||
entry->disconnect(m_db);
|
entry->disconnect(m_db);
|
||||||
DeletedObject delObject;
|
|
||||||
delObject.deletionTime = QDateTime::currentDateTimeUtc();
|
|
||||||
delObject.uuid = entry->uuid();
|
|
||||||
m_db->addDeletedObject(delObject);
|
|
||||||
}
|
}
|
||||||
m_entries.removeAll(entry);
|
m_entries.removeAll(entry);
|
||||||
|
if (m_emitSignals) {
|
||||||
Q_EMIT modified();
|
Q_EMIT modified();
|
||||||
Q_EMIT entryRemoved();
|
Q_EMIT entryRemoved();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Group::recSetDatabase(Database* db)
|
void Group::recSetDatabase(Database* db)
|
||||||
@ -392,9 +417,41 @@ void Group::recSetDatabase(Database* db)
|
|||||||
void Group::cleanupParent()
|
void Group::cleanupParent()
|
||||||
{
|
{
|
||||||
if (m_parent) {
|
if (m_parent) {
|
||||||
|
if (m_parent->emitSignals()) {
|
||||||
Q_EMIT aboutToRemove(this);
|
Q_EMIT aboutToRemove(this);
|
||||||
|
}
|
||||||
m_parent->m_children.removeAll(this);
|
m_parent->m_children.removeAll(this);
|
||||||
|
if (m_parent->emitSignals()) {
|
||||||
Q_EMIT modified();
|
Q_EMIT modified();
|
||||||
Q_EMIT removed();
|
Q_EMIT removed();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Group::recCreateDelObjects()
|
||||||
|
{
|
||||||
|
if (m_db) {
|
||||||
|
DeletedObject delGroup;
|
||||||
|
delGroup.deletionTime = QDateTime::currentDateTimeUtc();
|
||||||
|
delGroup.uuid = m_uuid;
|
||||||
|
m_db->addDeletedObject(delGroup);
|
||||||
|
|
||||||
|
Q_FOREACH (Entry* entry, m_entries) {
|
||||||
|
DeletedObject delEntry;
|
||||||
|
delEntry.deletionTime = QDateTime::currentDateTimeUtc();
|
||||||
|
delEntry.uuid = entry->uuid();
|
||||||
|
m_db->addDeletedObject(delEntry);
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_FOREACH (Group* group, m_children) {
|
||||||
|
group->recCreateDelObjects();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Group::addDeletedObject(const DeletedObject& delObj)
|
||||||
|
{
|
||||||
|
if (m_db) {
|
||||||
|
m_db->addDeletedObject(delObj);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -75,6 +75,9 @@ public:
|
|||||||
QList<Entry*> entries();
|
QList<Entry*> entries();
|
||||||
const QList<Entry*>& entries() const;
|
const QList<Entry*>& entries() const;
|
||||||
QList<Entry*> entriesRecursive(bool includeHistoryItems = false);
|
QList<Entry*> entriesRecursive(bool includeHistoryItems = false);
|
||||||
|
bool emitSignals();
|
||||||
|
void addDeletedObject(const DeletedObject& delObj);
|
||||||
|
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void dataChanged(Group* group);
|
void dataChanged(Group* group);
|
||||||
@ -102,6 +105,7 @@ private:
|
|||||||
|
|
||||||
void recSetDatabase(Database* db);
|
void recSetDatabase(Database* db);
|
||||||
void cleanupParent();
|
void cleanupParent();
|
||||||
|
void recCreateDelObjects();
|
||||||
|
|
||||||
QPointer<Database> m_db;
|
QPointer<Database> m_db;
|
||||||
Uuid m_uuid;
|
Uuid m_uuid;
|
||||||
@ -122,6 +126,7 @@ private:
|
|||||||
QPixmapCache::Key m_pixmapCacheKey;
|
QPixmapCache::Key m_pixmapCacheKey;
|
||||||
|
|
||||||
bool m_updateTimeinfo;
|
bool m_updateTimeinfo;
|
||||||
|
bool m_emitSignals;
|
||||||
|
|
||||||
friend void Database::setRootGroup(Group* group);
|
friend void Database::setRootGroup(Group* group);
|
||||||
friend Entry::~Entry();
|
friend Entry::~Entry();
|
||||||
|
@ -302,6 +302,11 @@ void DatabaseTabWidget::editGroup()
|
|||||||
currentDatabaseWidget()->switchToGroupEdit();
|
currentDatabaseWidget()->switchToGroupEdit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DatabaseTabWidget::deleteGroup()
|
||||||
|
{
|
||||||
|
currentDatabaseWidget()->deleteGroup();
|
||||||
|
}
|
||||||
|
|
||||||
void DatabaseTabWidget::updateTabName(Database* db)
|
void DatabaseTabWidget::updateTabName(Database* db)
|
||||||
{
|
{
|
||||||
int index = databaseIndex(db);
|
int index = databaseIndex(db);
|
||||||
|
@ -66,6 +66,7 @@ public Q_SLOTS:
|
|||||||
void deleteEntry();
|
void deleteEntry();
|
||||||
void createGroup();
|
void createGroup();
|
||||||
void editGroup();
|
void editGroup();
|
||||||
|
void deleteGroup();
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void entrySelectionChanged(bool singleEntrySelected);
|
void entrySelectionChanged(bool singleEntrySelected);
|
||||||
|
@ -119,9 +119,6 @@ void DatabaseWidget::deleteEntry()
|
|||||||
if (result == QMessageBox::Yes) {
|
if (result == QMessageBox::Yes) {
|
||||||
delete m_entryView->currentEntry();
|
delete m_entryView->currentEntry();
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
m_db->recycleEntry(m_entryView->currentEntry());
|
m_db->recycleEntry(m_entryView->currentEntry());
|
||||||
@ -136,6 +133,24 @@ void DatabaseWidget::createGroup()
|
|||||||
switchToGroupEdit(m_newGroup, true);
|
switchToGroupEdit(m_newGroup, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DatabaseWidget::deleteGroup()
|
||||||
|
{
|
||||||
|
Q_ASSERT(canDeleteCurrentGoup());
|
||||||
|
|
||||||
|
bool inRecylceBin = Tools::hasChild(m_db->metadata()->recycleBin(), m_groupView->currentGroup());
|
||||||
|
if (inRecylceBin || !m_db->metadata()->recycleBinEnabled()) {
|
||||||
|
QMessageBox::StandardButton result = QMessageBox::question(
|
||||||
|
this, tr("Question"), tr("Do you really want to delete this group for good?"),
|
||||||
|
QMessageBox::Yes | QMessageBox::No);
|
||||||
|
if (result == QMessageBox::Yes) {
|
||||||
|
delete m_groupView->currentGroup();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
m_db->recycleGroup(m_groupView->currentGroup());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void DatabaseWidget::switchToView(bool accepted)
|
void DatabaseWidget::switchToView(bool accepted)
|
||||||
{
|
{
|
||||||
if (m_newGroup) {
|
if (m_newGroup) {
|
||||||
@ -235,3 +250,10 @@ bool DatabaseWidget::dbHasKey()
|
|||||||
{
|
{
|
||||||
return m_db->hasKey();
|
return m_db->hasKey();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool DatabaseWidget::canDeleteCurrentGoup()
|
||||||
|
{
|
||||||
|
bool isRootGroup = m_db->rootGroup() == m_groupView->currentGroup();
|
||||||
|
bool isRecycleBin = m_db->metadata()->recycleBin() == m_groupView->currentGroup();
|
||||||
|
return !isRootGroup && !isRecycleBin;
|
||||||
|
}
|
||||||
|
@ -40,6 +40,8 @@ public:
|
|||||||
EntryView* entryView();
|
EntryView* entryView();
|
||||||
bool dbHasKey();
|
bool dbHasKey();
|
||||||
void deleteEntry();
|
void deleteEntry();
|
||||||
|
void deleteGroup();
|
||||||
|
bool canDeleteCurrentGoup();
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void closeRequest();
|
void closeRequest();
|
||||||
|
@ -48,6 +48,7 @@ MainWindow::MainWindow()
|
|||||||
connect(m_ui->actionEntryDelete, SIGNAL(triggered()), m_ui->tabWidget, SLOT(deleteEntry()));
|
connect(m_ui->actionEntryDelete, SIGNAL(triggered()), m_ui->tabWidget, SLOT(deleteEntry()));
|
||||||
connect(m_ui->actionGroupNew, SIGNAL(triggered()), m_ui->tabWidget, SLOT(createGroup()));
|
connect(m_ui->actionGroupNew, SIGNAL(triggered()), m_ui->tabWidget, SLOT(createGroup()));
|
||||||
connect(m_ui->actionGroupEdit, SIGNAL(triggered()), m_ui->tabWidget, SLOT(editGroup()));
|
connect(m_ui->actionGroupEdit, SIGNAL(triggered()), m_ui->tabWidget, SLOT(editGroup()));
|
||||||
|
connect(m_ui->actionGroupDelete, SIGNAL(triggered()), m_ui->tabWidget, SLOT(deleteGroup()));
|
||||||
connect(m_ui->actionQuit, SIGNAL(triggered()), SLOT(close()));
|
connect(m_ui->actionQuit, SIGNAL(triggered()), SLOT(close()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,15 +80,13 @@ void MainWindow::setMenuActionState(int index)
|
|||||||
m_ui->actionEntryDelete->setEnabled(false);
|
m_ui->actionEntryDelete->setEnabled(false);
|
||||||
}
|
}
|
||||||
m_ui->actionGroupEdit->setEnabled(true);
|
m_ui->actionGroupEdit->setEnabled(true);
|
||||||
// TODO
|
|
||||||
/*
|
if (dbWidget->canDeleteCurrentGoup()) {
|
||||||
if () { //check if root group selected
|
m_ui->actionGroupDelete->setEnabled(true);
|
||||||
m_ui->actiocGroupDelete->setEnabled(true);
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
m_ui->actiocGroupDelete->setEnabled(false);
|
m_ui->actionGroupDelete->setEnabled(false);
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
m_ui->actionChangeMasterKey->setEnabled(true);
|
m_ui->actionChangeMasterKey->setEnabled(true);
|
||||||
m_ui->actionChangeDatabaseSettings->setEnabled(true);
|
m_ui->actionChangeDatabaseSettings->setEnabled(true);
|
||||||
m_ui->actionDatabaseSave->setEnabled(true);
|
m_ui->actionDatabaseSave->setEnabled(true);
|
||||||
@ -102,7 +101,7 @@ void MainWindow::setMenuActionState(int index)
|
|||||||
m_ui->actionEntryEdit->setEnabled(false);
|
m_ui->actionEntryEdit->setEnabled(false);
|
||||||
m_ui->actionGroupEdit->setEnabled(false);
|
m_ui->actionGroupEdit->setEnabled(false);
|
||||||
m_ui->actionEntryDelete->setEnabled(false);
|
m_ui->actionEntryDelete->setEnabled(false);
|
||||||
m_ui->actiocGroupDelete->setEnabled(false);
|
m_ui->actionGroupDelete->setEnabled(false);
|
||||||
m_ui->actionChangeMasterKey->setEnabled(false);
|
m_ui->actionChangeMasterKey->setEnabled(false);
|
||||||
m_ui->actionChangeDatabaseSettings->setEnabled(false);
|
m_ui->actionChangeDatabaseSettings->setEnabled(false);
|
||||||
m_ui->actionDatabaseSave->setEnabled(false);
|
m_ui->actionDatabaseSave->setEnabled(false);
|
||||||
@ -119,7 +118,7 @@ void MainWindow::setMenuActionState(int index)
|
|||||||
m_ui->actionEntryEdit->setEnabled(false);
|
m_ui->actionEntryEdit->setEnabled(false);
|
||||||
m_ui->actionGroupEdit->setEnabled(false);
|
m_ui->actionGroupEdit->setEnabled(false);
|
||||||
m_ui->actionEntryDelete->setEnabled(false);
|
m_ui->actionEntryDelete->setEnabled(false);
|
||||||
m_ui->actiocGroupDelete->setEnabled(false);
|
m_ui->actionGroupDelete->setEnabled(false);
|
||||||
m_ui->actionChangeMasterKey->setEnabled(false);
|
m_ui->actionChangeMasterKey->setEnabled(false);
|
||||||
m_ui->actionChangeDatabaseSettings->setEnabled(false);
|
m_ui->actionChangeDatabaseSettings->setEnabled(false);
|
||||||
m_ui->actionDatabaseSave->setEnabled(false);
|
m_ui->actionDatabaseSave->setEnabled(false);
|
||||||
|
@ -74,7 +74,7 @@
|
|||||||
</property>
|
</property>
|
||||||
<addaction name="actionGroupNew"/>
|
<addaction name="actionGroupNew"/>
|
||||||
<addaction name="actionGroupEdit"/>
|
<addaction name="actionGroupEdit"/>
|
||||||
<addaction name="actiocGroupDelete"/>
|
<addaction name="actionGroupDelete"/>
|
||||||
</widget>
|
</widget>
|
||||||
<addaction name="menuFile"/>
|
<addaction name="menuFile"/>
|
||||||
<addaction name="menuEntries"/>
|
<addaction name="menuEntries"/>
|
||||||
@ -175,7 +175,7 @@
|
|||||||
<string>Edit group</string>
|
<string>Edit group</string>
|
||||||
</property>
|
</property>
|
||||||
</action>
|
</action>
|
||||||
<action name="actiocGroupDelete">
|
<action name="actionGroupDelete">
|
||||||
<property name="enabled">
|
<property name="enabled">
|
||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
</property>
|
</property>
|
||||||
|
Loading…
Reference in New Issue
Block a user