27
28
#include <QtCore/QStringList>
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
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.
39
HistoryHostListModel::HistoryHostListModel(QObject* parent)
40
HistoryDomainListModel::HistoryDomainListModel(QObject* parent)
40
41
: QAbstractListModel(parent)
45
HistoryHostListModel::~HistoryHostListModel()
46
HistoryDomainListModel::~HistoryDomainListModel()
50
QHash<int, QByteArray> HistoryHostListModel::roleNames() const
51
QHash<int, QByteArray> HistoryDomainListModel::roleNames() const
52
53
static QHash<int, QByteArray> roles;
53
54
if (roles.isEmpty()) {
55
roles[Domain] = "domain";
55
56
roles[Thumbnail] = "thumbnail";
56
57
roles[Entries] = "entries";
61
int HistoryHostListModel::rowCount(const QModelIndex& parent) const
62
int HistoryDomainListModel::rowCount(const QModelIndex& parent) const
64
return m_hosts.count();
65
return m_domains.count();
67
QVariant HistoryHostListModel::data(const QModelIndex& index, int role) const
68
QVariant HistoryDomainListModel::data(const QModelIndex& index, int role) const
69
70
if (!index.isValid()) {
72
73
int row = index.row();
73
if ((row < 0) || (row >= m_hosts.count())) {
74
if ((row < 0) || (row >= m_domains.count())) {
76
const QString& host = m_hosts.keys().at(row);
77
const QString& domain = m_domains.keys().at(row);
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();
128
void HistoryHostListModel::clearHosts()
129
void HistoryDomainListModel::clearDomains()
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);
135
void HistoryHostListModel::populateModel()
136
void HistoryDomainListModel::populateModel()
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)) {
141
QString domain = getDomainFromSourceModel(m_sourceModel->index(i, 0));
142
if (!m_domains.contains(domain)) {
143
insertNewDomain(domain);
148
void HistoryHostListModel::onRowsInserted(const QModelIndex& parent, int start, int end)
149
void HistoryDomainListModel::onRowsInserted(const QModelIndex& parent, int start, int end)
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) {
162
163
beginInsertRows(QModelIndex(), insertAt, insertAt);
164
insertNewDomain(domain);
166
updated.append(host);
167
updated.append(domain);
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);
177
void HistoryHostListModel::onRowsRemoved(const QModelIndex& parent, int start, int end)
178
void HistoryDomainListModel::onRowsRemoved(const QModelIndex& parent, int start, int end)
179
180
Q_UNUSED(parent);
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)));
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);
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);
202
void HistoryHostListModel::onModelReset()
203
void HistoryDomainListModel::onModelReset()
204
205
beginResetModel();
210
void HistoryHostListModel::insertNewHost(const QString& host)
211
void HistoryDomainListModel::insertNewDomain(const QString& domain)
212
HistoryHostModel* model = new HistoryHostModel(this);
213
HistoryDomainModel* model = new HistoryDomainModel(this);
213
214
model->setSourceModel(m_sourceModel);
214
QString key = host.isNull() ? "" : host;
216
m_hosts.insert(key, model);
215
model->setDomain(domain);
216
m_domains.insert(domain, model);
219
QString HistoryHostListModel::getHostFromSourceModel(const QModelIndex& index) const
219
QString HistoryDomainListModel::getDomainFromSourceModel(const QModelIndex& index) const
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();