Skip to content

Commit bc23373

Browse files
Copilotjuzu-o
andcommitted
Add Show Subgroup Entries feature
Co-authored-by: juzu-o <[email protected]>
1 parent 41da5b2 commit bc23373

File tree

8 files changed

+77
-4
lines changed

8 files changed

+77
-4
lines changed

share/translations/keepassxc_en.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -577,6 +577,10 @@
577577
<source>Skip confirmation for main window Auto-Type actions</source>
578578
<translation type="unfinished"></translation>
579579
</message>
580+
<message>
581+
<source>Show subgroup entries in entry list view</source>
582+
<translation type="unfinished"></translation>
583+
</message>
580584
</context>
581585
<context>
582586
<name>ApplicationSettingsWidgetSecurity</name>

src/core/Config.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ static const QHash<Config::ConfigKey, ConfigDirective> configStrings = {
119119
{Config::GUI_CheckForUpdatesIncludeBetas, {QS("GUI/CheckForUpdatesIncludeBetas"), Roaming, false}},
120120
{Config::GUI_ShowExpiredEntriesOnDatabaseUnlock, {QS("GUI/ShowExpiredEntriesOnDatabaseUnlock"), Roaming, true}},
121121
{Config::GUI_ShowExpiredEntriesOnDatabaseUnlockOffsetDays, {QS("GUI/ShowExpiredEntriesOnDatabaseUnlockOffsetDays"), Roaming, 3}},
122+
{Config::GUI_ShowSubgroupEntries, {QS("GUI/ShowSubgroupEntries"), Roaming, false}},
122123
{Config::GUI_FontSizeOffset, {QS("GUI/FontSizeOffset"), Local, 0}},
123124

124125
{Config::GUI_MainWindowGeometry, {QS("GUI/MainWindowGeometry"), Local, {}}},

src/core/Config.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ class Config : public QObject
101101
SearchWaitForEnter,
102102
GUI_ShowExpiredEntriesOnDatabaseUnlock,
103103
GUI_ShowExpiredEntriesOnDatabaseUnlockOffsetDays,
104+
GUI_ShowSubgroupEntries,
104105
GUI_FontSizeOffset,
105106

106107
GUI_MainWindowGeometry,

src/gui/ApplicationSettingsWidget.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,7 @@ void ApplicationSettingsWidget::loadSettings()
214214
m_generalUi->dropToBackgroundOnCopyRadioButton->setChecked(config()->get(Config::DropToBackgroundOnCopy).toBool());
215215
m_generalUi->useGroupIconOnEntryCreationCheckBox->setChecked(
216216
config()->get(Config::UseGroupIconOnEntryCreation).toBool());
217+
m_generalUi->showSubgroupEntriesCheckBox->setChecked(config()->get(Config::GUI_ShowSubgroupEntries).toBool());
217218
m_generalUi->autoTypeEntryTitleMatchCheckBox->setChecked(config()->get(Config::AutoTypeEntryTitleMatch).toBool());
218219
m_generalUi->autoTypeEntryURLMatchCheckBox->setChecked(config()->get(Config::AutoTypeEntryURLMatch).toBool());
219220
m_generalUi->autoTypeHideExpiredEntryCheckBox->setChecked(config()->get(Config::AutoTypeHideExpiredEntry).toBool());
@@ -388,6 +389,7 @@ void ApplicationSettingsWidget::saveSettings()
388389
config()->set(Config::MinimizeOnCopy, m_generalUi->minimizeOnCopyRadioButton->isChecked());
389390
config()->set(Config::DropToBackgroundOnCopy, m_generalUi->dropToBackgroundOnCopyRadioButton->isChecked());
390391
config()->set(Config::UseGroupIconOnEntryCreation, m_generalUi->useGroupIconOnEntryCreationCheckBox->isChecked());
392+
config()->set(Config::GUI_ShowSubgroupEntries, m_generalUi->showSubgroupEntriesCheckBox->isChecked());
391393
config()->set(Config::AutoTypeEntryTitleMatch, m_generalUi->autoTypeEntryTitleMatchCheckBox->isChecked());
392394
config()->set(Config::AutoTypeEntryURLMatch, m_generalUi->autoTypeEntryURLMatchCheckBox->isChecked());
393395
config()->set(Config::AutoTypeHideExpiredEntry, m_generalUi->autoTypeHideExpiredEntryCheckBox->isChecked());

src/gui/ApplicationSettingsWidgetGeneral.ui

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -566,6 +566,13 @@
566566
</property>
567567
</widget>
568568
</item>
569+
<item>
570+
<widget class="QCheckBox" name="showSubgroupEntriesCheckBox">
571+
<property name="text">
572+
<string>Show subgroup entries in entry list view</string>
573+
</property>
574+
</widget>
575+
</item>
569576
<item>
570577
<widget class="QCheckBox" name="minimizeOnOpenUrlCheckBox">
571578
<property name="text">
@@ -1431,6 +1438,7 @@
14311438
<tabstop>EnableCopyOnDoubleClickCheckBox</tabstop>
14321439
<tabstop>openUrlOnDoubleClick</tabstop>
14331440
<tabstop>useGroupIconOnEntryCreationCheckBox</tabstop>
1441+
<tabstop>showSubgroupEntriesCheckBox</tabstop>
14341442
<tabstop>minimizeOnOpenUrlCheckBox</tabstop>
14351443
<tabstop>hideWindowOnCopyCheckBox</tabstop>
14361444
<tabstop>minimizeOnCopyRadioButton</tabstop>

src/gui/entry/EntryModel.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,13 @@ void EntryModel::setGroup(Group* group)
6868

6969
m_group = group;
7070
m_allGroups.clear();
71-
m_entries = group->entries();
71+
72+
// Check if we should show subgroup entries
73+
if (config()->get(Config::GUI_ShowSubgroupEntries).toBool()) {
74+
m_entries = group->entriesRecursive();
75+
} else {
76+
m_entries = group->entries();
77+
}
7278
m_orgEntries.clear();
7379

7480
makeConnections(group);
@@ -607,6 +613,12 @@ void EntryModel::onConfigChanged(Config::ConfigKey key)
607613
case Config::GUI_HidePasswords:
608614
emit dataChanged(index(0, Password), index(rowCount() - 1, Password), {Qt::DisplayRole});
609615
break;
616+
case Config::GUI_ShowSubgroupEntries:
617+
// Refresh the entry list when the subgroup setting changes
618+
if (m_group) {
619+
setGroup(m_group);
620+
}
621+
break;
610622
default:
611623
break;
612624
}

