Cleanup entry level Auto-Type menu

* Show the sequence that will be typed when performing the default action
* Combine default sequence action with Username / Password options
* Fix #4939 - confirm prior to performing entry level auto-type if "Always Ask Before Auto-Type" is enabled
This commit is contained in:
Jonathan White 2020-11-11 17:40:42 -05:00
parent f3d88fbd36
commit 7ce35f81de
No known key found for this signature in database
GPG key ID: 440FC65F2E0C6E01
5 changed files with 80 additions and 45 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 104 KiB

After

Width:  |  Height:  |  Size: 82 KiB

Before After
Before After

View file

@ -759,44 +759,44 @@ void DatabaseWidget::removeFromAgent()
} }
#endif #endif
void DatabaseWidget::performAutoType() void DatabaseWidget::performAutoType(const QString& sequence)
{ {
auto currentEntry = currentSelectedEntry(); auto currentEntry = currentSelectedEntry();
if (currentEntry) { if (currentEntry) {
// 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()); autoType()->performAutoType(currentEntry, window());
} else {
autoType()->performAutoTypeWithSequence(currentEntry, sequence, window());
}
} }
} }
void DatabaseWidget::performAutoTypeUsername() void DatabaseWidget::performAutoTypeUsername()
{ {
auto currentEntry = currentSelectedEntry(); performAutoType(QStringLiteral("{USERNAME}"));
if (currentEntry) {
autoType()->performAutoTypeWithSequence(currentEntry, QStringLiteral("{USERNAME}"), window());
}
} }
void DatabaseWidget::performAutoTypeUsernameEnter() void DatabaseWidget::performAutoTypeUsernameEnter()
{ {
auto currentEntry = currentSelectedEntry(); performAutoType(QStringLiteral("{USERNAME}{ENTER}"));
if (currentEntry) {
autoType()->performAutoTypeWithSequence(currentEntry, QStringLiteral("{USERNAME}{ENTER}"), window());
}
} }
void DatabaseWidget::performAutoTypePassword() void DatabaseWidget::performAutoTypePassword()
{ {
auto currentEntry = currentSelectedEntry(); performAutoType(QStringLiteral("{PASSWORD}"));
if (currentEntry) {
autoType()->performAutoTypeWithSequence(currentEntry, QStringLiteral("{PASSWORD}"), window());
}
} }
void DatabaseWidget::performAutoTypePasswordEnter() void DatabaseWidget::performAutoTypePasswordEnter()
{ {
auto currentEntry = currentSelectedEntry(); performAutoType(QStringLiteral("{PASSWORD}{ENTER}"));
if (currentEntry) {
autoType()->performAutoTypeWithSequence(currentEntry, QStringLiteral("{PASSWORD}{ENTER}"), window());
}
} }
void DatabaseWidget::openUrl() void DatabaseWidget::openUrl()

View file

@ -105,6 +105,7 @@ public:
QStringList customEntryAttributes() const; QStringList customEntryAttributes() const;
bool isEditWidgetModified() const; bool isEditWidgetModified() const;
void clearAllWidgets(); void clearAllWidgets();
Entry* currentSelectedEntry();
bool currentEntryHasTitle(); bool currentEntryHasTitle();
bool currentEntryHasUsername(); bool currentEntryHasUsername();
bool currentEntryHasPassword(); bool currentEntryHasPassword();
@ -181,7 +182,7 @@ public slots:
void addToAgent(); void addToAgent();
void removeFromAgent(); void removeFromAgent();
#endif #endif
void performAutoType(); void performAutoType(const QString& sequence = {});
void performAutoTypeUsername(); void performAutoTypeUsername();
void performAutoTypeUsernameEnter(); void performAutoTypeUsernameEnter();
void performAutoTypePassword(); void performAutoTypePassword();
@ -257,7 +258,6 @@ private:
bool confirmDeleteEntries(QList<Entry*> entries, bool permanent); bool confirmDeleteEntries(QList<Entry*> entries, bool permanent);
void performIconDownloads(const QList<Entry*>& entries, bool force = false); void performIconDownloads(const QList<Entry*>& entries, bool force = false);
bool performSave(QString& errorMessage, const QString& fileName = {}); bool performSave(QString& errorMessage, const QString& fileName = {});
Entry* currentSelectedEntry();
QSharedPointer<Database> m_db; QSharedPointer<Database> m_db;

