Overhaul action states and add icons to toolbar

* Fixes #10981
This commit is contained in:
Jonathan White 2024-10-07 18:07:15 -04:00
parent 413eec9b8c
commit 3c26709da9
No known key found for this signature in database
GPG key ID: 440FC65F2E0C6E01
20 changed files with 431 additions and 433 deletions

View file

@ -126,6 +126,8 @@ MainWindow::MainWindow()
m_entryContextMenu = new QMenu(this);
m_entryContextMenu->setSeparatorsCollapsible(true);
m_entryContextMenu->addAction(m_ui->actionEntryRestore);
m_entryContextMenu->addSeparator();
m_entryContextMenu->addAction(m_ui->actionEntryCopyUsername);
m_entryContextMenu->addAction(m_ui->actionEntryCopyPassword);
m_entryContextMenu->addAction(m_ui->actionEntryCopyURL);
@ -153,8 +155,6 @@ MainWindow::MainWindow()
m_entryContextMenu->addSeparator();
m_entryContextMenu->addAction(m_ui->actionEntryAddToAgent);
m_entryContextMenu->addAction(m_ui->actionEntryRemoveFromAgent);
m_entryContextMenu->addSeparator();
m_entryContextMenu->addAction(m_ui->actionEntryRestore);
m_entryNewContextMenu = new QMenu(this);
m_entryNewContextMenu->addAction(m_ui->actionEntryNew);
@ -382,8 +382,10 @@ MainWindow::MainWindow()
m_ui->actionDatabaseSaveBackup->setIcon(icons()->icon("document-save-copy"));
m_ui->actionDatabaseClose->setIcon(icons()->icon("document-close"));
m_ui->actionReports->setIcon(icons()->icon("reports"));
m_ui->actionDatabaseSettings->setIcon(icons()->icon("document-edit"));
m_ui->actionDatabaseSettings->setIcon(icons()->icon("database-settings"));
m_ui->actionDatabaseSecurity->setIcon(icons()->icon("database-change-key"));
m_ui->actionPasskeys->setIcon(icons()->icon("passkey"));
m_ui->actionImportPasskey->setIcon(icons()->icon("document-import"));
m_ui->actionLockDatabase->setIcon(icons()->icon("database-lock"));
m_ui->actionLockDatabaseToolbar->setIcon(icons()->icon("database-lock"));
m_ui->actionLockAllDatabases->setIcon(icons()->icon("database-lock-all"));
@ -392,6 +394,12 @@ MainWindow::MainWindow()
m_ui->actionImport->setIcon(icons()->icon("document-import"));
m_ui->menuExport->setIcon(icons()->icon("document-export"));
#ifndef WITH_XC_BROWSER_PASSKEYS
m_ui->actionPasskeys->setVisible(false);
m_ui->actionImportPasskey->setVisible(false);
m_ui->actionEntryImportPasskey->setVisible(false);
#endif
m_ui->actionEntryNew->setIcon(icons()->icon("entry-new"));
m_ui->actionEntryClone->setIcon(icons()->icon("entry-clone"));
m_ui->actionEntryEdit->setIcon(icons()->icon("entry-edit"));
@ -416,6 +424,7 @@ MainWindow::MainWindow()
m_ui->actionEntryCopyPasswordTotp->setIcon(icons()->icon("totp-copy-password"));
m_ui->actionEntryTotpQRCode->setIcon(icons()->icon("qrcode"));
m_ui->actionEntrySetupTotp->setIcon(icons()->icon("totp-edit"));
m_ui->actionEntryImportPasskey->setIcon(icons()->icon("document-import"));
m_ui->actionEntryAddToAgent->setIcon(icons()->icon("utilities-terminal"));
m_ui->actionEntryRemoveFromAgent->setIcon(icons()->icon("utilities-terminal"));
m_ui->menuTags->setIcon(icons()->icon("tag-multiple"));
@ -450,11 +459,10 @@ MainWindow::MainWindow()
m_ui->actionEntryRemovePasskey->setIcon(icons()->icon("document-close"));
#endif
m_actionMultiplexer.connect(
SIGNAL(currentModeChanged(DatabaseWidget::Mode)), this, SLOT(setMenuActionState(DatabaseWidget::Mode)));
m_actionMultiplexer.connect(SIGNAL(groupChanged()), this, SLOT(setMenuActionState()));
m_actionMultiplexer.connect(SIGNAL(entrySelectionChanged()), this, SLOT(setMenuActionState()));
m_actionMultiplexer.connect(SIGNAL(databaseNonDataChanged()), this, SLOT(setMenuActionState()));
m_actionMultiplexer.connect(SIGNAL(currentModeChanged(DatabaseWidget::Mode)), this, SLOT(updateMenuActionState()));
m_actionMultiplexer.connect(SIGNAL(groupChanged()), this, SLOT(updateMenuActionState()));
m_actionMultiplexer.connect(SIGNAL(entrySelectionChanged()), this, SLOT(updateMenuActionState()));
m_actionMultiplexer.connect(SIGNAL(databaseNonDataChanged()), this, SLOT(updateMenuActionState()));
m_actionMultiplexer.connect(SIGNAL(groupContextMenuRequested(QPoint)), this, SLOT(showGroupContextMenu(QPoint)));
m_actionMultiplexer.connect(SIGNAL(entryContextMenuRequested(QPoint)), this, SLOT(showEntryContextMenu(QPoint)));
m_actionMultiplexer.connect(SIGNAL(groupChanged()), this, SLOT(updateEntryCountLabel()));
@ -473,11 +481,11 @@ MainWindow::MainWindow()
connect(m_ui->tabWidget, SIGNAL(tabNameChanged()), SLOT(updateWindowTitle()));
connect(m_ui->tabWidget, SIGNAL(currentChanged(int)), SLOT(updateWindowTitle()));
connect(m_ui->tabWidget, SIGNAL(currentChanged(int)), SLOT(databaseTabChanged(int)));
connect(m_ui->tabWidget, SIGNAL(currentChanged(int)), SLOT(setMenuActionState()));
connect(m_ui->tabWidget, SIGNAL(currentChanged(int)), SLOT(updateMenuActionState()));
connect(m_ui->tabWidget, SIGNAL(databaseLocked(DatabaseWidget*)), SLOT(databaseStatusChanged(DatabaseWidget*)));
connect(m_ui->tabWidget, SIGNAL(databaseUnlocked(DatabaseWidget*)), SLOT(databaseStatusChanged(DatabaseWidget*)));
connect(m_ui->tabWidget, SIGNAL(tabVisibilityChanged(bool)), SLOT(updateToolbarSeparatorVisibility()));
connect(m_ui->stackedWidget, SIGNAL(currentChanged(int)), SLOT(setMenuActionState()));
connect(m_ui->stackedWidget, SIGNAL(currentChanged(int)), SLOT(updateMenuActionState()));
connect(m_ui->stackedWidget, SIGNAL(currentChanged(int)), SLOT(updateWindowTitle()));
connect(m_ui->stackedWidget, SIGNAL(currentChanged(int)), SLOT(updateToolbarSeparatorVisibility()));
connect(m_ui->settingsWidget, SIGNAL(accepted()), SLOT(applySettingsChanges()));
@ -492,9 +500,9 @@ MainWindow::MainWindow()
connect(m_ui->actionDatabaseSaveBackup, SIGNAL(triggered()), m_ui->tabWidget, SLOT(saveDatabaseBackup()));
connect(m_ui->actionDatabaseClose, SIGNAL(triggered()), m_ui->tabWidget, SLOT(closeCurrentDatabaseTab()));
connect(m_ui->actionDatabaseMerge, SIGNAL(triggered()), m_ui->tabWidget, SLOT(mergeDatabase()));
connect(m_ui->actionDatabaseSettings, SIGNAL(toggled(bool)), m_ui->tabWidget, SLOT(showDatabaseSettings(bool)));
connect(m_ui->actionDatabaseSecurity, SIGNAL(triggered()), m_ui->tabWidget, SLOT(showDatabaseSecurity()));
connect(m_ui->actionReports, SIGNAL(triggered()), m_ui->tabWidget, SLOT(showDatabaseReports()));
connect(m_ui->actionDatabaseSettings, SIGNAL(triggered()), m_ui->tabWidget, SLOT(showDatabaseSettings()));
connect(m_ui->actionReports, SIGNAL(toggled(bool)), m_ui->tabWidget, SLOT(showDatabaseReports(bool)));
#ifdef WITH_XC_BROWSER_PASSKEYS
connect(m_ui->actionPasskeys, SIGNAL(triggered()), m_ui->tabWidget, SLOT(showPasskeys()));
connect(m_ui->actionImportPasskey, SIGNAL(triggered()), m_ui->tabWidget, SLOT(importPasskey()));
@ -708,7 +716,7 @@ MainWindow::MainWindow()
statusBar()->addPermanentWidget(m_statusBarLabel);
restoreConfigState();
setMenuActionState();
updateMenuActionState();
}
MainWindow::~MainWindow()
@ -884,247 +892,148 @@ void MainWindow::openDatabase(const QString& filePath, const QString& password,
m_ui->tabWidget->addDatabaseTab(filePath, false, password, keyfile);
}
void MainWindow::setMenuActionState(DatabaseWidget::Mode mode)
void MainWindow::updateMenuActionState()
{
// MainWindow State
int currentIndex = m_ui->stackedWidget->currentIndex();
bool hasLockableDatabase = m_ui->tabWidget->hasLockableDatabases();
bool inAppSettings = (currentIndex == SettingsScreen);
bool inPasswordGenerator = (currentIndex == PasswordGeneratorScreen);
bool inDatabaseTabWidget = (currentIndex == DatabaseTabScreen);
bool inWelcomeWidget = (currentIndex == WelcomeScreen);
bool inDatabaseTabWidgetOrWelcomeWidget = inDatabaseTabWidget || inWelcomeWidget;
auto dbWidget = (currentIndex == DatabaseTabScreen ? m_ui->tabWidget->currentDatabaseWidget() : nullptr);
auto dbMode = (dbWidget ? dbWidget->currentMode() : DatabaseWidget::Mode::None);
m_ui->actionDatabaseClose->setEnabled(true);
m_ui->actionDatabaseMerge->setEnabled(inDatabaseTabWidget);
m_ui->actionDatabaseNew->setEnabled(inDatabaseTabWidgetOrWelcomeWidget);
m_ui->actionDatabaseOpen->setEnabled(inDatabaseTabWidgetOrWelcomeWidget);
m_ui->menuRecentDatabases->setEnabled(inDatabaseTabWidgetOrWelcomeWidget);
m_ui->actionImport->setEnabled(inDatabaseTabWidgetOrWelcomeWidget);
m_ui->actionLockDatabase->setEnabled(m_ui->tabWidget->hasLockableDatabases());
m_ui->actionLockDatabaseToolbar->setEnabled(m_ui->tabWidget->hasLockableDatabases());
m_ui->actionLockAllDatabases->setEnabled(m_ui->tabWidget->hasLockableDatabases());
// Database State
bool databaseUnlocked = (dbWidget && !dbWidget->isLocked());
bool inDatabase = (dbMode == DatabaseWidget::Mode::ViewMode);
bool inDatabaseSettings = (dbMode == DatabaseWidget::Mode::DatabaseSettingsMode);
bool inReports = (dbMode == DatabaseWidget::Mode::ReportsMode);
bool editingEntry = (dbMode == DatabaseWidget::Mode::EditEntryMode);
if (inDatabaseTabWidget && m_ui->tabWidget->currentIndex() != -1) {
DatabaseWidget* dbWidget = m_ui->tabWidget->currentDatabaseWidget();
Q_ASSERT(dbWidget);
// Synchronize toggle buttons
m_ui->actionDatabaseSettings->blockSignals(true);
m_ui->actionPasswordGenerator->blockSignals(true);
m_ui->actionReports->blockSignals(true);
m_ui->actionSettings->blockSignals(true);
if (mode == DatabaseWidget::Mode::None) {
mode = dbWidget->currentMode();
}
m_ui->actionDatabaseSettings->setChecked(inDatabaseSettings);
m_ui->actionPasswordGenerator->setChecked(inPasswordGenerator);
m_ui->actionReports->setChecked(inReports);
m_ui->actionSettings->setChecked(inAppSettings);
switch (mode) {
case DatabaseWidget::Mode::ViewMode: {
bool singleEntrySelected = dbWidget->numberOfSelectedEntries() == 1;
bool entriesSelected = dbWidget->numberOfSelectedEntries() > 0;
bool groupSelected = dbWidget->isGroupSelected();
bool currentGroupHasChildren = dbWidget->currentGroup()->hasChildren();
bool currentGroupHasEntries = !dbWidget->currentGroup()->entries().isEmpty();
bool recycleBinSelected = dbWidget->isRecycleBinSelected();
bool sorted = dbWidget->isSorted();
int entryIndex = dbWidget->currentEntryIndex();
int numEntries = dbWidget->currentGroup()->entries().size();
m_ui->actionDatabaseSettings->blockSignals(false);
m_ui->actionPasswordGenerator->blockSignals(false);
m_ui->actionReports->blockSignals(false);
m_ui->actionSettings->blockSignals(false);
m_ui->actionEntryNew->setEnabled(true);
m_ui->actionEntryClone->setEnabled(singleEntrySelected);
m_ui->actionEntryEdit->setEnabled(singleEntrySelected);
m_ui->actionEntryDelete->setEnabled(entriesSelected);
m_ui->actionEntryRestore->setVisible(entriesSelected && recycleBinSelected);
m_ui->actionEntryRestore->setEnabled(entriesSelected && recycleBinSelected);
m_ui->actionEntryRestore->setText(tr("Restore Entry(s)", "", dbWidget->numberOfSelectedEntries()));
m_ui->actionEntryRestore->setToolTip(tr("Restore Entry(s)", "", dbWidget->numberOfSelectedEntries()));
m_ui->actionEntryMoveUp->setVisible(!sorted);
m_ui->actionEntryMoveDown->setVisible(!sorted);
m_ui->actionEntryMoveUp->setEnabled(singleEntrySelected && !sorted && entryIndex > 0);
m_ui->actionEntryMoveDown->setEnabled(singleEntrySelected && !sorted && entryIndex >= 0
&& entryIndex < numEntries - 1);
m_ui->actionEntryCopyTitle->setEnabled(singleEntrySelected && dbWidget->currentEntryHasTitle());
m_ui->actionEntryCopyUsername->setEnabled(singleEntrySelected && dbWidget->currentEntryHasUsername());
// NOTE: Copy password is enabled even if the selected entry's password is blank to prevent Ctrl+C
// from copying information from the currently selected cell in the entry view table.
m_ui->actionEntryCopyPassword->setEnabled(singleEntrySelected);
m_ui->actionEntryCopyURL->setEnabled(singleEntrySelected && dbWidget->currentEntryHasUrl());
m_ui->actionEntryCopyNotes->setEnabled(singleEntrySelected && dbWidget->currentEntryHasNotes());
m_ui->menuEntryCopyAttribute->setEnabled(singleEntrySelected);
m_ui->menuEntryTotp->setEnabled(singleEntrySelected);
m_ui->menuTags->setEnabled(entriesSelected);
m_ui->actionEntryAutoType->setEnabled(singleEntrySelected && dbWidget->currentEntryHasAutoTypeEnabled());
m_ui->actionEntryAutoType->menu()->setEnabled(singleEntrySelected
&& dbWidget->currentEntryHasAutoTypeEnabled());
m_ui->actionEntryAutoTypeSequence->setText(
singleEntrySelected ? dbWidget->currentSelectedEntry()->effectiveAutoTypeSequence()
: Group::RootAutoTypeSequence);
m_ui->actionEntryAutoTypeSequence->setEnabled(singleEntrySelected);
m_ui->actionEntryAutoTypeUsername->setEnabled(singleEntrySelected && dbWidget->currentEntryHasUsername());
m_ui->actionEntryAutoTypeUsernameEnter->setEnabled(singleEntrySelected
&& dbWidget->currentEntryHasUsername());
m_ui->actionEntryAutoTypePassword->setEnabled(singleEntrySelected && dbWidget->currentEntryHasPassword());
m_ui->actionEntryAutoTypePasswordEnter->setEnabled(singleEntrySelected
&& dbWidget->currentEntryHasPassword());
m_ui->actionEntryAutoTypeTOTP->setEnabled(singleEntrySelected && dbWidget->currentEntryHasTotp());
m_ui->actionEntryAutoTypeTOTP->setVisible(singleEntrySelected && dbWidget->currentEntryHasTotp());
m_ui->actionEntryOpenUrl->setEnabled(singleEntrySelected && dbWidget->currentEntryHasUrl());
m_ui->actionEntryTotp->setEnabled(singleEntrySelected && dbWidget->currentEntryHasTotp());
m_ui->actionEntryCopyTotp->setEnabled(singleEntrySelected && dbWidget->currentEntryHasTotp());
m_ui->actionEntryCopyPasswordTotp->setEnabled(singleEntrySelected && dbWidget->currentEntryHasTotp());
m_ui->actionEntrySetupTotp->setEnabled(singleEntrySelected);
m_ui->actionEntryTotpQRCode->setEnabled(singleEntrySelected && dbWidget->currentEntryHasTotp());
m_ui->actionEntryDownloadIcon->setEnabled((entriesSelected && !singleEntrySelected)
|| (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);
m_ui->actionGroupEmptyRecycleBin->setVisible(recycleBinSelected);
m_ui->actionGroupEmptyRecycleBin->setEnabled(recycleBinSelected);
#ifdef WITH_XC_NETWORKING
m_ui->actionGroupDownloadFavicons->setVisible(!recycleBinSelected);
#endif
m_ui->actionGroupDownloadFavicons->setEnabled(groupSelected && currentGroupHasEntries
&& !recycleBinSelected);
m_ui->actionDatabaseSecurity->setEnabled(true);
m_ui->actionReports->setEnabled(true);
m_ui->actionDatabaseSettings->setEnabled(true);
m_ui->actionDatabaseSave->setEnabled(m_ui->tabWidget->canSave());
m_ui->actionDatabaseSaveAs->setEnabled(true);
m_ui->actionDatabaseSaveBackup->setEnabled(true);
m_ui->menuExport->setEnabled(true);
m_ui->actionExportCsv->setEnabled(true);
m_ui->actionExportHtml->setEnabled(true);
m_ui->actionExportXML->setEnabled(true);
m_ui->actionDatabaseMerge->setEnabled(m_ui->tabWidget->currentIndex() != -1);
// Entry State
bool singleEntrySelected = (inDatabase && dbWidget->numberOfSelectedEntries() == 1);
bool singleEntryOrEditing = (singleEntrySelected || editingEntry);
bool multiEntrySelected = (inDatabase && dbWidget->numberOfSelectedEntries() > 0);
// Group State
bool groupSelected = (inDatabase && dbWidget->isGroupSelected());
bool groupHasChildren = (groupSelected && dbWidget->currentGroup()->hasChildren());
bool groupHasEntries = (groupSelected && !dbWidget->currentGroup()->entries().isEmpty());
bool inRecycleBin = (inDatabase && dbWidget->isRecycleBinSelected());
bool entryViewSorted = (inDatabase && dbWidget->isSorted());
bool entryViewAtTop = (inDatabase && dbWidget->currentEntryIndex() == 0);
bool entryViewAtBottom =
(groupSelected && dbWidget->currentEntryIndex() == dbWidget->currentGroup()->entries().size() - 1);
m_ui->actionEntryNew->setEnabled(inDatabase && !inRecycleBin);
m_ui->actionEntryClone->setEnabled(singleEntrySelected && !inRecycleBin);
m_ui->actionEntryEdit->setEnabled(singleEntrySelected);
m_ui->actionEntryDelete->setEnabled(multiEntrySelected);
m_ui->actionEntryRestore->setVisible(multiEntrySelected && inRecycleBin);
m_ui->actionEntryRestore->setEnabled(multiEntrySelected && inRecycleBin);
if (dbWidget) {
m_ui->actionEntryRestore->setText(tr("Restore Entry(s)", "", dbWidget->numberOfSelectedEntries()));
m_ui->actionEntryRestore->setToolTip(tr("Restore Entry(s)", "", dbWidget->numberOfSelectedEntries()));
}
m_ui->actionEntryMoveUp->setVisible(inDatabase && !entryViewSorted);
m_ui->actionEntryMoveDown->setVisible(inDatabase && !entryViewSorted);
m_ui->actionEntryMoveUp->setEnabled(singleEntrySelected && !entryViewSorted && !entryViewAtTop);
m_ui->actionEntryMoveDown->setEnabled(singleEntrySelected && !entryViewSorted && !entryViewAtBottom);
m_ui->actionEntryCopyTitle->setEnabled(singleEntryOrEditing && dbWidget->currentEntryHasTitle());
m_ui->actionEntryCopyUsername->setEnabled(singleEntryOrEditing && dbWidget->currentEntryHasUsername());
// NOTE: Copy password is enabled even if the selected entry's password is blank to prevent Ctrl+C
// from copying information from the currently selected cell in the entry view table.
m_ui->actionEntryCopyPassword->setEnabled(singleEntryOrEditing);
m_ui->actionEntryCopyURL->setEnabled(singleEntryOrEditing && dbWidget->currentEntryHasUrl());
m_ui->actionEntryCopyNotes->setEnabled(singleEntryOrEditing && dbWidget->currentEntryHasNotes());
m_ui->menuEntryCopyAttribute->setEnabled(singleEntryOrEditing);
m_ui->menuEntryTotp->setEnabled(singleEntrySelected);
m_ui->menuTags->setEnabled(multiEntrySelected);
m_ui->actionEntryAutoType->setEnabled(singleEntrySelected && dbWidget->currentEntryHasAutoTypeEnabled());
m_ui->actionEntryAutoType->menu()->setEnabled(singleEntrySelected && dbWidget->currentEntryHasAutoTypeEnabled());
m_ui->actionEntryAutoTypeSequence->setText(singleEntrySelected
? dbWidget->currentSelectedEntry()->effectiveAutoTypeSequence()
: Group::RootAutoTypeSequence);
m_ui->actionEntryAutoTypeSequence->setEnabled(singleEntrySelected);
m_ui->actionEntryAutoTypeUsername->setEnabled(singleEntrySelected && dbWidget->currentEntryHasUsername());
m_ui->actionEntryAutoTypeUsernameEnter->setEnabled(singleEntrySelected && dbWidget->currentEntryHasUsername());
m_ui->actionEntryAutoTypePassword->setEnabled(singleEntrySelected && dbWidget->currentEntryHasPassword());
m_ui->actionEntryAutoTypePasswordEnter->setEnabled(singleEntrySelected && dbWidget->currentEntryHasPassword());
m_ui->actionEntryAutoTypeTOTP->setEnabled(singleEntrySelected && dbWidget->currentEntryHasTotp());
m_ui->actionEntryAutoTypeTOTP->setVisible(singleEntrySelected && dbWidget->currentEntryHasTotp());
m_ui->actionEntryOpenUrl->setEnabled(singleEntryOrEditing && dbWidget->currentEntryHasUrl());
m_ui->actionEntryTotp->setEnabled(singleEntrySelected && dbWidget->currentEntryHasTotp());
m_ui->actionEntryCopyTotp->setEnabled(singleEntrySelected && dbWidget->currentEntryHasTotp());
m_ui->actionEntryCopyPasswordTotp->setEnabled(singleEntrySelected && dbWidget->currentEntryHasTotp());
m_ui->actionEntrySetupTotp->setEnabled(singleEntrySelected);
m_ui->actionEntryTotpQRCode->setEnabled(singleEntrySelected && dbWidget->currentEntryHasTotp());
m_ui->actionEntryDownloadIcon->setEnabled((multiEntrySelected && !singleEntrySelected)
|| (singleEntrySelected && dbWidget->currentEntryHasUrl()));
#ifdef WITH_XC_BROWSER_PASSKEYS
bool singleEntryHasPasskey = singleEntrySelected && dbWidget->currentEntryHasPasskey();
m_ui->actionPasskeys->setEnabled(true);
m_ui->actionImportPasskey->setEnabled(true);
m_ui->actionEntryImportPasskey->setEnabled(singleEntrySelected);
m_ui->actionEntryRemovePasskey->setEnabled(singleEntryHasPasskey);
m_ui->actionEntryImportPasskey->setVisible(singleEntrySelected);
m_ui->actionEntryImportPasskey->setEnabled(singleEntrySelected);
m_ui->actionEntryRemovePasskey->setVisible(singleEntrySelected && dbWidget->currentEntryHasPasskey());
m_ui->actionEntryRemovePasskey->setEnabled(singleEntrySelected && dbWidget->currentEntryHasPasskey());
#endif
#ifdef WITH_XC_SSHAGENT
bool singleEntryHasSshKey =
singleEntrySelected && sshAgent()->isEnabled() && dbWidget->currentEntryHasSshKey();
m_ui->actionEntryAddToAgent->setVisible(singleEntryHasSshKey);
m_ui->actionEntryAddToAgent->setEnabled(singleEntryHasSshKey);
m_ui->actionEntryRemoveFromAgent->setVisible(singleEntryHasSshKey);
m_ui->actionEntryRemoveFromAgent->setEnabled(singleEntryHasSshKey);
bool hasSSHKey = singleEntrySelected && sshAgent()->isEnabled() && dbWidget->currentEntryHasSshKey();
m_ui->actionEntryAddToAgent->setVisible(hasSSHKey);
m_ui->actionEntryAddToAgent->setEnabled(hasSSHKey);
m_ui->actionEntryRemoveFromAgent->setVisible(hasSSHKey);
m_ui->actionEntryRemoveFromAgent->setEnabled(hasSSHKey);
#endif
m_searchWidgetAction->setEnabled(true);
break;
}
case DatabaseWidget::Mode::EditMode:
case DatabaseWidget::Mode::LockedMode: {
// Enable select actions when editing an entry
bool editEntryActive = dbWidget->isEntryEditActive();
const auto editEntryActionsMask = QList<QAction*>({m_ui->actionEntryCopyUsername,
m_ui->actionEntryCopyPassword,
m_ui->actionEntryCopyURL,
m_ui->actionEntryOpenUrl,
m_ui->actionEntryAutoType,
m_ui->actionEntryDownloadIcon,
m_ui->actionEntryCopyNotes,
m_ui->actionEntryCopyTitle,
m_ui->menuEntryCopyAttribute->menuAction(),
m_ui->menuEntryTotp->menuAction(),
m_ui->actionEntrySetupTotp});
auto entryActions = m_ui->menuEntries->actions();
entryActions << m_ui->menuEntryCopyAttribute->actions();
entryActions << m_ui->menuEntryTotp->actions();
for (auto action : entryActions) {
bool enabled = editEntryActive && editEntryActionsMask.contains(action);
if (action->menu()) {
action->menu()->setEnabled(enabled);
}
action->setEnabled(enabled);
}
const auto groupActions = m_ui->menuGroups->actions();
for (auto action : groupActions) {
action->setEnabled(false);
}
m_ui->actionDatabaseSecurity->setEnabled(false);
m_ui->actionReports->setEnabled(false);
m_ui->actionDatabaseSettings->setEnabled(false);
m_ui->actionDatabaseSave->setEnabled(false);
m_ui->actionDatabaseSaveAs->setEnabled(false);
m_ui->actionDatabaseSaveBackup->setEnabled(false);
m_ui->menuExport->setEnabled(false);
m_ui->actionExportCsv->setEnabled(false);
m_ui->actionExportHtml->setEnabled(false);
m_ui->actionDatabaseMerge->setEnabled(false);
// Only disable the action in the database menu so that the
// menu remains active in the toolbar, if necessary
m_ui->actionLockDatabase->setEnabled(false);
// Never show in these modes
m_ui->actionEntryMoveUp->setVisible(false);
m_ui->actionEntryMoveDown->setVisible(false);
m_ui->actionEntryRestore->setVisible(false);
m_ui->actionEntryAddToAgent->setVisible(false);
m_ui->actionEntryRemoveFromAgent->setVisible(false);
m_ui->actionGroupEmptyRecycleBin->setVisible(false);
m_ui->actionGroupNew->setEnabled(groupSelected && !inRecycleBin);
m_ui->actionGroupEdit->setEnabled(groupSelected);
m_ui->actionGroupClone->setEnabled(groupSelected && dbWidget->canCloneCurrentGroup());
m_ui->actionGroupDelete->setEnabled(groupSelected && dbWidget->canDeleteCurrentGroup());
m_ui->actionGroupSortAsc->setVisible(groupHasChildren);
m_ui->actionGroupSortAsc->setEnabled(groupHasChildren);
m_ui->actionGroupSortDesc->setVisible(groupHasChildren);
m_ui->actionGroupSortDesc->setEnabled(groupHasChildren);
m_ui->actionGroupEmptyRecycleBin->setVisible(inRecycleBin);
m_ui->actionGroupEmptyRecycleBin->setEnabled(inRecycleBin);
#ifdef WITH_XC_NETWORKING
m_ui->actionGroupDownloadFavicons->setVisible(!inRecycleBin);
#endif
m_ui->actionGroupDownloadFavicons->setEnabled(groupSelected && groupHasEntries && !inRecycleBin);
// Database Menu
m_ui->actionDatabaseSave->setEnabled(m_ui->tabWidget->canSave());
m_ui->actionDatabaseSaveAs->setEnabled(databaseUnlocked);
m_ui->actionDatabaseSaveBackup->setEnabled(databaseUnlocked);
m_ui->actionDatabaseClose->setEnabled(dbWidget);
m_ui->actionLockDatabase->setEnabled(databaseUnlocked);
m_ui->actionLockAllDatabases->setEnabled(hasLockableDatabase);
m_ui->actionLockDatabaseToolbar->setEnabled(hasLockableDatabase);
m_ui->actionDatabaseSettings->setEnabled(inDatabase || inDatabaseSettings);
m_ui->actionDatabaseSecurity->setEnabled(inDatabase || inDatabaseSettings);
m_ui->actionReports->setEnabled(inDatabase || inReports);
m_ui->menuExport->setEnabled(inDatabase);
m_ui->actionDatabaseMerge->setEnabled(inDatabase);
#ifdef WITH_XC_BROWSER_PASSKEYS
m_ui->actionPasskeys->setEnabled(false);
m_ui->actionImportPasskey->setEnabled(false);
m_ui->actionEntryImportPasskey->setEnabled(false);
m_ui->actionEntryRemovePasskey->setEnabled(false);
#else
m_ui->actionPasskeys->setVisible(false);
m_ui->actionImportPasskey->setVisible(false);
m_ui->actionEntryImportPasskey->setVisible(false);
m_ui->actionEntryRemovePasskey->setVisible(false);
m_ui->actionPasskeys->setEnabled(inDatabase || inReports);
m_ui->actionImportPasskey->setEnabled(inDatabase);
#endif
m_searchWidgetAction->setEnabled(false);
break;
}
default:
Q_ASSERT(false);
}
} else {
const auto entryActions = m_ui->menuEntries->actions();
for (auto action : entryActions) {
action->setEnabled(false);
}
const auto groupActions = m_ui->menuGroups->actions();
for (auto action : groupActions) {
action->setEnabled(false);
}
m_ui->actionDatabaseSecurity->setEnabled(false);
m_ui->actionReports->setEnabled(false);
m_ui->actionDatabaseSettings->setEnabled(false);
m_ui->actionDatabaseSave->setEnabled(false);
m_ui->actionDatabaseSaveAs->setEnabled(false);
m_ui->actionDatabaseSaveBackup->setEnabled(false);
m_ui->actionDatabaseClose->setEnabled(false);
m_ui->menuExport->setEnabled(false);
m_ui->actionExportCsv->setEnabled(false);
m_ui->actionExportHtml->setEnabled(false);
m_ui->actionDatabaseMerge->setEnabled(false);
// Hide entry-specific actions
m_ui->actionEntryMoveUp->setVisible(false);
m_ui->actionEntryMoveDown->setVisible(false);
m_ui->actionEntryRestore->setVisible(false);
m_ui->actionEntryAddToAgent->setVisible(false);
m_ui->actionEntryRemoveFromAgent->setVisible(false);
m_ui->actionGroupEmptyRecycleBin->setVisible(false);
m_searchWidgetAction->setEnabled(false);
}
if ((currentIndex == PasswordGeneratorScreen) != m_ui->actionPasswordGenerator->isChecked()) {
bool blocked = m_ui->actionPasswordGenerator->blockSignals(true);
m_ui->actionPasswordGenerator->toggle();
m_ui->actionPasswordGenerator->blockSignals(blocked);
} else if ((currentIndex == SettingsScreen) != m_ui->actionSettings->isChecked()) {
bool blocked = m_ui->actionSettings->blockSignals(true);
m_ui->actionSettings->toggle();
m_ui->actionSettings->blockSignals(blocked);
}
m_searchWidgetAction->setEnabled(inDatabase);
}
void MainWindow::updateToolbarSeparatorVisibility()