Add group sorting feature

* Enabling sorting of groups and their children in ascending and descending direction
This commit is contained in:
Balazs Gyurak 2019-06-18 21:58:47 +01:00 committed by Jonathan White
parent 0c2d1bcc50
commit 09181fab13
15 changed files with 373 additions and 0 deletions

View file

@ -521,6 +521,11 @@ QStringList Group::hierarchy() const
return hierarchy;
}
bool Group::hasChildren() const
{
return !children().isEmpty();
}
Database* Group::database()
{
return m_db;
@ -1074,6 +1079,23 @@ void Group::applyGroupIconTo(Entry* entry)
}
}
void Group::sortChildrenRecursively(bool reverse)
{
std::sort(
m_children.begin(), m_children.end(), [reverse](const Group* childGroup1, const Group* childGroup2) -> bool {
QString name1 = childGroup1->name();
QString name2 = childGroup2->name();
return reverse ? name1.compare(name2, Qt::CaseInsensitive) > 0
: name1.compare(name2, Qt::CaseInsensitive) < 0;
});
for (auto child : m_children) {
child->sortChildrenRecursively(reverse);
}
emit groupModified();
}
bool Group::GroupData::operator==(const Group::GroupData& other) const
{
return equals(other, CompareItemDefault);

View file

@ -144,6 +144,7 @@ public:
const Group* parentGroup() const;
void setParent(Group* parent, int index = -1);
QStringList hierarchy() const;
bool hasChildren() const;
Database* database();
const Database* database() const;
@ -169,6 +170,8 @@ public:
void applyGroupIconTo(Entry* entry);
void sortChildrenRecursively(bool reverse = false);
signals:
void groupDataChanged(Group* group);
void groupAboutToAdd(Group* group, int index);

View file

@ -1073,6 +1073,16 @@ void DatabaseWidget::switchToGroupEdit()
switchToGroupEdit(group, false);
}
void DatabaseWidget::sortGroupsAsc()
{
m_groupView->sortGroups();
}
void DatabaseWidget::sortGroupsDesc()
{
m_groupView->sortGroups(true);
}
void DatabaseWidget::switchToMasterKeyChange()
{
switchToDatabaseSettings();

View file

@ -175,6 +175,8 @@ public slots:
void switchToMainView(bool previousDialogAccepted = false);
void switchToEntryEdit();
void switchToGroupEdit();
void sortGroupsAsc();
void sortGroupsDesc();
void switchToMasterKeyChange();
void switchToDatabaseSettings();
void switchToOpenDatabase();

View file

@ -380,6 +380,8 @@ MainWindow::MainWindow()
m_actionMultiplexer.connect(m_ui->actionGroupEdit, SIGNAL(triggered()), SLOT(switchToGroupEdit()));
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()));
m_actionMultiplexer.connect(m_ui->actionGroupSortDesc, SIGNAL(triggered()), SLOT(sortGroupsDesc()));
connect(m_ui->actionSettings, SIGNAL(toggled(bool)), SLOT(switchToSettings(bool)));
connect(m_ui->actionPasswordGenerator, SIGNAL(toggled(bool)), SLOT(switchToPasswordGen(bool)));
@ -570,6 +572,7 @@ void MainWindow::setMenuActionState(DatabaseWidget::Mode mode)
bool singleEntrySelected = dbWidget->numberOfSelectedEntries() == 1 && hasFocus;
bool entriesSelected = dbWidget->numberOfSelectedEntries() > 0 && hasFocus;
bool groupSelected = dbWidget->isGroupSelected();
bool currentGroupHasChildren = dbWidget->currentGroup()->hasChildren();
bool recycleBinSelected = dbWidget->isRecycleBinSelected();
m_ui->actionEntryNew->setEnabled(true);
@ -592,6 +595,8 @@ void MainWindow::setMenuActionState(DatabaseWidget::Mode mode)
m_ui->actionGroupNew->setEnabled(groupSelected);
m_ui->actionGroupEdit->setEnabled(groupSelected);
m_ui->actionGroupDelete->setEnabled(groupSelected && dbWidget->canDeleteCurrentGroup());
m_ui->actionGroupSortAsc->setEnabled(groupSelected && currentGroupHasChildren);
m_ui->actionGroupSortDesc->setEnabled(groupSelected && currentGroupHasChildren);
m_ui->actionGroupEmptyRecycleBin->setVisible(recycleBinSelected);
m_ui->actionGroupEmptyRecycleBin->setEnabled(recycleBinSelected);
m_ui->actionChangeMasterKey->setEnabled(true);

View file

@ -281,6 +281,9 @@
<addaction name="actionGroupEdit"/>
<addaction name="actionGroupDelete"/>
<addaction name="actionGroupEmptyRecycleBin"/>
<addaction name="separator"/>
<addaction name="actionGroupSortAsc"/>
<addaction name="actionGroupSortDesc"/>
</widget>
<widget class="QMenu" name="menuTools">
<property name="title">
@ -452,6 +455,22 @@
<string>&amp;Delete group</string>
</property>
</action>
<action name="actionGroupSortAsc">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Sort &amp;A-Z</string>
</property>
</action>
<action name="actionGroupSortDesc">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Sort &amp;Z-A</string>
</property>
</action>
<action name="actionDatabaseSaveAs">
<property name="enabled">
<bool>false</bool>

View file

@ -410,3 +410,30 @@ void GroupModel::groupMoved()
{
endMoveRows();
}
void GroupModel::sortChildren(Group* rootGroup, bool reverse)
{
emit layoutAboutToBeChanged();
QList<QModelIndex> oldIndexes;
collectIndexesRecursively(oldIndexes, rootGroup->children());
rootGroup->sortChildrenRecursively(reverse);
QList<QModelIndex> newIndexes;
collectIndexesRecursively(newIndexes, rootGroup->children());
for (int i = 0; i < oldIndexes.count(); i++) {
changePersistentIndex(oldIndexes[i], newIndexes[i]);
}
emit layoutChanged();
}
void GroupModel::collectIndexesRecursively(QList<QModelIndex>& indexes, QList<Group*> groups)
{
for (auto group : groups) {
indexes.append(index(group));
collectIndexesRecursively(indexes, group->children());
}
}

View file

@ -45,9 +45,11 @@ public:
dropMimeData(const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent) override;
QStringList mimeTypes() const override;
QMimeData* mimeData(const QModelIndexList& indexes) const override;
void sortChildren(Group* rootGroup, bool reverse = false);
private:
QModelIndex parent(Group* group) const;
void collectIndexesRecursively(QList<QModelIndex>& indexes, QList<Group*> groups);
private slots:
void groupDataChanged(Group* group);

View file

@ -115,6 +115,14 @@ void GroupView::expandGroup(Group* group, bool expand)
setExpanded(index, expand);
}
void GroupView::sortGroups(bool reverse)
{
Group* group = currentGroup();
if (group) {
m_model->sortChildren(group, reverse);
}
}
void GroupView::setModel(QAbstractItemModel* model)
{
Q_UNUSED(model);

View file

@ -35,6 +35,7 @@ public:
Group* currentGroup();
void setCurrentGroup(Group* group);
void expandGroup(Group* group, bool expand = true);
void sortGroups(bool reverse = false);
signals:
void groupSelectionChanged(Group* group);