summaryrefslogtreecommitdiff
path: root/boardmodel.cpp
blob: f8da74e3c842962811ca456f5399c550864903f9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#include <QtCore/QDebug>
#include <QtSql/QSqlError>

#include "global.h"
#include "board.h"
#include "boardmodel.h"

BoardModel::BoardModel(QObject *parent) :
    QAbstractListModel(parent),
    _rootForumId(0)
{
	QHash<int, QByteArray> roles = roleNames();
	roles[NameRole] = QByteArray("title");
	roles[LogoRole] = QByteArray("logo");
	roles[DescriptionRole] = QByteArray("description");
	roles[ForumIdRole] = QByteArray("forumId");
	roles[ParentIdRole] = QByteArray("parentId");
	roles[CategoryRole] = QByteArray("category");
	setRoleNames(roles);
}

QString BoardModel::boardUrl() const
{
	return _boardUrl;
}

void BoardModel::setBoardUrl(const QString &url)
{
	if (_boardUrl != url) {
		disconnect(this, SLOT(reload()));
		_boardUrl = url;
		reload();
		emit boardUrlChanged();
	}
}

int BoardModel::rootForumId() const
{
	return _rootForumId;
}

void BoardModel::setRootForumId(const int id)
{
	if (_rootForumId != id) {
		_rootForumId = id;
		reload();
		emit rootForumIdChanged();
	}
}

int BoardModel::rowCount(const QModelIndex &parent) const
{
	return parent.isValid() ? 0 : _records;
}

QVariant BoardModel::data(const QModelIndex &index, int role) const
{
	if (!index.isValid()) return QVariant();
	if (!_query.seek(index.row())) {
		qWarning() << "Could not seek to" << index.row();
		return QVariant();
	}

	switch (role) {
	case NameRole:
		return _query.value(1);
		break;
	case DescriptionRole:
		return _query.value(4);
		break;
	case ForumIdRole:
		return _query.value(0);
		break;
	case CategoryRole:
		return _query.value(5);
		break;
	}

	return QVariant();
}

bool BoardModel::canFetchMore(const QModelIndex &parent) const
{
	return parent.isValid() || !_query.isValid() ? false : !_eof;
}

void BoardModel::fetchMore(const QModelIndex &parent)
{
	if (parent.isValid()) return;
	if (_eof) return;

	const int prefetch_count = 20;
	int new_num_records;
	if (_query.seek(_records + prefetch_count)) {
		new_num_records = _query.at() + 1;
	} else if (_query.previous()) {
		// We hit the last record and just went back
		new_num_records = _query.at() + 1;
		_eof = true;
	} else {
		// There are no records or other error
		new_num_records = 0;
		_eof = true;
	}


	if (new_num_records <= 0) {
		return; // No records!
	} else if (new_num_records > _records) {
		beginInsertRows(QModelIndex(), _records, new_num_records - 1);
		_records = new_num_records;
		endInsertRows();
	}
}

void BoardModel::reload()
{
	beginResetModel();
	_eof = false;
	_records = 0;
	_query.clear();

	if (!_boardUrl.isEmpty()) {
		Board *board = board_manager->getBoard(_boardUrl);
		connect(board, SIGNAL(forumsChanged()), SLOT(reload()));
		_query = QSqlQuery(board->database());
		_query.prepare("SELECT f1.forum_id,f1.forum_name,f1.parent_id,f1.logo_url,f1.description,f2.forum_name AS cat_name FROM forums f1 "
					   "LEFT JOIN forums f2 ON f2.forum_id = f1.parent_id "
					   "WHERE f1.sub_only=0 AND (f1.parent_id=:parent_id_1 OR f1.parent_id IN "
					   "  (SELECT forum_id from forums WHERE parent_id=:parent_id_2 AND sub_only=1)) "
					   "ORDER by f1.sort_index ASC;");
		_query.bindValue(0, _rootForumId);
		_query.bindValue(1, _rootForumId);
		if (!_query.exec()) {
			qWarning() << "Coult not select forums: " << _query.lastError().text();
		}
	}

	endResetModel();
	fetchMore();
}