summaryrefslogtreecommitdiff
path: root/boardmodel.cpp
blob: 98c63024ba83930d4bf0d3ec07c3446c430ac94b (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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
#include <QtCore/QDebug>
#include <QtSql/QSqlError>

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

BoardModel::BoardModel(QObject *parent) :
    QAbstractListModel(parent), _board(0), _forumId(-1)
{
	QHash<int, QByteArray> roles = roleNames();
	roles[NameRole] = QByteArray("title");
	roles[LogoRole] = QByteArray("logo");
	roles[DescriptionRole] = QByteArray("description");
	roles[ForumIdRole] = QByteArray("forumId");
	roles[SubOnlyRole] = QByteArray("subOnly");
	roles[CategoryRole] = QByteArray("category");
	roles[UnreadRole] = QByteArray("unread");
	setRoleNames(roles);
}

Board * BoardModel::board() const
{
	return _board;
}

void BoardModel::setBoard(Board *board)
{
	if (_board != board) {
		disconnect(this, SLOT(reload()));
		disconnect(this, SLOT(handleForumChanged(int)));
		_board = board;
		if (_board) {
			connect(board, SIGNAL(forumsChanged()), SLOT(reload()));
			connect(board, SIGNAL(forumChanged(int)), SLOT(handleForumChanged(int)));
		}
		reload();
		emit boardChanged();
	}
}

int BoardModel::forumId() const
{
	return _forumId;
}

void BoardModel::setForumId(const int id)
{
	if (_forumId != id) {
		_forumId = id;
		reload();
		emit forumIdChanged();
	}
}

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 (!_board) return QVariant();
	if (!_query.seek(index.row())) {
		qWarning() << "Could not seek to" << index.row();
		return QVariant();
	}

	switch (role) {
	case ForumIdRole:
		return _query.value(0);
	case NameRole:
		return _query.value(1);
	case LogoRole:
		return _query.value(2);
	case DescriptionRole:
		return _query.value(3);
	case SubOnlyRole:
		return _query.value(4);
	case CategoryRole:
		return _query.value(5);
	case UnreadRole:
		return _query.value(6);
	}

	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::refresh()
{
	// Forcefully refresh the forums list
	if (_board) {
		_board->enqueueAction(new FetchForumsAction(_board));
	}
}

void BoardModel::markSubforumsRead()
{
	if (_forumId == 0 || _board->getConfig("mark_forum") == "1") {
		_board->enqueueAction(new MarkForumReadAction(_forumId, _board));
	} else {
		qWarning() << "Unsupported: marking specific subforum as read";
	}
}

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

	if (_board && _forumId >= 0) {
		_query = QSqlQuery(_board->database());
		_query.prepare("SELECT f1.forum_id,f1.forum_name,f1.logo_url,f1.description,f1.sub_only,f2.forum_name,f1.new_post AS cat_name FROM forums f1 "
					   "LEFT JOIN forums f2 ON f2.forum_id = f1.parent_id "
					   "WHERE (f1.parent_id=:parent_id_1 AND f1.sub_only = 0) OR f1.parent_id IN "
					   "(SELECT forum_id from forums WHERE parent_id=:parent_id_2 AND sub_only=1) "
					   "ORDER by f1.position ASC;");
		_query.bindValue(0, _forumId);
		_query.bindValue(1, _forumId);
		if (!_query.exec()) {
			qWarning() << "Coult not select forums: " << _query.lastError().text();
		}
	}

	endResetModel();
	fetchMore(); // So that at least a few rows are sent
}

void BoardModel::handleForumChanged(int forumId)
{
	Q_UNUSED(forumId);
	reload(); // TODO improve
}