Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/keepassxreboot/keepassxc.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/gui/entry/EntryModel.cpp')
-rw-r--r--src/gui/entry/EntryModel.cpp215
1 files changed, 190 insertions, 25 deletions
diff --git a/src/gui/entry/EntryModel.cpp b/src/gui/entry/EntryModel.cpp
index 2f79f02d9..6f7ebf6af 100644
--- a/src/gui/entry/EntryModel.cpp
+++ b/src/gui/entry/EntryModel.cpp
@@ -18,8 +18,11 @@
#include "EntryModel.h"
#include <QFont>
+#include <QFontMetrics>
#include <QMimeData>
#include <QPalette>
+#include <QDateTime>
+#include <QPainter>
#include "core/DatabaseIcons.h"
#include "core/Entry.h"
@@ -27,9 +30,17 @@
#include "core/Group.h"
#include "core/Metadata.h"
+// String being displayed when hiding content
+const QString EntryModel::HiddenContentDisplay(QString("\u25cf").repeated(6));
+
+// Format used to display dates
+const Qt::DateFormat EntryModel::DateFormat = Qt::DefaultLocaleShortDate;
+
EntryModel::EntryModel(QObject* parent)
: QAbstractTableModel(parent)
, m_group(nullptr)
+ , m_hideUsernames(false)
+ , m_hidePasswords(true)
{
}
@@ -64,7 +75,7 @@ void EntryModel::setGroup(Group* group)
makeConnections(group);
endResetModel();
- emit switchedToGroupMode();
+ emit switchedToListMode();
}
void EntryModel::setEntryList(const QList<Entry*>& entries)
@@ -101,24 +112,26 @@ void EntryModel::setEntryList(const QList<Entry*>& entries)
}
endResetModel();
- emit switchedToEntryListMode();
+ emit switchedToSearchMode();
}
int EntryModel::rowCount(const QModelIndex& parent) const
{
if (parent.isValid()) {
return 0;
- }
- else {
+ } else {
return m_entries.size();
}
}
int EntryModel::columnCount(const QModelIndex& parent) const
{
- Q_UNUSED(parent);
+ // Advised by Qt documentation
+ if (parent.isValid()) {
+ return 0;
+ }
- return 4;
+ return 12;
}
QVariant EntryModel::data(const QModelIndex& index, int role) const
@@ -141,25 +154,92 @@ QVariant EntryModel::data(const QModelIndex& index, int role) const
case Title:
result = entry->resolveMultiplePlaceholders(entry->title());
if (attr->isReference(EntryAttributes::TitleKey)) {
- result.prepend(tr("Ref: ","Reference abbreviation"));
+ result.prepend(tr("Ref: ", "Reference abbreviation"));
}
return result;
case Username:
- result = entry->resolveMultiplePlaceholders(entry->username());
+ if (m_hideUsernames) {
+ result = EntryModel::HiddenContentDisplay;
+ } else {
+ result = entry->resolveMultiplePlaceholders(entry->username());
+ }
if (attr->isReference(EntryAttributes::UserNameKey)) {
- result.prepend(tr("Ref: ","Reference abbreviation"));
+ result.prepend(tr("Ref: ", "Reference abbreviation"));
+ }
+ return result;
+ case Password:
+ if (m_hidePasswords) {
+ result = EntryModel::HiddenContentDisplay;
+ } else {
+ result = entry->resolveMultiplePlaceholders(entry->password());
+ }
+ if (attr->isReference(EntryAttributes::PasswordKey)) {
+ result.prepend(tr("Ref: ", "Reference abbreviation"));
}
return result;
case Url:
- result = entry->maskPasswordPlaceholders(entry->url());
- result = entry->resolveMultiplePlaceholders(result);
+ result = entry->resolveMultiplePlaceholders(entry->displayUrl());
if (attr->isReference(EntryAttributes::URLKey)) {
- result.prepend(tr("Ref: ","Reference abbreviation"));
+ result.prepend(tr("Ref: ", "Reference abbreviation"));
+ }
+ return result;
+ case Notes:
+ // Display only first line of notes in simplified format
+ result = entry->resolveMultiplePlaceholders(entry->notes().section("\n", 0, 0).simplified());
+ if (attr->isReference(EntryAttributes::NotesKey)) {
+ result.prepend(tr("Ref: ", "Reference abbreviation"));
+ }
+ return result;
+ case Expires:
+ // Display either date of expiry or 'Never'
+ result = entry->timeInfo().expires() ? entry->timeInfo().expiryTime().toLocalTime().toString(EntryModel::DateFormat) : tr("Never");
+ return result;
+ case Created:
+ result = entry->timeInfo().creationTime().toLocalTime().toString(EntryModel::DateFormat);
+ return result;
+ case Modified:
+ result = entry->timeInfo().lastModificationTime().toLocalTime().toString(EntryModel::DateFormat);
+ return result;
+ case Accessed:
+ result = entry->timeInfo().lastAccessTime().toLocalTime().toString(EntryModel::DateFormat);
+ return result;
+ case Attachments:
+ // Display comma-separated list of attachments
+ QList<QString> attachments = entry->attachments()->keys();
+ for (int i = 0; i < attachments.size(); ++i) {
+ if (result.isEmpty()) {
+ result.append(attachments.at(i));
+ continue;
+ }
+ result.append(QString(", ") + attachments.at(i));
}
return result;
}
- }
- else if (role == Qt::DecorationRole) {
+ } else if (role == Qt::UserRole) { // Qt::UserRole is used as sort role, see EntryView::EntryView()
+ switch (index.column()) {
+ case Username:
+ return entry->resolveMultiplePlaceholders(entry->username());
+ case Password:
+ return entry->resolveMultiplePlaceholders(entry->password());
+ case Expires:
+ // There seems to be no better way of expressing 'infinity'
+ return entry->timeInfo().expires() ? entry->timeInfo().expiryTime() : QDateTime(QDate(9999, 1, 1));
+ case Created:
+ return entry->timeInfo().creationTime();
+ case Modified:
+ return entry->timeInfo().lastModificationTime();
+ case Accessed:
+ return entry->timeInfo().lastAccessTime();
+ case Paperclip:
+ // Display entries with attachments above those without when
+ // sorting ascendingly (and vice versa when sorting descendingly)
+ return entry->attachments()->isEmpty() ? 1 : 0;
+ default:
+ // For all other columns, simply use data provided by Qt::Display-
+ // Role for sorting
+ return data(index, Qt::DisplayRole);
+ }
+ } else if (role == Qt::DecorationRole) {
switch (index.column()) {
case ParentGroup:
if (entry->group()) {
@@ -170,30 +250,44 @@ QVariant EntryModel::data(const QModelIndex& index, int role) const
if (entry->isExpired()) {
return databaseIcons()->iconPixmap(DatabaseIcons::ExpiredIconIndex);
}
- else {
- return entry->iconScaledPixmap();
+ return entry->iconScaledPixmap();
+ case Paperclip:
+ if (!entry->attachments()->isEmpty()) {
+ return m_paperClipPixmap;
}
+ break;
}
- }
- else if (role == Qt::FontRole) {
+ } else if (role == Qt::FontRole) {
QFont font;
if (entry->isExpired()) {
font.setStrikeOut(true);
}
return font;
- }
- else if (role == Qt::TextColorRole) {
+ } else if (role == Qt::ForegroundRole) {
if (entry->hasReferences()) {
QPalette p;
return QVariant(p.color(QPalette::Active, QPalette::Mid));
+ } else if (entry->foregroundColor().isValid()) {
+ return QVariant(entry->foregroundColor());
+ }
+ } else if (role == Qt::BackgroundRole) {
+ if (entry->backgroundColor().isValid()) {
+ return QVariant(entry->backgroundColor());
+ }
+ } else if (role == Qt::TextAlignmentRole) {
+ if (index.column() == Paperclip) {
+ return Qt::AlignCenter;
}
}
return QVariant();
}
+
QVariant EntryModel::headerData(int section, Qt::Orientation orientation, int role) const
{
- if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
+ Q_UNUSED(orientation);
+
+ if (role == Qt::DisplayRole) {
switch (section) {
case ParentGroup:
return tr("Group");
@@ -201,8 +295,26 @@ QVariant EntryModel::headerData(int section, Qt::Orientation orientation, int ro
return tr("Title");
case Username:
return tr("Username");
+ case Password:
+ return tr("Password");
case Url:
return tr("URL");
+ case Notes:
+ return tr("Notes");
+ case Expires:
+ return tr("Expires");
+ case Created:
+ return tr("Created");
+ case Modified:
+ return tr("Modified");
+ case Accessed:
+ return tr("Accessed");
+ case Attachments:
+ return tr("Attachments");
+ }
+ } else if (role == Qt::DecorationRole) {
+ if (section == Paperclip) {
+ return m_paperClipPixmap;
}
}
@@ -223,8 +335,7 @@ Qt::ItemFlags EntryModel::flags(const QModelIndex& modelIndex) const
{
if (!modelIndex.isValid()) {
return Qt::NoItemFlags;
- }
- else {
+ } else {
return QAbstractItemModel::flags(modelIndex) | Qt::ItemIsDragEnabled;
}
}
@@ -265,8 +376,7 @@ QMimeData* EntryModel::mimeData(const QModelIndexList& indexes) const
if (seenEntries.isEmpty()) {
delete data;
return nullptr;
- }
- else {
+ } else {
data->setData(mimeTypes().at(0), encoded);
return data;
}
@@ -338,3 +448,58 @@ void EntryModel::makeConnections(const Group* group)
connect(group, SIGNAL(entryRemoved(Entry*)), SLOT(entryRemoved()));
connect(group, SIGNAL(entryDataChanged(Entry*)), SLOT(entryDataChanged(Entry*)));
}
+
+/**
+ * Get current state of 'Hide Usernames' setting
+ */
+bool EntryModel::isUsernamesHidden() const
+{
+ return m_hideUsernames;
+}
+
+/**
+ * Set state of 'Hide Usernames' setting and signal change
+ */
+void EntryModel::setUsernamesHidden(const bool hide)
+{
+ m_hideUsernames = hide;
+ emit usernamesHiddenChanged();
+}
+
+/**
+ * Get current state of 'Hide Passwords' setting
+ */
+bool EntryModel::isPasswordsHidden() const
+{
+ return m_hidePasswords;
+}
+
+/**
+ * Set state of 'Hide Passwords' setting and signal change
+ */
+void EntryModel::setPasswordsHidden(const bool hide)
+{
+ m_hidePasswords = hide;
+ emit passwordsHiddenChanged();
+}
+
+/**
+ * Toggle state of 'Hide Usernames' setting
+ */
+void EntryModel::toggleUsernamesHidden(const bool hide)
+{
+ setUsernamesHidden(hide);
+}
+
+/**
+ * Toggle state of 'Hide Passwords' setting
+ */
+void EntryModel::togglePasswordsHidden(const bool hide)
+{
+ setPasswordsHidden(hide);
+}
+
+void EntryModel::setPaperClipPixmap(const QPixmap& paperclip)
+{
+ m_paperClipPixmap = paperclip;
+}