View file

@ -25,6 +25,7 @@
#include <QMimeData> #include <QMimeData>
#include <QShortcut> #include <QShortcut>
#include <QTimer> #include <QTimer>
#include <QToolButton>
#include <QWindow> #include <QWindow>
#include "config-keepassx.h" #include "config-keepassx.h"
@ -128,7 +129,6 @@ MainWindow::MainWindow()
m_entryContextMenu->addAction(m_ui->menuEntryTotp->menuAction()); m_entryContextMenu->addAction(m_ui->menuEntryTotp->menuAction());
m_entryContextMenu->addSeparator(); m_entryContextMenu->addSeparator();
m_entryContextMenu->addAction(m_ui->actionEntryAutoType); m_entryContextMenu->addAction(m_ui->actionEntryAutoType);
m_entryContextMenu->addAction(m_ui->menuEntryAutoTypeWithSequence->menuAction());
m_entryContextMenu->addSeparator(); m_entryContextMenu->addSeparator();
m_entryContextMenu->addAction(m_ui->actionEntryEdit); m_entryContextMenu->addAction(m_ui->actionEntryEdit);
m_entryContextMenu->addAction(m_ui->actionEntryClone); m_entryContextMenu->addAction(m_ui->actionEntryClone);
@ -144,6 +144,20 @@ MainWindow::MainWindow()
m_entryNewContextMenu = new QMenu(this); m_entryNewContextMenu = new QMenu(this);
m_entryNewContextMenu->addAction(m_ui->actionEntryNew); 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<QToolButton*>(m_ui->toolBar->widgetForAction(m_ui->actionEntryAutoType));
if (autoTypeButton) {
autoTypeButton->setPopupMode(QToolButton::MenuButtonPopup);
}
restoreGeometry(config()->get(Config::GUI_MainWindowGeometry).toByteArray()); restoreGeometry(config()->get(Config::GUI_MainWindowGeometry).toByteArray());
restoreState(config()->get(Config::GUI_MainWindowState).toByteArray()); restoreState(config()->get(Config::GUI_MainWindowState).toByteArray());
#ifdef WITH_XC_BROWSER #ifdef WITH_XC_BROWSER
@ -223,12 +237,7 @@ MainWindow::MainWindow()
m_ui->toolbarSeparator->setVisible(false); m_ui->toolbarSeparator->setVisible(false);
m_showToolbarSeparator = config()->get(Config::GUI_ApplicationTheme).toString() != "classic"; m_showToolbarSeparator = config()->get(Config::GUI_ApplicationTheme).toString() != "classic";
bool isAutoTypeAvailable = autoType()->isAvailable(); m_ui->actionEntryAutoType->setVisible(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_inactivityTimer = new InactivityTimer(this); m_inactivityTimer = new InactivityTimer(this);
connect(m_inactivityTimer, SIGNAL(inactivityDetected()), this, SLOT(lockDatabasesAfterInactivity())); 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->actionEntryMoveDown->setShortcut(Qt::CTRL + Qt::ALT + Qt::Key_Down);
m_ui->actionEntryCopyUsername->setShortcut(Qt::CTRL + Qt::Key_B); m_ui->actionEntryCopyUsername->setShortcut(Qt::CTRL + Qt::Key_B);
m_ui->actionEntryCopyPassword->setShortcut(Qt::CTRL + Qt::Key_C); 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->actionEntryOpenUrl->setShortcut(Qt::CTRL + Qt::SHIFT + Qt::Key_U);
m_ui->actionEntryCopyURL->setShortcut(Qt::CTRL + 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->actionEntryMoveDown->setShortcutVisibleInContextMenu(true);
m_ui->actionEntryCopyUsername->setShortcutVisibleInContextMenu(true); m_ui->actionEntryCopyUsername->setShortcutVisibleInContextMenu(true);
m_ui->actionEntryCopyPassword->setShortcutVisibleInContextMenu(true); m_ui->actionEntryCopyPassword->setShortcutVisibleInContextMenu(true);
m_ui->actionEntryAutoType->setShortcutVisibleInContextMenu(true); m_ui->actionEntryAutoTypeSequence->setShortcutVisibleInContextMenu(true);
m_ui->actionEntryOpenUrl->setShortcutVisibleInContextMenu(true); m_ui->actionEntryOpenUrl->setShortcutVisibleInContextMenu(true);
m_ui->actionEntryCopyURL->setShortcutVisibleInContextMenu(true); m_ui->actionEntryCopyURL->setShortcutVisibleInContextMenu(true);
m_ui->actionEntryAddToAgent->setShortcutVisibleInContextMenu(true); m_ui->actionEntryAddToAgent->setShortcutVisibleInContextMenu(true);
@ -360,7 +369,7 @@ MainWindow::MainWindow()
m_ui->actionEntryEdit->setIcon(icons()->icon("entry-edit")); m_ui->actionEntryEdit->setIcon(icons()->icon("entry-edit"));
m_ui->actionEntryDelete->setIcon(icons()->icon("entry-delete")); m_ui->actionEntryDelete->setIcon(icons()->icon("entry-delete"));
m_ui->actionEntryAutoType->setIcon(icons()->icon("auto-type")); 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->actionEntryAutoTypeUsername->setIcon(icons()->icon("auto-type"));
m_ui->actionEntryAutoTypeUsernameEnter->setIcon(icons()->icon("auto-type")); m_ui->actionEntryAutoTypeUsernameEnter->setIcon(icons()->icon("auto-type"));
m_ui->actionEntryAutoTypePassword->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->actionEntryCopyURL, SIGNAL(triggered()), SLOT(copyURL()));
m_actionMultiplexer.connect(m_ui->actionEntryCopyNotes, SIGNAL(triggered()), SLOT(copyNotes())); 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->actionEntryAutoType, SIGNAL(triggered()), SLOT(performAutoType()));
m_actionMultiplexer.connect(m_ui->actionEntryAutoTypeSequence, SIGNAL(triggered()), SLOT(performAutoType()));
m_actionMultiplexer.connect( m_actionMultiplexer.connect(
m_ui->actionEntryAutoTypeUsername, SIGNAL(triggered()), SLOT(performAutoTypeUsername())); m_ui->actionEntryAutoTypeUsername, SIGNAL(triggered()), SLOT(performAutoTypeUsername()));
m_actionMultiplexer.connect( m_actionMultiplexer.connect(
@ -782,7 +792,11 @@ void MainWindow::setMenuActionState(DatabaseWidget::Mode mode)
m_ui->menuEntryCopyAttribute->setEnabled(singleEntrySelected); m_ui->menuEntryCopyAttribute->setEnabled(singleEntrySelected);
m_ui->menuEntryTotp->setEnabled(singleEntrySelected); m_ui->menuEntryTotp->setEnabled(singleEntrySelected);
m_ui->actionEntryAutoType->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->actionEntryAutoTypeUsername->setEnabled(singleEntrySelected && dbWidget->currentEntryHasUsername());
m_ui->actionEntryAutoTypeUsernameEnter->setEnabled(singleEntrySelected m_ui->actionEntryAutoTypeUsernameEnter->setEnabled(singleEntrySelected
&& dbWidget->currentEntryHasUsername()); && dbWidget->currentEntryHasUsername());
@ -841,7 +855,6 @@ void MainWindow::setMenuActionState(DatabaseWidget::Mode mode)
m_ui->actionEntryCopyURL, m_ui->actionEntryCopyURL,
m_ui->actionEntryOpenUrl, m_ui->actionEntryOpenUrl,
m_ui->actionEntryAutoType, m_ui->actionEntryAutoType,
m_ui->menuEntryAutoTypeWithSequence->menuAction(),
m_ui->actionEntryDownloadIcon, m_ui->actionEntryDownloadIcon,
m_ui->actionEntryCopyNotes, m_ui->actionEntryCopyNotes,
m_ui->actionEntryCopyTitle, m_ui->actionEntryCopyTitle,

View file

@ -310,18 +310,6 @@
<addaction name="actionEntryTotpQRCode"/> <addaction name="actionEntryTotpQRCode"/>
<addaction name="actionEntrySetupTotp"/> <addaction name="actionEntrySetupTotp"/>
</widget> </widget>
<widget class="QMenu" name="menuEntryAutoTypeWithSequence">
<property name="enabled">
<bool>false</bool>
</property>
<property name="title">
<string>Perform Auto-Type Sequence</string>
</property>
<addaction name="actionEntryAutoTypeUsername"/>
<addaction name="actionEntryAutoTypeUsernameEnter"/>
<addaction name="actionEntryAutoTypePassword"/>
<addaction name="actionEntryAutoTypePasswordEnter"/>
</widget>
<addaction name="actionEntryNew"/> <addaction name="actionEntryNew"/>
<addaction name="actionEntryEdit"/> <addaction name="actionEntryEdit"/>
<addaction name="actionEntryClone"/> <addaction name="actionEntryClone"/>
@ -336,7 +324,6 @@
<addaction name="menuEntryTotp"/> <addaction name="menuEntryTotp"/>
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="actionEntryAutoType"/> <addaction name="actionEntryAutoType"/>
<addaction name="menuEntryAutoTypeWithSequence"/>
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="actionEntryOpenUrl"/> <addaction name="actionEntryOpenUrl"/>
<addaction name="actionEntryDownloadIcon"/> <addaction name="actionEntryDownloadIcon"/>
@ -704,6 +691,12 @@
<property name="text"> <property name="text">
<string notr="true">{USERNAME}</string> <string notr="true">{USERNAME}</string>
</property> </property>
<property name="iconText">
<string notr="true">{USERNAME}</string>
</property>
<property name="toolTip">
<string notr="true">{USERNAME}</string>
</property>
</action> </action>
<action name="actionEntryAutoTypeUsernameEnter"> <action name="actionEntryAutoTypeUsernameEnter">
<property name="enabled"> <property name="enabled">
@ -712,6 +705,12 @@
<property name="text"> <property name="text">
<string notr="true">{USERNAME}{ENTER}</string> <string notr="true">{USERNAME}{ENTER}</string>
</property> </property>
<property name="iconText">
<string notr="true">{USERNAME}{ENTER}</string>
</property>
<property name="toolTip">
<string notr="true">{USERNAME}{ENTER}</string>
</property>
</action> </action>
<action name="actionEntryAutoTypePassword"> <action name="actionEntryAutoTypePassword">
<property name="enabled"> <property name="enabled">
@ -720,6 +719,12 @@
<property name="text"> <property name="text">
<string notr="true">{PASSWORD}</string> <string notr="true">{PASSWORD}</string>
</property> </property>
<property name="iconText">
<string notr="true">{PASSWORD}</string>
</property>
<property name="toolTip">
<string notr="true">{PASSWORD}</string>
</property>
</action> </action>
<action name="actionEntryAutoTypePasswordEnter"> <action name="actionEntryAutoTypePasswordEnter">
<property name="enabled"> <property name="enabled">
@ -728,6 +733,12 @@
<property name="text"> <property name="text">
<string notr="true">{PASSWORD}{ENTER}</string> <string notr="true">{PASSWORD}{ENTER}</string>
</property> </property>
<property name="iconText">
<string notr="true">{PASSWORD}{ENTER}</string>
</property>
<property name="toolTip">
<string notr="true">{PASSWORD}{ENTER}</string>
</property>
</action> </action>
<action name="actionEntryDownloadIcon"> <action name="actionEntryDownloadIcon">
<property name="text"> <property name="text">
@ -1023,6 +1034,17 @@
<string notr="true">Ctrl+Shift+C</string> <string notr="true">Ctrl+Shift+C</string>
</property> </property>
</action> </action>
<action name="actionEntryAutoTypeSequence">
<property name="text">
<string notr="true">{USERNAME}{TAB}{PASSWORD}{ENTER}</string>
</property>
<property name="iconText">
<string notr="true">{USERNAME}{TAB}{PASSWORD}{ENTER}</string>
</property>
<property name="toolTip">
<string notr="true">{USERNAME}{TAB}{PASSWORD}{ENTER}</string>
</property>
</action>
</widget> </widget>
<customwidgets> <customwidgets>
<customwidget> <customwidget>