#include #include #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 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 }