mirror of
https://github.com/keepassxreboot/keepassxc.git
synced 2025-12-27 22:24:50 -05:00
parent
413eec9b8c
commit
3c26709da9
20 changed files with 431 additions and 433 deletions
|
|
@ -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()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue