2
* Copyright (C) 2015 David Wu <lightvector@gmail.com>
3
* Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
5
* This program is free software: you can redistribute it and/or modify
6
* it under the terms of the GNU General Public License as published by
7
* the Free Software Foundation, either version 2 or (at your option)
8
* version 3 of the License.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program. If not, see <http://www.gnu.org/licenses/>.
19
#include "AutoTypeMatchModel.h"
23
#include "core/Entry.h"
24
#include "core/Global.h"
25
#include "core/Group.h"
26
#include "core/Metadata.h"
27
#include "gui/DatabaseIcons.h"
30
AutoTypeMatchModel::AutoTypeMatchModel(QObject* parent)
31
: QAbstractTableModel(parent)
35
AutoTypeMatch AutoTypeMatchModel::matchFromIndex(const QModelIndex& index) const
37
Q_ASSERT(index.isValid() && index.row() < m_matches.size());
38
return m_matches.at(index.row());
41
QModelIndex AutoTypeMatchModel::indexFromMatch(const AutoTypeMatch& match) const
43
int row = m_matches.indexOf(match);
48
QModelIndex AutoTypeMatchModel::closestIndexFromMatch(const AutoTypeMatch& match) const
52
for (int i = m_matches.size() - 1; i >= 0; --i) {
53
const auto& currentMatch = m_matches.at(i);
54
if (currentMatch.first == match.first) {
57
if (currentMatch.second == match.second) {
63
return (row > -1) ? index(row, 1) : QModelIndex();
66
void AutoTypeMatchModel::setMatchList(const QList<AutoTypeMatch>& matches)
75
QSet<Database*> databases;
77
for (AutoTypeMatch& match : m_matches) {
78
databases.insert(match.first->group()->database());
81
for (Database* db : asConst(databases)) {
83
for (const Group* group : db->rootGroup()->groupsRecursive(true)) {
84
m_allGroups.append(group);
87
if (db->metadata()->recycleBin()) {
88
m_allGroups.removeOne(db->metadata()->recycleBin());
92
for (const Group* group : asConst(m_allGroups)) {
93
makeConnections(group);
99
int AutoTypeMatchModel::rowCount(const QModelIndex& parent) const
101
if (parent.isValid()) {
104
return m_matches.size();
107
int AutoTypeMatchModel::columnCount(const QModelIndex& parent) const
113
QVariant AutoTypeMatchModel::data(const QModelIndex& index, int role) const
115
if (!index.isValid()) {
119
AutoTypeMatch match = matchFromIndex(index);
121
if (role == Qt::DisplayRole) {
122
switch (index.column()) {
124
if (match.first->group()) {
125
return match.first->group()->name();
129
return match.first->resolveMultiplePlaceholders(match.first->title());
131
return match.first->resolveMultiplePlaceholders(match.first->username());
135
} else if (role == Qt::DecorationRole) {
136
switch (index.column()) {
138
if (match.first->group()) {
139
return Icons::groupIconPixmap(match.first->group());
143
return Icons::entryIconPixmap(match.first);
145
} else if (role == Qt::FontRole) {
147
if (match.first->isExpired()) {
148
font.setStrikeOut(true);
156
QVariant AutoTypeMatchModel::headerData(int section, Qt::Orientation orientation, int role) const
158
if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
165
return tr("Username");
167
return tr("Sequence");
174
void AutoTypeMatchModel::entryDataChanged(Entry* entry)
176
for (int row = 0; row < m_matches.size(); ++row) {
177
AutoTypeMatch match = m_matches[row];
178
if (match.first == entry) {
179
emit dataChanged(index(row, 0), index(row, columnCount() - 1));
184
void AutoTypeMatchModel::entryAboutToRemove(Entry* entry)
186
for (int row = 0; row < m_matches.size(); ++row) {
187
AutoTypeMatch match = m_matches[row];
188
if (match.first == entry) {
189
beginRemoveRows(QModelIndex(), row, row);
190
m_matches.removeAt(row);
197
void AutoTypeMatchModel::entryRemoved()
201
void AutoTypeMatchModel::severConnections()
203
for (const Group* group : asConst(m_allGroups)) {
204
disconnect(group, nullptr, this, nullptr);
208
void AutoTypeMatchModel::makeConnections(const Group* group)
210
connect(group, SIGNAL(entryAboutToRemove(Entry*)), SLOT(entryAboutToRemove(Entry*)));
211
connect(group, SIGNAL(entryRemoved(Entry*)), SLOT(entryRemoved()));
212
connect(group, SIGNAL(entryDataChanged(Entry*)), SLOT(entryDataChanged(Entry*)));