keepassxc

Форк
0
/
AutoTypeMatchModel.cpp 
213 строк · 5.6 Кб
1
/*
2
 *  Copyright (C) 2015 David Wu <lightvector@gmail.com>
3
 *  Copyright (C) 2017 KeePassXC Team <team@keepassxc.org>
4
 *
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.
9
 *
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.
14
 *
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/>.
17
 */
18

19
#include "AutoTypeMatchModel.h"
20

21
#include <QFont>
22

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"
28
#include "gui/Icons.h"
29

30
AutoTypeMatchModel::AutoTypeMatchModel(QObject* parent)
31
    : QAbstractTableModel(parent)
32
{
33
}
34

35
AutoTypeMatch AutoTypeMatchModel::matchFromIndex(const QModelIndex& index) const
36
{
37
    Q_ASSERT(index.isValid() && index.row() < m_matches.size());
38
    return m_matches.at(index.row());
39
}
40

41
QModelIndex AutoTypeMatchModel::indexFromMatch(const AutoTypeMatch& match) const
42
{
43
    int row = m_matches.indexOf(match);
44
    Q_ASSERT(row != -1);
45
    return index(row, 1);
46
}
47

48
QModelIndex AutoTypeMatchModel::closestIndexFromMatch(const AutoTypeMatch& match) const
49
{
50
    int row = -1;
51

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) {
55
            row = i;
56

57
            if (currentMatch.second == match.second) {
58
                break;
59
            }
60
        }
61
    }
62

63
    return (row > -1) ? index(row, 1) : QModelIndex();
64
}
65

66
void AutoTypeMatchModel::setMatchList(const QList<AutoTypeMatch>& matches)
67
{
68
    beginResetModel();
69

70
    severConnections();
71

72
    m_allGroups.clear();
73
    m_matches = matches;
74

75
    QSet<Database*> databases;
76

77
    for (AutoTypeMatch& match : m_matches) {
78
        databases.insert(match.first->group()->database());
79
    }
80

81
    for (Database* db : asConst(databases)) {
82
        Q_ASSERT(db);
83
        for (const Group* group : db->rootGroup()->groupsRecursive(true)) {
84
            m_allGroups.append(group);
85
        }
86

87
        if (db->metadata()->recycleBin()) {
88
            m_allGroups.removeOne(db->metadata()->recycleBin());
89
        }
90
    }
91

92
    for (const Group* group : asConst(m_allGroups)) {
93
        makeConnections(group);
94
    }
95

96
    endResetModel();
97
}
98

99
int AutoTypeMatchModel::rowCount(const QModelIndex& parent) const
100
{
101
    if (parent.isValid()) {
102
        return 0;
103
    }
104
    return m_matches.size();
105
}
106

107
int AutoTypeMatchModel::columnCount(const QModelIndex& parent) const
108
{
109
    Q_UNUSED(parent);
110
    return 4;
111
}
112

113
QVariant AutoTypeMatchModel::data(const QModelIndex& index, int role) const
114
{
115
    if (!index.isValid()) {
116
        return {};
117
    }
118

119
    AutoTypeMatch match = matchFromIndex(index);
120

121
    if (role == Qt::DisplayRole) {
122
        switch (index.column()) {
123
        case ParentGroup:
124
            if (match.first->group()) {
125
                return match.first->group()->name();
126
            }
127
            break;
128
        case Title:
129
            return match.first->resolveMultiplePlaceholders(match.first->title());
130
        case Username:
131
            return match.first->resolveMultiplePlaceholders(match.first->username());
132
        case Sequence:
133
            return match.second;
134
        }
135
    } else if (role == Qt::DecorationRole) {
136
        switch (index.column()) {
137
        case ParentGroup:
138
            if (match.first->group()) {
139
                return Icons::groupIconPixmap(match.first->group());
140
            }
141
            break;
142
        case Title:
143
            return Icons::entryIconPixmap(match.first);
144
        }
145
    } else if (role == Qt::FontRole) {
146
        QFont font;
147
        if (match.first->isExpired()) {
148
            font.setStrikeOut(true);
149
        }
150
        return font;
151
    }
152

153
    return {};
154
}
155

156
QVariant AutoTypeMatchModel::headerData(int section, Qt::Orientation orientation, int role) const
157
{
158
    if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
159
        switch (section) {
160
        case ParentGroup:
161
            return tr("Group");
162
        case Title:
163
            return tr("Title");
164
        case Username:
165
            return tr("Username");
166
        case Sequence:
167
            return tr("Sequence");
168
        }
169
    }
170

171
    return {};
172
}
173

174
void AutoTypeMatchModel::entryDataChanged(Entry* entry)
175
{
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));
180
        }
181
    }
182
}
183

184
void AutoTypeMatchModel::entryAboutToRemove(Entry* entry)
185
{
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);
191
            endRemoveRows();
192
            --row;
193
        }
194
    }
195
}
196

197
void AutoTypeMatchModel::entryRemoved()
198
{
199
}
200

201
void AutoTypeMatchModel::severConnections()
202
{
203
    for (const Group* group : asConst(m_allGroups)) {
204
        disconnect(group, nullptr, this, nullptr);
205
    }
206
}
207

208
void AutoTypeMatchModel::makeConnections(const Group* group)
209
{
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*)));
213
}
214

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.