diff --git a/docs/images/autotype_entrylevel.png b/docs/images/autotype_entrylevel.png index 5a92df4e..0c947991 100644 Binary files a/docs/images/autotype_entrylevel.png and b/docs/images/autotype_entrylevel.png differ diff --git a/src/gui/DatabaseWidget.cpp b/src/gui/DatabaseWidget.cpp index 9d861fb3..737a4a2f 100644 --- a/src/gui/DatabaseWidget.cpp +++ b/src/gui/DatabaseWidget.cpp @@ -759,44 +759,44 @@ void DatabaseWidget::removeFromAgent() } #endif -void DatabaseWidget::performAutoType() +void DatabaseWidget::performAutoType(const QString& sequence) { auto currentEntry = currentSelectedEntry(); if (currentEntry) { - autoType()->performAutoType(currentEntry, window()); + // TODO: Include name of previously active window in confirmation question + if (config()->get(Config::Security_AutoTypeAsk).toBool() + && MessageBox::question( + this, tr("Confirm Auto-Type"), tr("Perform Auto-Type into the previously active window?")) + != MessageBox::Yes) { + return; + } + + if (sequence.isEmpty()) { + autoType()->performAutoType(currentEntry, window()); + } else { + autoType()->performAutoTypeWithSequence(currentEntry, sequence, window()); + } } } void DatabaseWidget::performAutoTypeUsername() { - auto currentEntry = currentSelectedEntry(); - if (currentEntry) { - autoType()->performAutoTypeWithSequence(currentEntry, QStringLiteral("{USERNAME}"), window()); - } + performAutoType(QStringLiteral("{USERNAME}")); } void DatabaseWidget::performAutoTypeUsernameEnter() { - auto currentEntry = currentSelectedEntry(); - if (currentEntry) { - autoType()->performAutoTypeWithSequence(currentEntry, QStringLiteral("{USERNAME}{ENTER}"), window()); - } + performAutoType(QStringLiteral("{USERNAME}{ENTER}")); } void DatabaseWidget::performAutoTypePassword() { - auto currentEntry = currentSelectedEntry(); - if (currentEntry) { - autoType()->performAutoTypeWithSequence(currentEntry, QStringLiteral("{PASSWORD}"), window()); - } + performAutoType(QStringLiteral("{PASSWORD}")); } void DatabaseWidget::performAutoTypePasswordEnter() { - auto currentEntry = currentSelectedEntry(); - if (currentEntry) { - autoType()->performAutoTypeWithSequence(currentEntry, QStringLiteral("{PASSWORD}{ENTER}"), window()); - } + performAutoType(QStringLiteral("{PASSWORD}{ENTER}")); } void DatabaseWidget::openUrl() diff --git a/src/gui/DatabaseWidget.h b/src/gui/DatabaseWidget.h index fc8d9ee7..e56e6595 100644 --- a/src/gui/DatabaseWidget.h +++ b/src/gui/DatabaseWidget.h @@ -105,6 +105,7 @@ public: QStringList customEntryAttributes() const; bool isEditWidgetModified() const; void clearAllWidgets(); + Entry* currentSelectedEntry(); bool currentEntryHasTitle(); bool currentEntryHasUsername(); bool currentEntryHasPassword(); @@ -181,7 +182,7 @@ public slots: void addToAgent(); void removeFromAgent(); #endif - void performAutoType(); + void performAutoType(const QString& sequence = {}); void performAutoTypeUsername(); void performAutoTypeUsernameEnter(); void performAutoTypePassword(); @@ -257,7 +258,6 @@ private: bool confirmDeleteEntries(QList entries, bool permanent); void performIconDownloads(const QList& entries, bool force = false); bool performSave(QString& errorMessage, const QString& fileName = {}); - Entry* currentSelectedEntry(); QSharedPointer m_db; diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp index ceb1739b..de19f37a 100644 --- a/src/gui/MainWindow.cpp +++ b/src/gui/MainWindow.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include "config-keepassx.h" @@ -128,7 +129,6 @@ MainWindow::MainWindow() m_entryContextMenu->addAction(m_ui->menuEntryTotp->menuAction()); m_entryContextMenu->addSeparator(); m_entryContextMenu->addAction(m_ui->actionEntryAutoType); - m_entryContextMenu->addAction(m_ui->menuEntryAutoTypeWithSequence->menuAction()); m_entryContextMenu->addSeparator(); m_entryContextMenu->addAction(m_ui->actionEntryEdit); m_entryContextMenu->addAction(m_ui->actionEntryClone); @@ -144,6 +144,20 @@ MainWindow::MainWindow() m_entryNewContextMenu = new QMenu(this); m_entryNewContextMenu->addAction(m_ui->actionEntryNew); + // Build Entry Level Auto-Type menu + auto autotypeMenu = new QMenu({}, this); + autotypeMenu->addAction(m_ui->actionEntryAutoTypeSequence); + autotypeMenu->addSeparator(); + autotypeMenu->addAction(m_ui->actionEntryAutoTypeUsername); + autotypeMenu->addAction(m_ui->actionEntryAutoTypeUsernameEnter); + autotypeMenu->addAction(m_ui->actionEntryAutoTypePassword); + autotypeMenu->addAction(m_ui->actionEntryAutoTypePasswordEnter); + m_ui->actionEntryAutoType->setMenu(autotypeMenu); + auto autoTypeButton = qobject_cast(m_ui->toolBar->widgetForAction(m_ui->actionEntryAutoType)); + if (autoTypeButton) { + autoTypeButton->setPopupMode(QToolButton::MenuButtonPopup); + } + restoreGeometry(config()->get(Config::GUI_MainWindowGeometry).toByteArray()); restoreState(config()->get(Config::GUI_MainWindowState).toByteArray()); #ifdef WITH_XC_BROWSER @@ -223,12 +237,7 @@ MainWindow::MainWindow() m_ui->toolbarSeparator->setVisible(false); m_showToolbarSeparator = config()->get(Config::GUI_ApplicationTheme).toString() != "classic"; - bool isAutoTypeAvailable = autoType()->isAvailable(); - m_ui->actionEntryAutoType->setVisible(isAutoTypeAvailable); - m_ui->actionEntryAutoTypeUsername->setVisible(isAutoTypeAvailable); - m_ui->actionEntryAutoTypeUsernameEnter->setVisible(isAutoTypeAvailable); - m_ui->actionEntryAutoTypePassword->setVisible(isAutoTypeAvailable); - m_ui->actionEntryAutoTypePasswordEnter->setVisible(isAutoTypeAvailable); + m_ui->actionEntryAutoType->setVisible(autoType()->isAvailable()); m_inactivityTimer = new InactivityTimer(this); connect(m_inactivityTimer, SIGNAL(inactivityDetected()), this, SLOT(lockDatabasesAfterInactivity())); @@ -257,7 +266,7 @@ MainWindow::MainWindow() m_ui->actionEntryMoveDown->setShortcut(Qt::CTRL + Qt::ALT + Qt::Key_Down); m_ui->actionEntryCopyUsername->setShortcut(Qt::CTRL + Qt::Key_B); m_ui->actionEntryCopyPassword->setShortcut(Qt::CTRL + Qt::Key_C); - m_ui->actionEntryAutoType->setShortcut(Qt::CTRL + Qt::SHIFT + Qt::Key_V); + m_ui->actionEntryAutoTypeSequence->setShortcut(Qt::CTRL + Qt::SHIFT + Qt::Key_V); m_ui->actionEntryOpenUrl->setShortcut(Qt::CTRL + Qt::SHIFT + Qt::Key_U); m_ui->actionEntryCopyURL->setShortcut(Qt::CTRL + Qt::Key_U); @@ -284,7 +293,7 @@ MainWindow::MainWindow() m_ui->actionEntryMoveDown->setShortcutVisibleInContextMenu(true); m_ui->actionEntryCopyUsername->setShortcutVisibleInContextMenu(true); m_ui->actionEntryCopyPassword->setShortcutVisibleInContextMenu(true); - m_ui->actionEntryAutoType->setShortcutVisibleInContextMenu(true); + m_ui->actionEntryAutoTypeSequence->setShortcutVisibleInContextMenu(true); m_ui->actionEntryOpenUrl->setShortcutVisibleInContextMenu(true); m_ui->actionEntryCopyURL->setShortcutVisibleInContextMenu(true); m_ui->actionEntryAddToAgent->setShortcutVisibleInContextMenu(true); @@ -360,7 +369,7 @@ MainWindow::MainWindow() m_ui->actionEntryEdit->setIcon(icons()->icon("entry-edit")); m_ui->actionEntryDelete->setIcon(icons()->icon("entry-delete")); m_ui->actionEntryAutoType->setIcon(icons()->icon("auto-type")); - m_ui->menuEntryAutoTypeWithSequence->setIcon(icons()->icon("auto-type")); + m_ui->actionEntryAutoTypeSequence->setIcon(icons()->icon("auto-type")); m_ui->actionEntryAutoTypeUsername->setIcon(icons()->icon("auto-type")); m_ui->actionEntryAutoTypeUsernameEnter->setIcon(icons()->icon("auto-type")); m_ui->actionEntryAutoTypePassword->setIcon(icons()->icon("auto-type")); @@ -458,6 +467,7 @@ MainWindow::MainWindow() m_actionMultiplexer.connect(m_ui->actionEntryCopyURL, SIGNAL(triggered()), SLOT(copyURL())); m_actionMultiplexer.connect(m_ui->actionEntryCopyNotes, SIGNAL(triggered()), SLOT(copyNotes())); m_actionMultiplexer.connect(m_ui->actionEntryAutoType, SIGNAL(triggered()), SLOT(performAutoType())); + m_actionMultiplexer.connect(m_ui->actionEntryAutoTypeSequence, SIGNAL(triggered()), SLOT(performAutoType())); m_actionMultiplexer.connect( m_ui->actionEntryAutoTypeUsername, SIGNAL(triggered()), SLOT(performAutoTypeUsername())); m_actionMultiplexer.connect( @@ -782,7 +792,11 @@ void MainWindow::setMenuActionState(DatabaseWidget::Mode mode) m_ui->menuEntryCopyAttribute->setEnabled(singleEntrySelected); m_ui->menuEntryTotp->setEnabled(singleEntrySelected); m_ui->actionEntryAutoType->setEnabled(singleEntrySelected); - m_ui->menuEntryAutoTypeWithSequence->setEnabled(singleEntrySelected); + m_ui->actionEntryAutoType->menu()->setEnabled(singleEntrySelected); + 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()); @@ -841,7 +855,6 @@ void MainWindow::setMenuActionState(DatabaseWidget::Mode mode) m_ui->actionEntryCopyURL, m_ui->actionEntryOpenUrl, m_ui->actionEntryAutoType, - m_ui->menuEntryAutoTypeWithSequence->menuAction(), m_ui->actionEntryDownloadIcon, m_ui->actionEntryCopyNotes, m_ui->actionEntryCopyTitle, diff --git a/src/gui/MainWindow.ui b/src/gui/MainWindow.ui index b57ef848..125ef23f 100644 --- a/src/gui/MainWindow.ui +++ b/src/gui/MainWindow.ui @@ -310,18 +310,6 @@ - - - false - - - Perform Auto-Type Sequence - - - - - - @@ -336,7 +324,6 @@ - @@ -704,6 +691,12 @@ {USERNAME} + + {USERNAME} + + + {USERNAME} + @@ -712,6 +705,12 @@ {USERNAME}{ENTER} + + {USERNAME}{ENTER} + + + {USERNAME}{ENTER} + @@ -720,6 +719,12 @@ {PASSWORD} + + {PASSWORD} + + + {PASSWORD} + @@ -728,6 +733,12 @@ {PASSWORD}{ENTER} + + {PASSWORD}{ENTER} + + + {PASSWORD}{ENTER} + @@ -1023,6 +1034,17 @@ Ctrl+Shift+C + + + {USERNAME}{TAB}{PASSWORD}{ENTER} + + + {USERNAME}{TAB}{PASSWORD}{ENTER} + + + {USERNAME}{TAB}{PASSWORD}{ENTER} + +