~bfiller/webbrowser-app/fix-tab-tests-etc

« back to all changes in this revision

Viewing changes to src/Ubuntu/Components/Extras/Browser/history-domainlist-model.cpp

  • Committer: Tarmac
  • Author(s): Olivier Tilloy
  • Date: 2013-07-12 16:31:27 UTC
  • mfrom: (188.1.29 domain-name)
  • Revision ID: tarmac-20130712163127-1h0345ccp72kd223
Refactor the models to group history entries by domain name, not by host.

Approved by Bill Filler, PS Jenkins bot.

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
17
 */
18
18
 
19
 
#include "history-hostlist-model.h"
 
19
#include "domain-utils.h"
 
20
#include "history-domain-model.h"
 
21
#include "history-domainlist-model.h"
20
22
#include "history-model.h"
21
 
#include "history-host-model.h"
22
23
#include "history-timeframe-model.h"
23
24
#include "webthumbnail-utils.h"
24
25
 
27
28
#include <QtCore/QStringList>
28
29
 
29
30
/*!
30
 
    \class HistoryHostListModel
31
 
    \brief List model that exposes history entries grouped by host
 
31
    \class HistoryDomainListModel
 
32
    \brief List model that exposes history entries grouped by domain name
32
33
 
33
 
    HistoryHostListModel is a list model that exposes history entries from a
34
 
    HistoryTimeframeModel grouped by host. Each item in the list has three
35
 
    roles: 'host' for the host name, 'thumbnail' for a thumbnail picture of a
36
 
    page corresponding to this host, and 'entries' for the corresponding
37
 
    HistoryHostModel that contains all entries in this group.
 
34
    HistoryDomainListModel is a list model that exposes history entries from a
 
35
    HistoryTimeframeModel grouped by domain name. Each item in the list has
 
36
    three roles: 'domain' for the domain name, 'thumbnail' for a thumbnail
 
37
    picture of a page corresponding to this domain name, and 'entries' for the
 
38
    corresponding HistoryDomainModel that contains all entries in this group.
38
39
*/
39
 
HistoryHostListModel::HistoryHostListModel(QObject* parent)
 
40
HistoryDomainListModel::HistoryDomainListModel(QObject* parent)
40
41
    : QAbstractListModel(parent)
41
42
    , m_sourceModel(0)
42
43
{
43
44
}
44
45
 
45
 
HistoryHostListModel::~HistoryHostListModel()
 
46
HistoryDomainListModel::~HistoryDomainListModel()
46
47
{
47
 
    clearHosts();
 
48
    clearDomains();
48
49
}
49
50
 
50
 
QHash<int, QByteArray> HistoryHostListModel::roleNames() const
 
51
QHash<int, QByteArray> HistoryDomainListModel::roleNames() const
51
52
{
52
53
    static QHash<int, QByteArray> roles;
53
54
    if (roles.isEmpty()) {
54
 
        roles[Host] = "host";
 
55
        roles[Domain] = "domain";
55
56
        roles[Thumbnail] = "thumbnail";
56
57
        roles[Entries] = "entries";
57
58
    }
58
59
    return roles;
59
60
}
60
61
 
61
 
int HistoryHostListModel::rowCount(const QModelIndex& parent) const
 
62
int HistoryDomainListModel::rowCount(const QModelIndex& parent) const
62
63
{
63
64
    Q_UNUSED(parent);
64
 
    return m_hosts.count();
 
65
    return m_domains.count();
65
66
}
66
67
 
67
 
QVariant HistoryHostListModel::data(const QModelIndex& index, int role) const
 