src/gui/entry/EntryView.cpp

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@
3333
#include "gui/Icons.h"
3434
#include "gui/SortFilterHideProxyModel.h"
3535

36+
#include "core/Config.h"
37+
3638
#define ICON_ONLY_SECTION_SIZE 26
3739

3840
class PasswordStrengthItemDelegate : public QStyledItemDelegate
@@ -94,6 +96,9 @@ EntryView::EntryView(QWidget* parent)
9496
emit entrySelectionChanged(currentEntry());
9597
});
9698

99+
// Listen for config changes to update Group column visibility
100+
connect(config(), &Config::changed, this, &EntryView::onConfigChanged);
101+
97102
new QShortcut(Qt::CTRL + Qt::Key_F10, this, SLOT(contextMenuShortcutPressed()), nullptr, Qt::WidgetShortcut);
98103

99104
resetViewToDefaults();
@@ -209,7 +214,16 @@ void EntryView::focusInEvent(QFocusEvent* event)
209214
void EntryView::displayGroup(Group* group)
210215
{
211216
m_model->setGroup(group);
212-
header()->hideSection(EntryModel::ParentGroup);
217+
218+
// Show Group column when subgroup entries are enabled, since entries from different groups will be shown
219+
// But respect user's preference if they've manually hidden it
220+
if (config()->get(Config::GUI_ShowSubgroupEntries).toBool() && !m_userHidGroupColumnInSubgroupMode) {
221+
header()->showSection(EntryModel::ParentGroup);
222+
} else if (!config()->get(Config::GUI_ShowSubgroupEntries).toBool()) {
223+
header()->hideSection(EntryModel::ParentGroup);
224+
}
225+
// If user has hidden the column in subgroup mode, don't force it to show
226+
213227
setFirstEntryActive();
214228
m_inSearchMode = false;
215229
}
@@ -355,7 +369,8 @@ void EntryView::showHeaderMenu(const QPoint& position)
355369
int columnIndex = action->data().toInt();
356370
action->setChecked(!isColumnHidden(columnIndex));
357371
}
358-
actions[EntryModel::ParentGroup]->setVisible(inSearchMode());
372+
actions[EntryModel::ParentGroup]->setVisible(inSearchMode()
373+
|| config()->get(Config::GUI_ShowSubgroupEntries).toBool());
359374

