keepassxc

Форк
0
/
AutoTypeMatchView.cpp 
149 строк · 4.9 Кб
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 "AutoTypeMatchView.h"
20
#include "AutoTypeMatchModel.h"
21
#include "core/Entry.h"
22

23
#include <QHeaderView>
24
#include <QKeyEvent>
25
#include <QSortFilterProxyModel>
26

27
class CustomSortFilterProxyModel : public QSortFilterProxyModel
28
{
29
public:
30
    explicit CustomSortFilterProxyModel(QObject* parent = nullptr)
31
        : QSortFilterProxyModel(parent){};
32
    ~CustomSortFilterProxyModel() override = default;
33

34
    // Only search the first three columns (ie, ignore sequence column)
35
    bool filterAcceptsRow(int sourceRow, const QModelIndex& sourceParent) const override
36
    {
37
        auto index0 = sourceModel()->index(sourceRow, 0, sourceParent);
38
        auto index1 = sourceModel()->index(sourceRow, 1, sourceParent);
39
        auto index2 = sourceModel()->index(sourceRow, 2, sourceParent);
40

41
        return sourceModel()->data(index0).toString().contains(filterRegExp())
42
               || sourceModel()->data(index1).toString().contains(filterRegExp())
43
               || sourceModel()->data(index2).toString().contains(filterRegExp());
44
    }
45
};
46

47
AutoTypeMatchView::AutoTypeMatchView(QWidget* parent)
48
    : QTableView(parent)
49
    , m_model(new AutoTypeMatchModel(this))
50
    , m_sortModel(new CustomSortFilterProxyModel(this))
51
{
52
    m_sortModel->setSourceModel(m_model);
53
    m_sortModel->setDynamicSortFilter(true);
54
    m_sortModel->setSortLocaleAware(true);
55
    m_sortModel->setSortCaseSensitivity(Qt::CaseInsensitive);
56
    m_sortModel->setFilterKeyColumn(-1);
57
    m_sortModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
58
    setModel(m_sortModel);
59

60
    sortByColumn(0, Qt::AscendingOrder);
61

62
    setContextMenuPolicy(Qt::CustomContextMenu);
63

64
    connect(this, &QTableView::doubleClicked, this, [this](const QModelIndex& index) {
65
        emit matchActivated(matchFromIndex(index));
66
    });
67
}
68

69
void AutoTypeMatchView::keyPressEvent(QKeyEvent* event)
70
{
71
    if ((event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return) && currentIndex().isValid()) {
72
        emit matchActivated(matchFromIndex(currentIndex()));
73
    } else if (event->key() == Qt::Key_PageUp) {
74
        moveSelection(-5);
75
    } else if (event->key() == Qt::Key_PageDown) {
76
        moveSelection(5);
77
    } else {
78
        QTableView::keyPressEvent(event);
79
    }
80
}
81

82
void AutoTypeMatchView::setMatchList(const QList<AutoTypeMatch>& matches)
83
{
84
    m_model->setMatchList(matches);
85
    m_sortModel->setFilterWildcard({});
86

87
    horizontalHeader()->resizeSections(QHeaderView::ResizeToContents);
88

89
    selectionModel()->clear();
90
    emit currentMatchChanged(currentMatch());
91
}
92

93
void AutoTypeMatchView::selectFirstMatch()
94
{
95
    selectionModel()->setCurrentIndex(m_sortModel->index(0, 0),
96
                                      QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
97
    emit currentMatchChanged(currentMatch());
98
}
99

100
bool AutoTypeMatchView::selectMatch(const AutoTypeMatch& match)
101
{
102
    QModelIndex index = m_model->closestIndexFromMatch(match);
103

104
    if (index.isValid()) {
105
        selectionModel()->setCurrentIndex(m_sortModel->mapFromSource(index),
106
                                          QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
107
        emit currentMatchChanged(currentMatch());
108
        return true;
109
    }
110

111
    return false;
112
}
113

114
void AutoTypeMatchView::filterList(const QString& filter)
115
{
116
    m_sortModel->setFilterWildcard(filter);
117
    setCurrentIndex(m_sortModel->index(0, 0));
118
}
119

120
void AutoTypeMatchView::moveSelection(int offset)
121
{
122
    auto index = currentIndex();
123
    auto row = index.isValid() ? index.row() : -1;
124
    selectRow(qBound(0, row + offset, model()->rowCount() - 1));
125
}
126

127
AutoTypeMatch AutoTypeMatchView::currentMatch()
128
{
129
    QModelIndexList list = selectionModel()->selectedRows();
130
    if (list.size() == 1) {
131
        return m_model->matchFromIndex(m_sortModel->mapToSource(list.first()));
132
    }
133
    return {};
134
}
135

136
AutoTypeMatch AutoTypeMatchView::matchFromIndex(const QModelIndex& index)
137
{
138
    if (index.isValid()) {
139
        return m_model->matchFromIndex(m_sortModel->mapToSource(index));
140
    }
141
    return {};
142
}
143

144
void AutoTypeMatchView::currentChanged(const QModelIndex& current, const QModelIndex& previous)
145
{
146
    auto match = matchFromIndex(current);
147
    emit currentMatchChanged(match);
148
    QTableView::currentChanged(current, previous);
149
}
150

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

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

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

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