68
QVariant HistoryDomainListModel::data(const QModelIndex& index, int role) const
68
69
{
69
70
    if (!index.isValid()) {
70
71
        return QVariant();
71
72
    }
72
73
    int row = index.row();
73
 
    if ((row < 0) || (row >= m_hosts.count())) {
 
74
    if ((row < 0) || (row >= m_domains.count())) {
74
75
        return QVariant();
75
76
    }
76
 
    const QString& host = m_hosts.keys().at(row);
 
77
    const QString& domain = m_domains.keys().at(row);
77
78
    switch (role) {
78
 
    case Host:
79
 
        return host;
 
79
    case Domain:
 
80
        return domain;
80
81
    case Thumbnail:
81
82
    {
82
83
        // Iterate over all the entries, and return the first valid thumbnail.
83
 
        HistoryHostModel* entries = m_hosts.value(host);
 
84
        HistoryDomainModel* entries = m_domains.value(domain);
84
85
        int count = entries->rowCount();
85
86
        for (int i = 0; i < count; ++i) {
86
87
            QUrl url = entries->data(entries->index(i, 0), HistoryModel::Url).toUrl();
92
93
        return QUrl();
93
94
    }
94
95
    case Entries:
95
 
        return QVariant::fromValue(m_hosts.value(host));
 
96
        return QVariant::fromValue(m_domains.value(domain));
96
97
    default:
97
98
        return QVariant();
98
99
    }
99
100
}
100
101
 
101
 
HistoryTimeframeModel* HistoryHostListModel::sourceModel() const
 
102
HistoryTimeframeModel* HistoryDomainListModel::sourceModel() const
102
103
{
103
104
    return m_sourceModel;
104
105
}
105
106
 
106
 
void HistoryHostListModel::setSourceModel(HistoryTimeframeModel* sourceModel)
 
107
void HistoryDomainListModel::setSourceModel(HistoryTimeframeModel* sourceModel)
107
108
{
108
109
    if (sourceModel != m_sourceModel) {
109
110
        beginResetModel();
110
111
        if (m_sourceModel != 0) {
111
112
            m_sourceModel->disconnect(this);
112
113
        }
113
 
        clearHosts();
 
114
        clearDomains();
114
115
        m_sourceModel = sourceModel;
115
116
        populateModel();
116
117
        if (m_sourceModel != 0) {
125
126
    }
126
127
}
127
128
 
128
 
void HistoryHostListModel::clearHosts()
 
129
void HistoryDomainListModel::clearDomains()
129
130
{
130
 
    Q_FOREACH(const QString& host, m_hosts.keys()) {
131
 
        delete m_hosts.take(host);
 
131
    Q_FOREACH(const QString& domain, m_domains.keys()) {
 
132
        delete m_domains.take(domain);
132
133
    }
133
134
}
134
135
 
135
 
void HistoryHostListModel::populateModel()
 
136
void HistoryDomainListModel::populateModel()
136
137
{
137
138
    if (m_sourceModel != 0) {
138
139
        int count = m_sourceModel->rowCount();
139
140
        for (int i = 0; i < count; ++i) {
140
 
            QString host = getHostFromSourceModel(m_sourceModel->index(i, 0));
141
 
            if (!m_hosts.contains(host)) {
142
 
                insertNewHost(host);
 
141
            QString domain = getDomainFromSourceModel(m_sourceModel->index(i, 0));
 
142
            if (!m_domains.contains(domain)) {
 
143
                insertNewDomain(domain);
143
144
            }
144
145
        }
145
146
    }
146
147
}
147
148
 
148
 
void HistoryHostListModel::onRowsInserted(const QModelIndex& parent, int start, int end)
 
149
void HistoryDomainListModel::onRowsInserted(const QModelIndex& parent, int start, int end)
149
150
{
150
151
    QStringList updated;
151
152
    for (int i = start; i <= end; ++i) {
152
 
        QString host = getHostFromSourceModel(m_sourceModel->index(i, 0, parent));
153
 
        if (!m_hosts.contains(host)) {
154
 
            QStringList hosts = m_hosts.keys();
 
153
        QString domain = getDomainFromSourceModel(m_sourceModel->index(i, 0, parent));
 
154
        if (!m_domains.contains(domain)) {
 
155
            QStringList domains = m_domains.keys();
155
156
            int insertAt = 0;
156
 
            while (insertAt < hosts.count()) {
157
 
                if (host.compare(hosts.at(insertAt)) < 0) {
 
157
            while (insertAt < domains.count()) {
 
158
                if (domain.compare(domains.at(insertAt)) < 0) {
158
159
                    break;
159
160
                }
160
161
                ++insertAt;
161
162
            }
162
163
            beginInsertRows(QModelIndex(), insertAt, insertAt);
163
 
            insertNewHost(host);
 
164
            insertNewDomain(domain);
164
165
            endInsertRows();
165
166
        } else {
166
 
            updated.append(host);
 
167
            updated.append(domain);
167
168
        }
168
169
    }
169
170
    QVector<int> updatedRoles = QVector<int>() << Thumbnail << Entries;
170
 
    QStringList hosts = m_hosts.keys();
171
 
    Q_FOREACH(const QString& host, updated) {
172
 
        QModelIndex index = this->index(hosts.indexOf(host), 0);
 
171
    QStringList domains = m_domains.keys();
 
172
    Q_FOREACH(const QString& domain, updated) {
 
173
        QModelIndex index = this->index(domains.indexOf(domain), 0);
173
174
        Q_EMIT dataChanged(index, index, updatedRoles);
174
175
    }
175
176
}
176
177
 
177
 
void HistoryHostListModel::onRowsRemoved(const QModelIndex& parent, int start, int end)
 
178
void HistoryDomainListModel::onRowsRemoved(const QModelIndex& parent, int start, int end)
178
179
{
179
180
    Q_UNUSED(parent);
180
181
    Q_UNUSED(start);
181
182
    Q_UNUSED(end);
182
 
    QSet<QString> newHosts;
 
183
    QSet<QString> newDomains;
183
184
    int count = m_sourceModel->rowCount();
184
185
    for (int i = 0; i < count; ++i) {
185
 
        newHosts.insert(getHostFromSourceModel(m_sourceModel->index(i, 0)));
 
186
        newDomains.insert(getDomainFromSourceModel(m_sourceModel->index(i, 0)));
186
187
    }
187
 
    QSet<QString> removed = QSet<QString>::fromList(m_hosts.keys());
188
 
    removed.subtract(newHosts);
189
 
    Q_FOREACH(const QString& host, removed) {
190
 
        int removeAt = m_hosts.keys().indexOf(host);
 
188
    QSet<QString> removed = QSet<QString>::fromList(m_domains.keys());
 
189
    removed.subtract(newDomains);
 
190
    Q_FOREACH(const QString& domain, removed) {
 
191
        int removeAt = m_domains.keys().indexOf(domain);
191
192
        beginRemoveRows(QModelIndex(), removeAt, removeAt);
192
 
        delete m_hosts.take(host);
 
193
        delete m_domains.take(domain);
193
194
        endRemoveRows();
194
195
    }
195
 
    // XXX: unfortunately there is no way to get a list of hosts that had some
 
196
    // XXX: unfortunately there is no way to get a list of domains that had some
196
197
    // (but not all) entries removed. To ensure the views are correctly updated,
197
198
    // let’s emit the signal for all entries, even those that haven’t changed.
198
199
    Q_EMIT dataChanged(this->index(0, 0), this->index(rowCount() - 1, 0),
199
200
                       QVector<int>() << Thumbnail << Entries);
200
201
}
201
202
 
202
 
void HistoryHostListModel::onModelReset()
 
203
void HistoryDomainListModel::onModelReset()
203
204
{
204
205
    beginResetModel();
205
 
    clearHosts();
 
206
    clearDomains();
206
207
    populateModel();
207
208
    endResetModel();
208
209
}
209
210
 
210
 
void HistoryHostListModel::insertNewHost(const QString& host)
 
211
void HistoryDomainListModel::insertNewDomain(const QString& domain)
211
212
{
212
 
    HistoryHostModel* model = new HistoryHostModel(this);
 
213
    HistoryDomainModel* model = new HistoryDomainModel(this);
213
214
    model->setSourceModel(m_sourceModel);
214
 
    QString key = host.isNull() ? "" : host;
215
 
    model->setHost(key);
216
 
    m_hosts.insert(key, model);
 
215
    model->setDomain(domain);
 
216
    m_domains.insert(domain, model);
217
217
}
218
218
 
219
 
QString HistoryHostListModel::getHostFromSourceModel(const QModelIndex& index) const
 
219
QString HistoryDomainListModel::getDomainFromSourceModel(const QModelIndex& index) const
220
220
{
221
 
    return m_sourceModel->data(index, HistoryModel::Url).toUrl().host().toLower();
 
221
    QUrl url = m_sourceModel->data(index, HistoryModel::Url).toUrl();
 
222
    return DomainUtils::extractTopLevelDomainName(url).toLower();
222
223
}