diff --git a/src/gui/DatabaseWidget.cpp b/src/gui/DatabaseWidget.cpp index ef76bd82d4..5e3c101c13 100644 --- a/src/gui/DatabaseWidget.cpp +++ b/src/gui/DatabaseWidget.cpp @@ -264,6 +264,11 @@ bool DatabaseWidget::isSearchActive() const return m_entryView->inSearchMode(); } +bool DatabaseWidget::isEntryEditActive() const +{ + return currentWidget() == m_editEntryWidget; +} + bool DatabaseWidget::isEditWidgetModified() const { if (currentWidget() == m_editEntryWidget) { @@ -397,7 +402,7 @@ void DatabaseWidget::replaceDatabase(QSharedPointer db) void DatabaseWidget::cloneEntry() { - Entry* currentEntry = m_entryView->currentEntry(); + auto currentEntry = currentSelectedEntry(); Q_ASSERT(currentEntry); if (!currentEntry) { return; @@ -409,7 +414,7 @@ void DatabaseWidget::cloneEntry() void DatabaseWidget::showTotp() { - Entry* currentEntry = m_entryView->currentEntry(); + auto currentEntry = currentSelectedEntry(); Q_ASSERT(currentEntry); if (!currentEntry) { return; @@ -421,7 +426,7 @@ void DatabaseWidget::showTotp() void DatabaseWidget::copyTotp() { - Entry* currentEntry = m_entryView->currentEntry(); + auto currentEntry = currentSelectedEntry(); Q_ASSERT(currentEntry); if (!currentEntry) { return; @@ -431,7 +436,7 @@ void DatabaseWidget::copyTotp() void DatabaseWidget::setupTotp() { - Entry* currentEntry = m_entryView->currentEntry(); + auto currentEntry = currentSelectedEntry(); Q_ASSERT(currentEntry); if (!currentEntry) { return; @@ -568,7 +573,7 @@ void DatabaseWidget::setFocus() void DatabaseWidget::copyTitle() { - Entry* currentEntry = m_entryView->currentEntry(); + auto currentEntry = currentSelectedEntry(); if (currentEntry) { setClipboardTextAndMinimize(currentEntry->resolveMultiplePlaceholders(currentEntry->title())); } @@ -576,7 +581,7 @@ void DatabaseWidget::copyTitle() void DatabaseWidget::copyUsername() { - Entry* currentEntry = m_entryView->currentEntry(); + auto currentEntry = currentSelectedEntry(); if (currentEntry) { setClipboardTextAndMinimize(currentEntry->resolveMultiplePlaceholders(currentEntry->username())); } @@ -584,7 +589,7 @@ void DatabaseWidget::copyUsername() void DatabaseWidget::copyPassword() { - Entry* currentEntry = m_entryView->currentEntry(); + auto currentEntry = currentSelectedEntry(); if (currentEntry) { setClipboardTextAndMinimize(currentEntry->resolveMultiplePlaceholders(currentEntry->password())); } @@ -592,7 +597,7 @@ void DatabaseWidget::copyPassword() void DatabaseWidget::copyURL() { - Entry* currentEntry = m_entryView->currentEntry(); + auto currentEntry = currentSelectedEntry(); if (currentEntry) { setClipboardTextAndMinimize(currentEntry->resolveMultiplePlaceholders(currentEntry->url())); } @@ -600,7 +605,7 @@ void DatabaseWidget::copyURL() void DatabaseWidget::copyNotes() { - Entry* currentEntry = m_entryView->currentEntry(); + auto currentEntry = currentSelectedEntry(); if (currentEntry) { setClipboardTextAndMinimize(currentEntry->resolveMultiplePlaceholders(currentEntry->notes())); } @@ -608,7 +613,7 @@ void DatabaseWidget::copyNotes() void DatabaseWidget::copyAttribute(QAction* action) { - Entry* currentEntry = m_entryView->currentEntry(); + auto currentEntry = currentSelectedEntry(); if (currentEntry) { setClipboardTextAndMinimize( currentEntry->resolveMultiplePlaceholders(currentEntry->attributes()->value(action->data().toString()))); @@ -617,7 +622,7 @@ void DatabaseWidget::copyAttribute(QAction* action) void DatabaseWidget::showTotpKeyQrCode() { - Entry* currentEntry = m_entryView->currentEntry(); + auto currentEntry = currentSelectedEntry(); if (currentEntry) { auto totpDisplayDialog = new TotpExportSettingsDialog(this, currentEntry); totpDisplayDialog->open(); @@ -638,7 +643,7 @@ void DatabaseWidget::setClipboardTextAndMinimize(const QString& text) void DatabaseWidget::performAutoType() { - Entry* currentEntry = m_entryView->currentEntry(); + auto currentEntry = currentSelectedEntry(); if (currentEntry) { autoType()->performAutoType(currentEntry, window()); } @@ -646,7 +651,7 @@ void DatabaseWidget::performAutoType() void DatabaseWidget::openUrl() { - Entry* currentEntry = m_entryView->currentEntry(); + auto currentEntry = currentSelectedEntry(); if (currentEntry) { openUrlForEntry(currentEntry); } @@ -749,6 +754,15 @@ void DatabaseWidget::openUrlForEntry(Entry* entry) } } +Entry* DatabaseWidget::currentSelectedEntry() +{ + if (currentWidget() == m_editEntryWidget) { + return m_editEntryWidget->currentEntry(); + } + + return m_entryView->currentEntry(); +} + void DatabaseWidget::createGroup() { Q_ASSERT(m_groupView->currentGroup()); @@ -845,7 +859,8 @@ void DatabaseWidget::switchToMainView(bool previousDialogAccepted) void DatabaseWidget::switchToHistoryView(Entry* entry) { - m_historyEditEntryWidget->loadEntry(entry, false, true, m_editEntryWidget->entryTitle(), m_db); + auto entryTitle = m_editEntryWidget->currentEntry() ? m_editEntryWidget->currentEntry()->title() : ""; + m_historyEditEntryWidget->loadEntry(entry, false, true, entryTitle, m_db); setCurrentWidget(m_historyEditEntryWidget); } @@ -869,10 +884,13 @@ void DatabaseWidget::switchToEntryEdit(Entry* entry, bool create) group = currentGroup(); } else { group = entry->group(); + // Ensure we have only this entry selected + m_entryView->setCurrentEntry(entry); } Q_ASSERT(group); + // Setup the entry edit widget and display m_editEntryWidget->loadEntry(entry, create, false, group->name(), m_db); setCurrentWidget(m_editEntryWidget); } @@ -1099,8 +1117,7 @@ void DatabaseWidget::switchToImportOpVault(const QString& fileName) void DatabaseWidget::switchToEntryEdit() { - Entry* entry = m_entryView->currentEntry(); - + auto entry = m_entryView->currentEntry(); if (!entry) { return; } @@ -1110,8 +1127,7 @@ void DatabaseWidget::switchToEntryEdit() void DatabaseWidget::switchToGroupEdit() { - Group* group = m_groupView->currentGroup(); - + auto group = m_groupView->currentGroup(); if (!group) { return; } @@ -1362,8 +1378,9 @@ bool DatabaseWidget::lock() m_groupBeforeLock = m_db->rootGroup()->uuid(); } - if (m_entryView->currentEntry()) { - m_entryBeforeLock = m_entryView->currentEntry()->uuid(); + auto currentEntry = currentSelectedEntry(); + if (currentEntry) { + m_entryBeforeLock = currentEntry->uuid(); } endSearch(); @@ -1482,7 +1499,7 @@ bool DatabaseWidget::currentEntryHasFocus() bool DatabaseWidget::currentEntryHasTitle() { - Entry* currentEntry = m_entryView->currentEntry(); + auto currentEntry = currentSelectedEntry(); Q_ASSERT(currentEntry); if (!currentEntry) { return false; @@ -1492,7 +1509,7 @@ bool DatabaseWidget::currentEntryHasTitle() bool DatabaseWidget::currentEntryHasUsername() { - Entry* currentEntry = m_entryView->currentEntry(); + auto currentEntry = currentSelectedEntry(); Q_ASSERT(currentEntry); if (!currentEntry) { return false; @@ -1502,7 +1519,7 @@ bool DatabaseWidget::currentEntryHasUsername() bool DatabaseWidget::currentEntryHasPassword() { - Entry* currentEntry = m_entryView->currentEntry(); + auto currentEntry = currentSelectedEntry(); Q_ASSERT(currentEntry); if (!currentEntry) { return false; @@ -1512,7 +1529,7 @@ bool DatabaseWidget::currentEntryHasPassword() bool DatabaseWidget::currentEntryHasUrl() { - Entry* currentEntry = m_entryView->currentEntry(); + auto currentEntry = currentSelectedEntry(); Q_ASSERT(currentEntry); if (!currentEntry) { return false; @@ -1522,7 +1539,7 @@ bool DatabaseWidget::currentEntryHasUrl() bool DatabaseWidget::currentEntryHasTotp() { - Entry* currentEntry = m_entryView->currentEntry(); + auto currentEntry = currentSelectedEntry(); Q_ASSERT(currentEntry); if (!currentEntry) { return false; @@ -1532,7 +1549,7 @@ bool DatabaseWidget::currentEntryHasTotp() bool DatabaseWidget::currentEntryHasNotes() { - Entry* currentEntry = m_entryView->currentEntry(); + auto currentEntry = currentSelectedEntry(); Q_ASSERT(currentEntry); if (!currentEntry) { return false; diff --git a/src/gui/DatabaseWidget.h b/src/gui/DatabaseWidget.h index 5a163a3124..6f40c65c58 100644 --- a/src/gui/DatabaseWidget.h +++ b/src/gui/DatabaseWidget.h @@ -80,6 +80,7 @@ class DatabaseWidget : public QStackedWidget DatabaseWidget::Mode currentMode() const; bool isLocked() const; bool isSearchActive() const; + bool isEntryEditActive() const; QString getCurrentSearch(); void refreshSearch(); @@ -234,6 +235,7 @@ private slots: void processAutoOpen(); bool confirmDeleteEntries(QList entries, bool permanent); void performIconDownloads(const QList& entries, bool force = false); + Entry* currentSelectedEntry(); QSharedPointer m_db; diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp index 534a3e766b..01b8cf0280 100644 --- a/src/gui/MainWindow.cpp +++ b/src/gui/MainWindow.cpp @@ -168,6 +168,21 @@ MainWindow::MainWindow() m_countDefaultAttributes = m_ui->menuEntryCopyAttribute->actions().size(); + m_entryContextMenu = new QMenu(this); + m_entryContextMenu->addAction(m_ui->actionEntryCopyUsername); + m_entryContextMenu->addAction(m_ui->actionEntryCopyPassword); + m_entryContextMenu->addAction(m_ui->menuEntryCopyAttribute->menuAction()); + m_entryContextMenu->addAction(m_ui->menuEntryTotp->menuAction()); + m_entryContextMenu->addSeparator(); + m_entryContextMenu->addAction(m_ui->actionEntryAutoType); + m_entryContextMenu->addSeparator(); + m_entryContextMenu->addAction(m_ui->actionEntryEdit); + m_entryContextMenu->addAction(m_ui->actionEntryClone); + m_entryContextMenu->addAction(m_ui->actionEntryDelete); + m_entryContextMenu->addSeparator(); + m_entryContextMenu->addAction(m_ui->actionEntryOpenUrl); + m_entryContextMenu->addAction(m_ui->actionEntryDownloadIcon); + restoreGeometry(config()->get("GUI/MainWindowGeometry").toByteArray()); restoreState(config()->get("GUI/MainWindowState").toByteArray()); #ifdef WITH_XC_BROWSER @@ -639,13 +654,33 @@ void MainWindow::setMenuActionState(DatabaseWidget::Mode mode) case DatabaseWidget::Mode::EditMode: case DatabaseWidget::Mode::ImportMode: case DatabaseWidget::Mode::LockedMode: { - const QList entryActions = m_ui->menuEntries->actions(); - for (QAction* action : entryActions) { - action->setEnabled(false); + // Enable select actions when editing an entry + bool editEntryActive = dbWidget->isEntryEditActive(); + const auto editEntryActionsMask = QList({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 QList groupActions = m_ui->menuGroups->actions(); - for (QAction* action : groupActions) { + const auto groupActions = m_ui->menuGroups->actions(); + for (auto action : groupActions) { action->setEnabled(false); } @@ -666,13 +701,13 @@ void MainWindow::setMenuActionState(DatabaseWidget::Mode mode) } m_ui->actionDatabaseClose->setEnabled(true); } else { - const QList entryActions = m_ui->menuEntries->actions(); - for (QAction* action : entryActions) { + const auto entryActions = m_ui->menuEntries->actions(); + for (auto action : entryActions) { action->setEnabled(false); } - const QList groupActions = m_ui->menuGroups->actions(); - for (QAction* action : groupActions) { + const auto groupActions = m_ui->menuGroups->actions(); + for (auto action : groupActions) { action->setEnabled(false); } @@ -1090,7 +1125,7 @@ void MainWindow::releaseContextFocusLock() void MainWindow::showEntryContextMenu(const QPoint& globalPos) { - m_ui->menuEntries->popup(globalPos); + m_entryContextMenu->popup(globalPos); } void MainWindow::showGroupContextMenu(const QPoint& globalPos) diff --git a/src/gui/MainWindow.h b/src/gui/MainWindow.h index 1763a4ee08..71acb1081f 100644 --- a/src/gui/MainWindow.h +++ b/src/gui/MainWindow.h @@ -146,6 +146,7 @@ private slots: SignalMultiplexer m_actionMultiplexer; QAction* m_clearHistoryAction; QAction* m_searchWidgetAction; + QMenu* m_entryContextMenu; QActionGroup* m_lastDatabasesActions; QActionGroup* m_copyAdditionalAttributeActions; InactivityTimer* m_inactivityTimer; diff --git a/src/gui/MainWindow.ui b/src/gui/MainWindow.ui index c53ab38c41..bb98363d47 100644 --- a/src/gui/MainWindow.ui +++ b/src/gui/MainWindow.ui @@ -195,7 +195,7 @@ 0 0 800 - 20 + 21 @@ -298,11 +298,11 @@ - - + + diff --git a/src/gui/entry/EditEntryWidget.cpp b/src/gui/entry/EditEntryWidget.cpp index 8567255173..3fa75e3b8e 100644 --- a/src/gui/entry/EditEntryWidget.cpp +++ b/src/gui/entry/EditEntryWidget.cpp @@ -809,13 +809,9 @@ void EditEntryWidget::toggleHideNotes(bool visible) m_mainUi->notesHint->setVisible(!visible); } -QString EditEntryWidget::entryTitle() const +Entry* EditEntryWidget::currentEntry() const { - if (m_entry) { - return m_entry->title(); - } else { - return QString(); - } + return m_entry; } void EditEntryWidget::loadEntry(Entry* entry, diff --git a/src/gui/entry/EditEntryWidget.h b/src/gui/entry/EditEntryWidget.h index 8c6fee0bc0..39b5fc5d96 100644 --- a/src/gui/entry/EditEntryWidget.h +++ b/src/gui/entry/EditEntryWidget.h @@ -72,7 +72,7 @@ class EditEntryWidget : public EditWidget void loadEntry(Entry* entry, bool create, bool history, const QString& parentName, QSharedPointer database); - QString entryTitle() const; + Entry* currentEntry() const; void clear(); signals: