0
0
mirror of https://github.com/keepassxreboot/keepassxc.git synced 2024-09-20 04:12:15 +02:00

Add group clone action

Close #3796
This commit is contained in:
Stuzer05 2021-02-15 17:10:02 +02:00 committed by Jonathan White
parent bc5d0df19e
commit 304cb44d0d
9 changed files with 43 additions and 0 deletions

View File

@ -164,6 +164,7 @@ Files: share/icons/application/scalable/actions/chevron-double-down.svg
share/icons/application/scalable/actions/entry-edit.svg
share/icons/application/scalable/actions/entry-new.svg
share/icons/application/scalable/actions/favicon-download.svg
share/icons/application/scalable/actions/group-clone.svg
share/icons/application/scalable/actions/group-delete.svg
share/icons/application/scalable/actions/group-edit.svg
share/icons/application/scalable/actions/group-empty-trash.svg

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24"><path d="M6 2.58c-1.11 0-2 .89-2 2v1.572l-1.951-.007a1.99 1.99 0 0 0-2 2v12c0 1.11.89 2 2 2h16a1.99 1.99 0 0 0 2-2l-.01-1.565H22c1.11 0 2-.89 2-2v-10c0-1.11-.89-2-2-2h-8l-2-2H6zm0 4h16v10H6v-10zm10 2v2h-2v2h2v2h2v-2h2v-2h-2v-2h-2zM2.049 10.145 4 10.158v6.422c0 1.11.89 2 2 2h12.053l-.004 1.565h-16v-10z"/></svg>

After

Width:  |  Height:  |  Size: 374 B

View File

@ -40,6 +40,7 @@
<file>application/scalable/actions/getting-started.svg</file>
<file>application/scalable/actions/group-delete.svg</file>
<file>application/scalable/actions/group-edit.svg</file>
<file>application/scalable/actions/group-clone.svg</file>
<file>application/scalable/actions/group-empty-trash.svg</file>
<file>application/scalable/actions/group-new.svg</file>
<file>application/scalable/actions/hammer-wrench.svg</file>

View File

@ -905,6 +905,10 @@ Group* Group::clone(Entry::CloneFlags entryFlags, Group::CloneFlags groupFlags)
clonedGroup->m_data.timeInfo.setLocationChanged(now);
}
if (groupFlags & Group::CloneRenameTitle) {
clonedGroup->setName(tr("%1 - Clone").arg(name()));
}
return clonedGroup;
}

View File

@ -53,6 +53,7 @@ public:
CloneResetTimeInfo = 2, // set all TimeInfo attributes to the current time
CloneIncludeEntries = 4, // clone the group entries
CloneDefault = CloneNewUuid | CloneResetTimeInfo | CloneIncludeEntries,
CloneRenameTitle = 8, // add "- Clone" after the original title
};
Q_DECLARE_FLAGS(CloneFlags, CloneFlag)

View File

@ -826,6 +826,19 @@ void DatabaseWidget::createGroup()
switchToGroupEdit(m_newGroup.data(), true);
}
void DatabaseWidget::cloneGroup()
{
Group* currentGroup = m_groupView->currentGroup();
Q_ASSERT(currentGroup && canCloneCurrentGroup());
if (!currentGroup || !canCloneCurrentGroup()) {
return;
}
m_newGroup.reset(currentGroup->clone(Entry::CloneCopy, Group::CloneDefault | Group::CloneRenameTitle));
m_newParent = currentGroup->parentGroup();
switchToGroupEdit(m_newGroup.data(), true);
}
void DatabaseWidget::deleteGroup()
{
Group* currentGroup = m_groupView->currentGroup();
@ -1375,6 +1388,14 @@ void DatabaseWidget::onEntryChanged(Entry* entry)
emit entrySelectionChanged();
}
bool DatabaseWidget::canCloneCurrentGroup() const
{
bool isRootGroup = m_db->rootGroup() == m_groupView->currentGroup();
// bool isRecycleBin = isRecycleBinSelected();
return !isRootGroup;
}
bool DatabaseWidget::canDeleteCurrentGroup() const
{
bool isRootGroup = m_db->rootGroup() == m_groupView->currentGroup();

View File

@ -94,6 +94,7 @@ public:
EntryView* entryView();
Group* currentGroup() const;
bool canCloneCurrentGroup() const;
bool canDeleteCurrentGroup() const;
bool isGroupSelected() const;
bool isRecycleBinSelected() const;
@ -190,6 +191,7 @@ public slots:
void downloadAllFavicons();
void openUrlForEntry(Entry* entry);
void createGroup();
void cloneGroup();
void deleteGroup();
void switchToMainView(bool previousDialogAccepted = false);
void switchToEntryEdit();

View File

@ -390,6 +390,7 @@ MainWindow::MainWindow()
m_ui->actionGroupNew->setIcon(icons()->icon("group-new"));
m_ui->actionGroupEdit->setIcon(icons()->icon("group-edit"));
m_ui->actionGroupClone->setIcon(icons()->icon("group-clone"));
m_ui->actionGroupDelete->setIcon(icons()->icon("group-delete"));
m_ui->actionGroupEmptyRecycleBin->setIcon(icons()->icon("group-empty-trash"));
m_ui->actionEntryOpenUrl->setIcon(icons()->icon("web"));
@ -490,6 +491,7 @@ MainWindow::MainWindow()
m_actionMultiplexer.connect(m_ui->actionGroupNew, SIGNAL(triggered()), SLOT(createGroup()));
m_actionMultiplexer.connect(m_ui->actionGroupEdit, SIGNAL(triggered()), SLOT(switchToGroupEdit()));
m_actionMultiplexer.connect(m_ui->actionGroupClone, SIGNAL(triggered()), SLOT(cloneGroup()));
m_actionMultiplexer.connect(m_ui->actionGroupDelete, SIGNAL(triggered()), SLOT(deleteGroup()));
m_actionMultiplexer.connect(m_ui->actionGroupEmptyRecycleBin, SIGNAL(triggered()), SLOT(emptyRecycleBin()));
m_actionMultiplexer.connect(m_ui->actionGroupSortAsc, SIGNAL(triggered()), SLOT(sortGroupsAsc()));
@ -830,6 +832,7 @@ void MainWindow::setMenuActionState(DatabaseWidget::Mode mode)
|| (singleEntrySelected && dbWidget->currentEntryHasUrl()));
m_ui->actionGroupNew->setEnabled(groupSelected);
m_ui->actionGroupEdit->setEnabled(groupSelected);
m_ui->actionGroupClone->setEnabled(groupSelected && dbWidget->canCloneCurrentGroup());
m_ui->actionGroupDelete->setEnabled(groupSelected && dbWidget->canDeleteCurrentGroup());
m_ui->actionGroupSortAsc->setEnabled(groupSelected && currentGroupHasChildren);
m_ui->actionGroupSortDesc->setEnabled(groupSelected && currentGroupHasChildren);

View File

@ -337,6 +337,7 @@
</property>
<addaction name="actionGroupNew"/>
<addaction name="actionGroupEdit"/>
<addaction name="actionGroupClone"/>
<addaction name="actionGroupDelete"/>
<addaction name="actionGroupEmptyRecycleBin"/>
<addaction name="separator"/>
@ -1045,6 +1046,14 @@
<string notr="true">{USERNAME}{TAB}{PASSWORD}{ENTER}</string>
</property>
</action>
<action name="actionGroupClone">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Clone Group...</string>
</property>
</action>
</widget>
<customwidgets>
<customwidget>