From a03e35450415283a9f9101d19d71acb83202b129 Mon Sep 17 00:00:00 2001 From: thez3ro Date: Sun, 5 Mar 2017 23:47:08 +0100 Subject: [PATCH 1/3] highlight reference field in Database view --- src/core/Entry.cpp | 11 +++++++++++ src/core/Entry.h | 1 + src/core/EntryAttributes.cpp | 15 +++++++++++++++ src/core/EntryAttributes.h | 1 + src/gui/entry/EntryModel.cpp | 27 ++++++++++++++++++++++++--- 5 files changed, 52 insertions(+), 3 deletions(-) diff --git a/src/core/Entry.cpp b/src/core/Entry.cpp index 99f119f66..208a1dec9 100644 --- a/src/core/Entry.cpp +++ b/src/core/Entry.cpp @@ -254,6 +254,17 @@ bool Entry::isExpired() const return m_data.timeInfo.expires() && m_data.timeInfo.expiryTime() < QDateTime::currentDateTimeUtc(); } +bool Entry::hasReferences() const +{ + const QList keyList = EntryAttributes::DefaultAttributes; + for (const QString& key : keyList) { + if (m_attributes->isReference(key)) { + return true; + } + } + return false; +} + EntryAttributes* Entry::attributes() { return m_attributes; diff --git a/src/core/Entry.h b/src/core/Entry.h index d08c7217c..38ec42d4e 100644 --- a/src/core/Entry.h +++ b/src/core/Entry.h @@ -79,6 +79,7 @@ public: QString password() const; QString notes() const; bool isExpired() const; + bool hasReferences() const; EntryAttributes* attributes(); const EntryAttributes* attributes() const; EntryAttachments* attachments(); diff --git a/src/core/EntryAttributes.cpp b/src/core/EntryAttributes.cpp index b633cae32..6f3c4fd6f 100644 --- a/src/core/EntryAttributes.cpp +++ b/src/core/EntryAttributes.cpp @@ -69,6 +69,21 @@ bool EntryAttributes::isProtected(const QString& key) const return m_protectedAttributes.contains(key); } +bool EntryAttributes::isReference(const QString& key) const +{ + if (!m_attributes.contains(key)) { + Q_ASSERT(false); + return false; + } + + QString data = value(key); + QRegExp referenceRegExp("\\{REF:([TUPAN])@I:([^}]+)\\}", Qt::CaseInsensitive, QRegExp::RegExp2); + if (referenceRegExp.indexIn(data) != -1) { + return true; + } + return false; +} + void EntryAttributes::set(const QString& key, const QString& value, bool protect) { bool emitModified = false; diff --git a/src/core/EntryAttributes.h b/src/core/EntryAttributes.h index 211b6d483..be33ab167 100644 --- a/src/core/EntryAttributes.h +++ b/src/core/EntryAttributes.h @@ -35,6 +35,7 @@ public: QString value(const QString& key) const; bool contains(const QString& key) const; bool isProtected(const QString& key) const; + bool isReference(const QString& key) const; void set(const QString& key, const QString& value, bool protect = false); void remove(const QString& key); void rename(const QString& oldKey, const QString& newKey); diff --git a/src/gui/entry/EntryModel.cpp b/src/gui/entry/EntryModel.cpp index d606a777e..323a55c82 100644 --- a/src/gui/entry/EntryModel.cpp +++ b/src/gui/entry/EntryModel.cpp @@ -19,6 +19,7 @@ #include #include +#include #include "core/DatabaseIcons.h" #include "core/Entry.h" @@ -127,8 +128,10 @@ QVariant EntryModel::data(const QModelIndex& index, int role) const } Entry* entry = entryFromIndex(index); + EntryAttributes* attr = entry->attributes(); if (role == Qt::DisplayRole) { + QString result; switch (index.column()) { case ParentGroup: if (entry->group()) { @@ -136,11 +139,23 @@ QVariant EntryModel::data(const QModelIndex& index, int role) const } break; case Title: - return entry->title(); + result = entry->resolvePlaceholder(entry->title()); + if (attr->isReference(EntryAttributes::TitleKey)) { + result.prepend(tr("Ref: ","Reference abbreviation")); + } + return result; case Username: - return entry->username(); + result = entry->resolvePlaceholder(entry->username()); + if (attr->isReference(EntryAttributes::UserNameKey)) { + result.prepend(tr("Ref: ","Reference abbreviation")); + } + return result; case Url: - return entry->url(); + result = entry->resolvePlaceholder(entry->url()); + if (attr->isReference(EntryAttributes::URLKey)) { + result.prepend(tr("Ref: ","Reference abbreviation")); + } + return result; } } else if (role == Qt::DecorationRole) { @@ -166,6 +181,12 @@ QVariant EntryModel::data(const QModelIndex& index, int role) const } return font; } + else if (role == Qt::TextColorRole) { + if (entry->hasReferences()) { + QPalette p; + return QVariant(p.color(QPalette::Active, QPalette::Mid)); + } + } return QVariant(); } From 40851409fb90004b4aefda2775ff4ae3282c0da6 Mon Sep 17 00:00:00 2001 From: thez3ro Date: Tue, 7 Mar 2017 17:19:41 +0100 Subject: [PATCH 2/3] reuse referenceRegExp --- src/core/Entry.cpp | 2 +- src/core/EntryAttributes.cpp | 9 +++++++-- src/core/EntryAttributes.h | 2 ++ 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/core/Entry.cpp b/src/core/Entry.cpp index 208a1dec9..235dd3a7e 100644 --- a/src/core/Entry.cpp +++ b/src/core/Entry.cpp @@ -690,7 +690,7 @@ QString Entry::resolvePlaceholder(const QString& str) const // using format from http://keepass.info/help/base/fieldrefs.html at the time of writing, // but supporting lookups of standard fields and references by UUID only - QRegExp tmpRegExp("\\{REF:([TUPAN])@I:([^}]+)\\}", Qt::CaseInsensitive, QRegExp::RegExp2); + QRegExp tmpRegExp = m_attributes->referenceRegExp(); if (tmpRegExp.indexIn(result) != -1) { // cap(0) contains the whole reference // cap(1) contains which field is wanted diff --git a/src/core/EntryAttributes.cpp b/src/core/EntryAttributes.cpp index 6f3c4fd6f..94e5f96b6 100644 --- a/src/core/EntryAttributes.cpp +++ b/src/core/EntryAttributes.cpp @@ -28,6 +28,7 @@ const QString EntryAttributes::RememberCmdExecAttr = "_EXEC_CMD"; EntryAttributes::EntryAttributes(QObject* parent) : QObject(parent) + , m_referenceRegExp("\\{REF:([TUPAN])@I:([^}]+)\\}", Qt::CaseInsensitive, QRegExp::RegExp2) { clear(); } @@ -77,13 +78,17 @@ bool EntryAttributes::isReference(const QString& key) const } QString data = value(key); - QRegExp referenceRegExp("\\{REF:([TUPAN])@I:([^}]+)\\}", Qt::CaseInsensitive, QRegExp::RegExp2); - if (referenceRegExp.indexIn(data) != -1) { + if (m_referenceRegExp.indexIn(data) != -1) { return true; } return false; } +QRegExp EntryAttributes::referenceRegExp() const +{ + return m_referenceRegExp; +} + void EntryAttributes::set(const QString& key, const QString& value, bool protect) { bool emitModified = false; diff --git a/src/core/EntryAttributes.h b/src/core/EntryAttributes.h index be33ab167..42abed1ee 100644 --- a/src/core/EntryAttributes.h +++ b/src/core/EntryAttributes.h @@ -36,6 +36,7 @@ public: bool contains(const QString& key) const; bool isProtected(const QString& key) const; bool isReference(const QString& key) const; + QRegExp referenceRegExp() const; void set(const QString& key, const QString& value, bool protect = false); void remove(const QString& key); void rename(const QString& oldKey, const QString& newKey); @@ -72,6 +73,7 @@ Q_SIGNALS: private: QMap m_attributes; QSet m_protectedAttributes; + QRegExp m_referenceRegExp; }; #endif // KEEPASSX_ENTRYATTRIBUTES_H From 78acdf9095f61f359d444e46d2cb2f4c30f27746 Mon Sep 17 00:00:00 2001 From: thez3ro Date: Tue, 7 Mar 2017 20:16:51 +0100 Subject: [PATCH 3/3] pointer to referenceRegExp --- src/core/Entry.cpp | 18 +++++++++--------- src/core/EntryAttributes.cpp | 4 ++-- src/core/EntryAttributes.h | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/core/Entry.cpp b/src/core/Entry.cpp index 235dd3a7e..a2e72f7fd 100644 --- a/src/core/Entry.cpp +++ b/src/core/Entry.cpp @@ -690,20 +690,20 @@ QString Entry::resolvePlaceholder(const QString& str) const // using format from http://keepass.info/help/base/fieldrefs.html at the time of writing, // but supporting lookups of standard fields and references by UUID only - QRegExp tmpRegExp = m_attributes->referenceRegExp(); - if (tmpRegExp.indexIn(result) != -1) { + QRegExp* tmpRegExp = m_attributes->referenceRegExp(); + if (tmpRegExp->indexIn(result) != -1) { // cap(0) contains the whole reference // cap(1) contains which field is wanted // cap(2) contains the uuid of the referenced entry - Entry* tmpRefEntry = m_group->database()->resolveEntry(Uuid(QByteArray::fromHex(tmpRegExp.cap(2).toLatin1()))); + Entry* tmpRefEntry = m_group->database()->resolveEntry(Uuid(QByteArray::fromHex(tmpRegExp->cap(2).toLatin1()))); if (tmpRefEntry) { // entry found, get the relevant field - QString tmpRefField = tmpRegExp.cap(1).toLower(); - if (tmpRefField == "t") result.replace(tmpRegExp.cap(0), tmpRefEntry->title(), Qt::CaseInsensitive); - else if (tmpRefField == "u") result.replace(tmpRegExp.cap(0), tmpRefEntry->username(), Qt::CaseInsensitive); - else if (tmpRefField == "p") result.replace(tmpRegExp.cap(0), tmpRefEntry->password(), Qt::CaseInsensitive); - else if (tmpRefField == "a") result.replace(tmpRegExp.cap(0), tmpRefEntry->url(), Qt::CaseInsensitive); - else if (tmpRefField == "n") result.replace(tmpRegExp.cap(0), tmpRefEntry->notes(), Qt::CaseInsensitive); + QString tmpRefField = tmpRegExp->cap(1).toLower(); + if (tmpRefField == "t") result.replace(tmpRegExp->cap(0), tmpRefEntry->title(), Qt::CaseInsensitive); + else if (tmpRefField == "u") result.replace(tmpRegExp->cap(0), tmpRefEntry->username(), Qt::CaseInsensitive); + else if (tmpRefField == "p") result.replace(tmpRegExp->cap(0), tmpRefEntry->password(), Qt::CaseInsensitive); + else if (tmpRefField == "a") result.replace(tmpRegExp->cap(0), tmpRefEntry->url(), Qt::CaseInsensitive); + else if (tmpRefField == "n") result.replace(tmpRegExp->cap(0), tmpRefEntry->notes(), Qt::CaseInsensitive); } } diff --git a/src/core/EntryAttributes.cpp b/src/core/EntryAttributes.cpp index 94e5f96b6..865e853f2 100644 --- a/src/core/EntryAttributes.cpp +++ b/src/core/EntryAttributes.cpp @@ -84,9 +84,9 @@ bool EntryAttributes::isReference(const QString& key) const return false; } -QRegExp EntryAttributes::referenceRegExp() const +QRegExp* EntryAttributes::referenceRegExp() { - return m_referenceRegExp; + return &m_referenceRegExp; } void EntryAttributes::set(const QString& key, const QString& value, bool protect) diff --git a/src/core/EntryAttributes.h b/src/core/EntryAttributes.h index 42abed1ee..78afe5efa 100644 --- a/src/core/EntryAttributes.h +++ b/src/core/EntryAttributes.h @@ -36,7 +36,7 @@ public: bool contains(const QString& key) const; bool isProtected(const QString& key) const; bool isReference(const QString& key) const; - QRegExp referenceRegExp() const; + QRegExp* referenceRegExp(); void set(const QString& key, const QString& value, bool protect = false); void remove(const QString& key); void rename(const QString& oldKey, const QString& newKey);