source: SMSSender/src/ui/completers/bettercompleter.cpp @ 67:578192d6fe64

3.0
Last change on this file since 67:578192d6fe64 was 43:10dd65d71f7f, checked in by Sämy Zehnder <saemy.zehnder@…>, 13 years ago
  • Did a lot of work...
File size: 4.8 KB
Line 
1/*
2 * BetterCompleter.cpp
3 *
4 *  Created on: Jan 16, 2010
5 *      Author: saemy
6 */
7
8#include "bettercompleter.h"
9
10BetterCompletionModel::BetterCompletionModel(QObject* parent)
11    : QSortFilterProxyModel(parent)
12    , isValid_(false)
13    , searchMatcher_(QString(), Qt::CaseInsensitive, QRegExp::FixedString)
14{
15    setDynamicSortFilter(true);
16}
17
18QVariant BetterCompletionModel::data(const QModelIndex& index, int role) const {
19    // if we are valid, tell QCompleter that everything we have filtered matches
20    // what the user typed; if not, nothing matches
21    if (role == BetterCompletionRole && index.isValid()) {
22        if (isValid())
23            return QLatin1String("a");
24        else
25            return QLatin1String("b");
26    }
27
28    return QSortFilterProxyModel::data(index, role);
29}
30
31QRegExp BetterCompletionModel::searchMatcher() const {
32    return searchMatcher_;
33}
34
35QString BetterCompletionModel::searchString() const {
36    return searchString_;
37}
38
39void BetterCompletionModel::setFilterFixedString (const QString& pattern) {
40    QSortFilterProxyModel::setFilterFixedString(pattern);
41
42    setSearchString(pattern);
43}
44
45void BetterCompletionModel::setSearchString(const QString& str) {
46    if (str == searchString_)
47        return;
48
49    searchString_ = str;
50    searchMatcher_.setPattern(str);
51
52    invalidateFilter();
53}
54
55bool BetterCompletionModel::isValid() const {
56    return isValid_;
57}
58
59void BetterCompletionModel::setValid(bool b) {
60    if (b == isValid_)
61        return;
62
63    isValid_ = b;
64
65    // tell the AccountCompleter that we've changed
66    emit dataChanged(index(0, 0), index(columnCount() - 1, rowCount() - 1));
67}
68
69bool BetterCompletionModel::filterAcceptsRow(int source_row, const QModelIndex& source_parent) const {
70    // do a case-insensitive substring match against the filterKeyColumns;
71    // we have also made sure that the user doesn't accidentally use regexp
72    // metacharacters
73    QList<QModelIndex> modelIndices;
74    int filterColumn = filterKeyColumn();
75    if (filterColumn == -1) {
76        for (int i = 0; i < sourceModel()->columnCount(source_parent); i++) {
77            modelIndices.append(sourceModel()->index(source_row, i, source_parent));
78        }
79    } else {
80        modelIndices.append(sourceModel()->index(source_row, filterColumn, source_parent));
81    }
82
83    foreach (QModelIndex index, modelIndices) {
84        QString field = sourceModel()->data(index, Qt::DisplayRole).toString();
85        if (searchMatcher_.indexIn(field) != -1)
86            return true;
87    }
88
89    return false;
90}
91
92
93
94
95BetterCompleter::BetterCompleter(QObject* parent)
96    : QCompleter(parent)
97{
98    init();
99}
100
101BetterCompleter::BetterCompleter(QAbstractItemModel* m, QObject* parent)
102    : QCompleter(m, parent)
103{
104    init();
105}
106
107void BetterCompleter::init() {
108    // we want to complete against our own faked role
109    setCompletionRole(BetterCompletionModel::BetterCompletionRole);
110
111    // and since we fake our completion role, we can take
112    // advantage of the sorted-model optimizations in QCompleter
113    setCaseSensitivity(Qt::CaseSensitive);
114    setModelSorting(QCompleter::CaseSensitivelySortedModel);
115
116    filterTimer_.setSingleShot(true);
117    connect(&filterTimer_, SIGNAL(timeout()), this, SLOT(updateFilter()));
118}
119
120QString BetterCompleter::pathFromIndex(const QModelIndex& index) const {
121    // we want to return the actual name from the account for the
122    // data the QCompleter finally returns
123    return model()->data(index, Qt::DisplayRole).toString();
124}
125
126QStringList BetterCompleter::splitPath(const QString& path) const {
127    if (path == searchString_)
128        return QStringList() << QLatin1String("a");
129
130    // queue an update to our search string
131    // We will wait a bit so that if the user is quickly typing,
132    // we don't try to complete until they pause.
133    if (filterTimer_.isActive())
134        filterTimer_.stop();
135    filterTimer_.start(150);
136
137    // if the previous search results are not a superset of
138    // the current search results, tell the model that it is not valid yet
139    if (!path.startsWith(searchString_)) {
140        BetterCompletionModel* completionModel = qobject_cast<BetterCompletionModel*>(model());
141        Q_ASSERT(completionModel);
142        completionModel->setValid(false);
143    }
144
145    searchString_ = path;
146
147    // the actual filtering is done by the BetterCompletionModel; we just
148    // return a short dummy here so that QCompleter thinks we match everything
149    return QStringList() << QLatin1String("a");
150}
151
152void BetterCompleter::updateFilter() {
153    BetterCompletionModel* completionModel = qobject_cast<BetterCompletionModel*>(model());
154    Q_ASSERT(completionModel);
155
156    // tell the BetterCompletionModel about the new search string
157    completionModel->setSearchString(searchString_);
158
159    // sort the model
160    completionModel->sort(0);
161
162    // mark it valid
163    completionModel->setValid(true);
164
165    // and now update the QCompleter widget
166    complete();
167}
Note: See TracBrowser for help on using the repository browser.