diff --git a/src/autotype/AutoType.cpp b/src/autotype/AutoType.cpp index f3496849d..2519b9dcb 100644 --- a/src/autotype/AutoType.cpp +++ b/src/autotype/AutoType.cpp @@ -563,7 +563,8 @@ QString AutoType::autoTypeSequence(const Entry* entry, const QString& windowTitl bool match = false; const QList assocList = entry->autoTypeAssociations()->getAll(); for (const AutoTypeAssociations::Association& assoc : assocList) { - if (windowMatches(windowTitle, assoc.window)) { + const QString window = entry->resolveMultiplePlaceholders(assoc.window); + if (windowMatches(windowTitle, window)) { if (!assoc.sequence.isEmpty()) { sequence = assoc.sequence; } diff --git a/src/gui/entry/AutoTypeAssociationsModel.cpp b/src/gui/entry/AutoTypeAssociationsModel.cpp index 4a76233b4..442453de0 100644 --- a/src/gui/entry/AutoTypeAssociationsModel.cpp +++ b/src/gui/entry/AutoTypeAssociationsModel.cpp @@ -17,9 +17,12 @@ #include "AutoTypeAssociationsModel.h" +#include "core/Entry.h" + AutoTypeAssociationsModel::AutoTypeAssociationsModel(QObject* parent) : QAbstractListModel(parent) , m_autoTypeAssociations(nullptr) + , m_entry(nullptr) { } @@ -46,6 +49,11 @@ void AutoTypeAssociationsModel::setAutoTypeAssociations(AutoTypeAssociations* au endResetModel(); } +void AutoTypeAssociationsModel::setEntry(const Entry *entry) +{ + m_entry = entry; +} + int AutoTypeAssociationsModel::rowCount(const QModelIndex& parent) const { if (!m_autoTypeAssociations || parent.isValid()) { @@ -86,7 +94,12 @@ QVariant AutoTypeAssociationsModel::data(const QModelIndex& index, int role) con if (role == Qt::DisplayRole) { if (index.column() == 0) { - return m_autoTypeAssociations->get(index.row()).window; + QString window = m_autoTypeAssociations->get(index.row()).window; + if (m_entry) { + window = m_entry->maskPasswordPlaceholders(window); + window = m_entry->resolveMultiplePlaceholders(window); + } + return window; } else { QString sequence = m_autoTypeAssociations->get(index.row()).sequence; diff --git a/src/gui/entry/AutoTypeAssociationsModel.h b/src/gui/entry/AutoTypeAssociationsModel.h index cef8bc66b..1daa4a9c7 100644 --- a/src/gui/entry/AutoTypeAssociationsModel.h +++ b/src/gui/entry/AutoTypeAssociationsModel.h @@ -19,10 +19,11 @@ #define KEEPASSX_AUTOTYPEASSOCIATIONSMODEL_H #include +#include #include "core/AutoTypeAssociations.h" -class EntryAttributes; +class Entry; class AutoTypeAssociationsModel : public QAbstractListModel { @@ -31,6 +32,7 @@ class AutoTypeAssociationsModel : public QAbstractListModel public: explicit AutoTypeAssociationsModel(QObject* parent = nullptr); void setAutoTypeAssociations(AutoTypeAssociations* autoTypeAssociations); + void setEntry(const Entry* entry); int rowCount(const QModelIndex& parent = QModelIndex()) const override; int columnCount(const QModelIndex& parent = QModelIndex()) const override; QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; @@ -47,6 +49,7 @@ public slots: private: AutoTypeAssociations* m_autoTypeAssociations; + QPointer m_entry; }; #endif // KEEPASSX_AUTOTYPEASSOCIATIONSMODEL_H diff --git a/src/gui/entry/EditEntryWidget.cpp b/src/gui/entry/EditEntryWidget.cpp index 809ac95eb..463096b32 100644 --- a/src/gui/entry/EditEntryWidget.cpp +++ b/src/gui/entry/EditEntryWidget.cpp @@ -378,6 +378,7 @@ void EditEntryWidget::setForms(const Entry* entry, bool restore) m_autoTypeUi->defaultWindowSequenceButton->setChecked(true); m_autoTypeUi->windowSequenceEdit->setText(""); m_autoTypeAssoc->copyDataFrom(entry->autoTypeAssociations()); + m_autoTypeAssocModel->setEntry(entry); if (m_autoTypeAssoc->size() != 0) { m_autoTypeUi->assocView->setCurrentIndex(m_autoTypeAssocModel->index(0, 0)); } diff --git a/tests/TestAutoType.cpp b/tests/TestAutoType.cpp index be73efd47..acc2df61f 100644 --- a/tests/TestAutoType.cpp +++ b/tests/TestAutoType.cpp @@ -96,6 +96,9 @@ void TestAutoType::init() m_entry4->setGroup(m_group); m_entry4->setPassword("custom_attr"); m_entry4->attributes()->set("CUSTOM","Attribute",false); + m_entry4->attributes()->set("CustomAttrFirst","AttrValueFirst",false); + m_entry4->attributes()->set("CustomAttrSecond","AttrValueSecond",false); + m_entry4->attributes()->set("CustomAttrThird","AttrValueThird",false); association.window = "//^CustomAttr1$//"; association.sequence = "{PASSWORD}:{S:CUSTOM}"; m_entry4->autoTypeAssociations()->add(association); @@ -105,7 +108,16 @@ void TestAutoType::init() association.window = "//^CustomAttr3$//"; association.sequence = "{PaSSworD}"; m_entry4->autoTypeAssociations()->add(association); - + association.window = "//^{S:CustomAttrFirst}$//"; + association.sequence = "custom_attr_first"; + m_entry4->autoTypeAssociations()->add(association); + association.window = "//{S:CustomAttrFirst}And{S:CustomAttrSecond}//"; + association.sequence = "custom_attr_first_and_second"; + m_entry4->autoTypeAssociations()->add(association); + association.window = "//{S:CustomAttrThird}//"; + association.sequence = "custom_attr_third"; + m_entry4->autoTypeAssociations()->add(association); + m_entry5 = new Entry(); m_entry5->setGroup(m_group); m_entry5->setPassword("example5"); @@ -253,4 +265,20 @@ void TestAutoType::testGlobalAutoTypeRegExp() m_autoType->performGlobalAutoType(m_dbList); QCOMPARE(m_test->actionChars(), QString("custom_attr")); m_test->clearActions(); + + // with resolve placeholders in window association title + m_test->setActiveWindowTitle("AttrValueFirst"); + m_autoType->performGlobalAutoType(m_dbList); + QCOMPARE(m_test->actionChars(), QString("custom_attr_first")); + m_test->clearActions(); + + m_test->setActiveWindowTitle("lorem AttrValueFirstAndAttrValueSecond ipsum"); + m_autoType->performGlobalAutoType(m_dbList); + QCOMPARE(m_test->actionChars(), QString("custom_attr_first_and_second")); + m_test->clearActions(); + + m_test->setActiveWindowTitle("lorem AttrValueThird ipsum"); + m_autoType->performGlobalAutoType(m_dbList); + QCOMPARE(m_test->actionChars(), QString("custom_attr_third")); + m_test->clearActions(); }