Add option to use the entry title for auto-type window matching.

This commit is contained in:
Felix Geyer 2014-05-15 18:26:01 +02:00
parent 9363d23e09
commit 147cd4ed7b
7 changed files with 98 additions and 47 deletions

View File

@ -503,6 +503,12 @@ QString AutoType::autoTypeSequence(const Entry* entry, const QString& windowTitl
} }
} }
if (!match && config()->get("AutoTypeEntryTitleMatch").toBool() && !entry->title().isEmpty()
&& windowTitle.contains(entry->title(), Qt::CaseInsensitive)) {
sequence = entry->defaultAutoTypeSequence();
match = true;
}
if (!match) { if (!match) {
return QString(); return QString();
} }

View File

@ -95,6 +95,7 @@ void Config::init(const QString& fileName)
m_defaults.insert("ShowToolbar", true); m_defaults.insert("ShowToolbar", true);
m_defaults.insert("MinimizeOnCopy", false); m_defaults.insert("MinimizeOnCopy", false);
m_defaults.insert("UseGroupIconOnEntryCreation", false); m_defaults.insert("UseGroupIconOnEntryCreation", false);
m_defaults.insert("AutoTypeEntryTitleMatch", false);
m_defaults.insert("security/clearclipboard", true); m_defaults.insert("security/clearclipboard", true);
m_defaults.insert("security/clearclipboardtimeout", 10); m_defaults.insert("security/clearclipboardtimeout", 10);
m_defaults.insert("security/lockdatabaseidle", false); m_defaults.insert("security/lockdatabaseidle", false);
@ -112,7 +113,7 @@ Config* Config::instance()
return m_instance; return m_instance;
} }
void Config::createConfigFromFile(QString file) void Config::createConfigFromFile(const QString& file)
{ {
Q_ASSERT(!m_instance); Q_ASSERT(!m_instance);
m_instance = new Config(file, qApp); m_instance = new Config(file, qApp);

View File

@ -36,7 +36,7 @@ public:
void set(const QString& key, const QVariant& value); void set(const QString& key, const QVariant& value);
static Config* instance(); static Config* instance();
static void createConfigFromFile(QString file); static void createConfigFromFile(const QString& file);
static void createTempFileInstance(); static void createTempFileInstance();
private: private:

View File

@ -67,6 +67,7 @@ void SettingsWidget::loadSettings()
m_generalUi->autoSaveOnExitCheckBox->setChecked(config()->get("AutoSaveOnExit").toBool()); m_generalUi->autoSaveOnExitCheckBox->setChecked(config()->get("AutoSaveOnExit").toBool());
m_generalUi->minimizeOnCopyCheckBox->setChecked(config()->get("MinimizeOnCopy").toBool()); m_generalUi->minimizeOnCopyCheckBox->setChecked(config()->get("MinimizeOnCopy").toBool());
m_generalUi->useGroupIconOnEntryCreationCheckBox->setChecked(config()->get("UseGroupIconOnEntryCreation").toBool()); m_generalUi->useGroupIconOnEntryCreationCheckBox->setChecked(config()->get("UseGroupIconOnEntryCreation").toBool());
m_generalUi->autoTypeEntryTitleMatchCheckBox->setChecked(config()->get("AutoTypeEntryTitleMatch").toBool());
if (autoType()->isAvailable()) { if (autoType()->isAvailable()) {
m_globalAutoTypeKey = static_cast<Qt::Key>(config()->get("GlobalAutoTypeKey").toInt()); m_globalAutoTypeKey = static_cast<Qt::Key>(config()->get("GlobalAutoTypeKey").toInt());
@ -102,6 +103,8 @@ void SettingsWidget::saveSettings()
config()->set("MinimizeOnCopy", m_generalUi->minimizeOnCopyCheckBox->isChecked()); config()->set("MinimizeOnCopy", m_generalUi->minimizeOnCopyCheckBox->isChecked());
config()->set("UseGroupIconOnEntryCreation", config()->set("UseGroupIconOnEntryCreation",
m_generalUi->useGroupIconOnEntryCreationCheckBox->isChecked()); m_generalUi->useGroupIconOnEntryCreationCheckBox->isChecked());
config()->set("AutoTypeEntryTitleMatch",
m_generalUi->autoTypeEntryTitleMatchCheckBox->isChecked());
if (autoType()->isAvailable()) { if (autoType()->isAvailable()) {
config()->set("GlobalAutoTypeKey", m_generalUi->autoTypeShortcutWidget->key()); config()->set("GlobalAutoTypeKey", m_generalUi->autoTypeShortcutWidget->key());
config()->set("GlobalAutoTypeModifiers", config()->set("GlobalAutoTypeModifiers",

View File

@ -7,10 +7,13 @@
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>456</width> <width>456</width>
<height>185</height> <height>230</height>
</rect> </rect>
</property> </property>
<layout class="QFormLayout" name="formLayout"> <layout class="QFormLayout" name="formLayout">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
</property>
<item row="0" column="0"> <item row="0" column="0">
<widget class="QCheckBox" name="rememberLastDatabasesCheckBox"> <widget class="QCheckBox" name="rememberLastDatabasesCheckBox">
<property name="text"> <property name="text">
@ -21,6 +24,13 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="0">
<widget class="QCheckBox" name="openPreviousDatabasesOnStartupCheckBox">
<property name="text">
<string>Open previous databases on startup</string>
</property>
</widget>
</item>
<item row="2" column="0"> <item row="2" column="0">
<widget class="QCheckBox" name="modifiedExpandedChangedCheckBox"> <widget class="QCheckBox" name="modifiedExpandedChangedCheckBox">
<property name="text"> <property name="text">
@ -31,13 +41,6 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="4" column="0">
<widget class="QCheckBox" name="autoSaveAfterEveryChangeCheckBox">
<property name="text">
<string>Automatically save after every change</string>
</property>
</widget>
</item>
<item row="3" column="0"> <item row="3" column="0">
<widget class="QCheckBox" name="autoSaveOnExitCheckBox"> <widget class="QCheckBox" name="autoSaveOnExitCheckBox">
<property name="text"> <property name="text">
@ -45,20 +48,10 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="7" column="0"> <item row="4" column="0">
<widget class="QLabel" name="autoTypeShortcutLabel"> <widget class="QCheckBox" name="autoSaveAfterEveryChangeCheckBox">
<property name="text"> <property name="text">
<string>Global Auto-Type shortcut</string> <string>Automatically save after every change</string>
</property>
</widget>
</item>
<item row="7" column="1">
<widget class="ShortcutWidget" name="autoTypeShortcutWidget"/>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="openPreviousDatabasesOnStartupCheckBox">
<property name="text">
<string>Open previous databases on startup</string>
</property> </property>
</widget> </widget>
</item> </item>
@ -76,6 +69,23 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="7" column="0">
<widget class="QLabel" name="autoTypeShortcutLabel">
<property name="text">
<string>Global Auto-Type shortcut</string>
</property>
</widget>
</item>
<item row="7" column="1">
<widget class="ShortcutWidget" name="autoTypeShortcutWidget"/>
</item>
<item row="8" column="0">
<widget class="QCheckBox" name="autoTypeEntryTitleMatchCheckBox">
<property name="text">
<string>Use entry title to match windows for global auto-type</string>
</property>
</widget>
</item>
</layout> </layout>
</widget> </widget>
<customwidgets> <customwidgets>

View File

@ -21,6 +21,7 @@
#include <QTest> #include <QTest>
#include "tests.h" #include "tests.h"
#include "core/Config.h"
#include "core/FilePath.h" #include "core/FilePath.h"
#include "core/Entry.h" #include "core/Entry.h"
#include "core/Group.h" #include "core/Group.h"
@ -33,7 +34,7 @@
void TestAutoType::initTestCase() void TestAutoType::initTestCase()
{ {
Crypto::init(); Crypto::init();
Config::createTempFileInstance();
AutoType::createTestInstance(); AutoType::createTestInstance();
QPluginLoader loader(filePath()->pluginPath("keepassx-autotype-test")); QPluginLoader loader(filePath()->pluginPath("keepassx-autotype-test"));
@ -54,12 +55,24 @@ void TestAutoType::init()
m_test->clearActions(); m_test->clearActions();
m_db = new Database(); m_db = new Database();
m_dbList.clear();
m_dbList.append(m_db);
m_group = new Group(); m_group = new Group();
m_db->setRootGroup(m_group); m_db->setRootGroup(m_group);
m_entry = new Entry();
m_entry->setGroup(m_group); m_entry1 = new Entry();
m_entry->setUsername("myuser"); m_entry1->setGroup(m_group);
m_entry->setPassword("mypass"); m_entry1->setUsername("myuser");
m_entry1->setPassword("mypass");
AutoTypeAssociations::Association association;
association.window = "custom window";
association.sequence = "{username}association{password}";
m_entry1->autoTypeAssociations()->add(association);
m_entry2 = new Entry();
m_entry2->setGroup(m_group);
m_entry2->setPassword("myuser");
m_entry2->setTitle("entry title");
} }
void TestAutoType::cleanup() void TestAutoType::cleanup()
@ -77,7 +90,7 @@ void TestAutoType::testInternal()
void TestAutoType::testAutoTypeWithoutSequence() void TestAutoType::testAutoTypeWithoutSequence()
{ {
m_autoType->performAutoType(m_entry, Q_NULLPTR); m_autoType->performAutoType(m_entry1, Q_NULLPTR);
QCOMPARE(m_test->actionCount(), 14); QCOMPARE(m_test->actionCount(), 14);
QCOMPARE(m_test->actionChars(), QCOMPARE(m_test->actionChars(),
@ -88,42 +101,56 @@ void TestAutoType::testAutoTypeWithoutSequence()
void TestAutoType::testAutoTypeWithSequence() void TestAutoType::testAutoTypeWithSequence()
{ {
m_autoType->performAutoType(m_entry, Q_NULLPTR, "{Username}abc{PaSsWoRd}"); m_autoType->performAutoType(m_entry1, Q_NULLPTR, "{Username}abc{PaSsWoRd}");
QCOMPARE(m_test->actionCount(), 15); QCOMPARE(m_test->actionCount(), 15);
QCOMPARE(m_test->actionChars(), QCOMPARE(m_test->actionChars(),
QString("%1abc%2") QString("%1abc%2")
.arg(m_entry->username()) .arg(m_entry1->username())
.arg(m_entry->password())); .arg(m_entry1->password()));
} }
void TestAutoType::testGlobalAutoTypeWithNoMatch() void TestAutoType::testGlobalAutoTypeWithNoMatch()
{ {
QList<Database*> dbList; m_test->setActiveWindowTitle("nomatch");
dbList.append(m_db);
MessageBox::setNextAnswer(QMessageBox::Ok); MessageBox::setNextAnswer(QMessageBox::Ok);
m_autoType->performGlobalAutoType(dbList); m_autoType->performGlobalAutoType(m_dbList);
QCOMPARE(m_test->actionChars(), QString()); QCOMPARE(m_test->actionChars(), QString());
} }
void TestAutoType::testGlobalAutoTypeWithOneMatch() void TestAutoType::testGlobalAutoTypeWithOneMatch()
{ {
QList<Database*> dbList;
dbList.append(m_db);
AutoTypeAssociations::Association association;
association.window = "custom window";
association.sequence = "{username}association{password}";
m_entry->autoTypeAssociations()->add(association);
m_test->setActiveWindowTitle("custom window"); m_test->setActiveWindowTitle("custom window");
m_autoType->performGlobalAutoType(dbList); m_autoType->performGlobalAutoType(m_dbList);
QCOMPARE(m_test->actionChars(), QCOMPARE(m_test->actionChars(),
QString("%1association%2") QString("%1association%2")
.arg(m_entry->username()) .arg(m_entry1->username())
.arg(m_entry->password())); .arg(m_entry1->password()));
}
void TestAutoType::testGlobalAutoTypeTitleMatch()
{
config()->set("AutoTypeEntryTitleMatch", true);
m_test->setActiveWindowTitle("An Entry Title!");
m_autoType->performGlobalAutoType(m_dbList);
QCOMPARE(m_test->actionChars(),
QString("%1%2").arg(m_entry2->password(), m_test->keyToString(Qt::Key_Enter)));
}
void TestAutoType::testGlobalAutoTypeTitleMatchDisabled()
{
config()->set("AutoTypeEntryTitleMatch", false);
m_test->setActiveWindowTitle("An Entry Title!");
MessageBox::setNextAnswer(QMessageBox::Ok);
m_autoType->performGlobalAutoType(m_dbList);
QCOMPARE(m_test->actionChars(), QString());
} }
QTEST_GUILESS_MAIN(TestAutoType) QTEST_GUILESS_MAIN(TestAutoType)

View File

@ -41,14 +41,18 @@ private Q_SLOTS:
void testAutoTypeWithSequence(); void testAutoTypeWithSequence();
void testGlobalAutoTypeWithNoMatch(); void testGlobalAutoTypeWithNoMatch();
void testGlobalAutoTypeWithOneMatch(); void testGlobalAutoTypeWithOneMatch();
void testGlobalAutoTypeTitleMatch();
void testGlobalAutoTypeTitleMatchDisabled();
private: private:
AutoTypePlatformInterface* m_platform; AutoTypePlatformInterface* m_platform;
AutoTypeTestInterface* m_test; AutoTypeTestInterface* m_test;
AutoType* m_autoType; AutoType* m_autoType;
Database* m_db; Database* m_db;
QList<Database*> m_dbList;
Group* m_group; Group* m_group;
Entry* m_entry; Entry* m_entry1;
Entry* m_entry2;
}; };
#endif // KEEPASSX_TESTAUTOTYPE_H #endif // KEEPASSX_TESTAUTOTYPE_H