360375
m_headerMenu->popup(mapToGlobal(position));
361376
}
@@ -385,11 +400,21 @@ void EntryView::toggleColumnVisibility(QAction* action)
385400
if (header()->sectionSize(columnIndex) == 0) {
386401
header()->resizeSection(columnIndex, header()->defaultSectionSize());
387402
}
403+
// Reset flag when user manually shows Group column
404+
if (columnIndex == EntryModel::ParentGroup && !m_inSearchMode
405+
&& config()->get(Config::GUI_ShowSubgroupEntries).toBool()) {
406+
m_userHidGroupColumnInSubgroupMode = false;
407+
}
388408
resetFixedColumns();
389409
return;
390410
}
391411
if ((header()->count() - header()->hiddenSectionCount()) > 1) {
392412
header()->hideSection(columnIndex);
413+
// Track when user manually hides Group column while subgroup entries is enabled
414+
if (columnIndex == EntryModel::ParentGroup && !m_inSearchMode
415+
&& config()->get(Config::GUI_ShowSubgroupEntries).toBool()) {
416+
m_userHidGroupColumnInSubgroupMode = true;
417+
}
393418
return;
394419
}
395420
action->setChecked(true);
@@ -461,7 +486,8 @@ void EntryView::resetFixedColumns()
461486
void EntryView::resetViewToDefaults()
462487
{
463488
// Reduce number of columns that are shown by default
464-
if (m_inSearchMode) {
489+
if (m_inSearchMode
490+
|| (config()->get(Config::GUI_ShowSubgroupEntries).toBool() && !m_userHidGroupColumnInSubgroupMode)) {
465491
header()->showSection(EntryModel::ParentGroup);
466492
} else {
467493
header()->hideSection(EntryModel::ParentGroup);
@@ -595,3 +621,19 @@ bool EntryView::isColumnHidden(int logicalIndex)
595621
{
596622
return header()->isSectionHidden(logicalIndex) || header()->sectionSize(logicalIndex) == 0;
597623
}
624+
625+
void EntryView::onConfigChanged(Config::ConfigKey key)
626+
{
627+
if (key == Config::GUI_ShowSubgroupEntries && !m_inSearchMode) {
628+
// Reset user preference when setting is toggled - this allows the
629+
// Group column to auto-appear when re-enabling the feature
630+
m_userHidGroupColumnInSubgroupMode = false;
631+
632+
// Update Group column visibility when subgroup entries setting changes
633+
if (config()->get(Config::GUI_ShowSubgroupEntries).toBool()) {
634+
header()->showSection(EntryModel::ParentGroup);
635+
} else {
636+
header()->hideSection(EntryModel::ParentGroup);
637+
}
638+
}
639+
}

src/gui/entry/EntryView.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
#include <QTreeView>
2323

24+
#include "core/Config.h"
2425
#include "gui/entry/EntryModel.h"
2526

2627
class Entry;
@@ -72,6 +73,7 @@ private slots:
7273
void resetViewToDefaults();
7374
void contextMenuShortcutPressed();
7475
void sortIndicatorChanged(int logicalIndex, Qt::SortOrder order);
76+
void onConfigChanged(Config::ConfigKey key);
7577

7678
private:
7779
void resetFixedColumns();
@@ -84,6 +86,7 @@ private slots:
8486
Qt::SortOrder m_lastOrder;
8587
bool m_inSearchMode = false;
8688
bool m_columnsNeedRelayout = true;
89+
bool m_userHidGroupColumnInSubgroupMode = false;
8790

8891
QMenu* m_headerMenu;
8992
QActionGroup* m_columnActions;

0 commit comments

Comments
 (0)