summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--board.cpp12
-rw-r--r--board.h11
-rw-r--r--fetchtopicsaction.cpp47
-rw-r--r--fetchtopicsaction.h7
-rw-r--r--forummodel.cpp212
-rw-r--r--forummodel.h9
-rw-r--r--newtopicaction.cpp1
7 files changed, 226 insertions, 73 deletions
diff --git a/board.cpp b/board.cpp
index da469dc..26908b7 100644
--- a/board.cpp
+++ b/board.cpp
@@ -293,10 +293,10 @@ void Board::notifyForumChanged(int forumId)
emit forumChanged(forumId);
}
-void Board::notifyForumTopicsChanged(int forumId, int start, int end)
+void Board::notifyForumTopicsChanged(int forumId, TopicType type, int start, int end)
{
- qDebug() << "ForumTopics changed" << forumId << start << end;
- emit forumTopicsChanged(forumId, start, end);
+ qDebug() << "ForumTopics changed" << forumId << type << start << end;
+ emit forumTopicsChanged(forumId, type, start, end);
}
void Board::notifyForumTopicChanged(int forumId, int topicId)
@@ -415,7 +415,7 @@ bool Board::initializeDb()
return false;
}
- if (!q.exec("CREATE TABLE IF NOT EXISTS forums (forum_id INTEGER PRIMARY KEY, forum_name TEXT, description TEXT, parent_id INT, logo_url TEXT, new_post BOOL, is_protected BOOL, is_subscribed BOOL, can_subscribe BOOL, url TEXT, sub_only BOOL, position INT)")) {
+ if (!q.exec("CREATE TABLE IF NOT EXISTS forums (forum_id INTEGER PRIMARY KEY, forum_name TEXT, description TEXT, parent_id INTEGER, logo_url TEXT, new_post BOOL, is_protected BOOL, is_subscribed BOOL, can_subscribe BOOL, url TEXT, sub_only BOOL, position INT)")) {
qWarning() << "Could not create forums table:" << q.lastError().text();
return false;
}
@@ -428,7 +428,7 @@ bool Board::initializeDb()
return false;
}
- if (!q.exec("CREATE TABLE IF NOT EXISTS topics (forum_id INTEGER, topic_id INTEGER PRIMARY KEY, topic_title TEXT, topic_author_id INTEGER, topic_author_name TEXT, is_subscribed BOOL, is_closed BOOL, icon_url TEXT, last_reply_time TEXT, reply_number INT, new_post BOOL, position INT, last_update_time TEXT)")) {
+ if (!q.exec("CREATE TABLE IF NOT EXISTS topics (forum_id INTEGER, topic_id INTEGER PRIMARY KEY, topic_type INT, topic_title TEXT, topic_author_id INTEGER, topic_author_name TEXT, is_subscribed BOOL, is_closed BOOL, icon_url TEXT, last_reply_time TEXT, reply_number INT, new_post BOOL, position INT, last_update_time TEXT)")) {
qWarning() << "Could not create topics table:" << q.lastError().text();
return false;
}
@@ -440,7 +440,7 @@ bool Board::initializeDb()
qWarning() << "Could not create topics_time index:" << q.lastError().text();
return false;
}
- if (!q.exec("CREATE INDEX IF NOT EXISTS topics_order ON topics (forum_id, position ASC)")) {
+ if (!q.exec("CREATE INDEX IF NOT EXISTS topics_order ON topics (forum_id, topic_type DESC, position ASC)")) {
qWarning() << "Could not create topics_order index:" << q.lastError().text();
return false;
}
diff --git a/board.h b/board.h
index 81ee81f..d7e91a2 100644
--- a/board.h
+++ b/board.h
@@ -21,12 +21,19 @@ class Board : public QObject
Q_PROPERTY(bool busy READ busy NOTIFY busyChanged)
Q_PROPERTY(bool loggedIn READ loggedIn NOTIFY loggedInChanged)
Q_PROPERTY(int rootForumId READ rootForumId CONSTANT)
+ Q_ENUMS(TopicType)
public:
explicit Board(QObject *parent = 0);
Board(const QUrl& url, const QString& username, const QString& password, QObject *parent = 0);
~Board();
+ enum TopicType {
+ Normal = 0,
+ Sticky = 1,
+ Announcement = 2
+ };
+
static const QLatin1String CURRENT_DB_VERSION;
bool busy() const;
@@ -71,7 +78,7 @@ public slots:
void notifyConfigChanged(const QString& key = QString());
void notifyForumsChanged();
void notifyForumChanged(int forumId);
- void notifyForumTopicsChanged(int forumId, int start, int end);
+ void notifyForumTopicsChanged(int forumId, Board::TopicType type, int start, int end);
void notifyForumTopicChanged(int forumId, int topicId);
void notifyTopicPostsChanged(int topicId, int start, int end);
void notifyTopicPostsUnread(int topicId, int position);
@@ -87,7 +94,7 @@ signals:
void configChanged(const QString& key);
void forumsChanged();
void forumChanged(int forumId);
- void forumTopicsChanged(int forumId, int start, int end);
+ void forumTopicsChanged(int forumId, Board::TopicType type, int start, int end);
void forumTopicChanged(int forumId, int topicId);
void topicPostsChanged(int topicId, int start, int end);
void topicPostsUnread(int topicId, int position);
diff --git a/fetchtopicsaction.cpp b/fetchtopicsaction.cpp
index 4617280..1c6cc86 100644
--- a/fetchtopicsaction.cpp
+++ b/fetchtopicsaction.cpp
@@ -10,8 +10,9 @@
#include "xmlrpcreply.h"
#include "fetchtopicsaction.h"
-FetchTopicsAction::FetchTopicsAction(int forumId, int start, int end, Board *board) :
- Action(board), _forumId(forumId), _start(start), _end(end)
+FetchTopicsAction::FetchTopicsAction(int forumId, Board::TopicType type,
+ int start, int end, Board *board) :
+ Action(board), _forumId(forumId), _type(type), _start(start), _end(end)
{
}
@@ -19,7 +20,7 @@ bool FetchTopicsAction::isSupersetOf(Action *action) const
{
FetchTopicsAction *other = qobject_cast<FetchTopicsAction*>(action);
if (other) {
- if (other->_forumId == _forumId) {
+ if (other->_forumId == _forumId && other->_type == _type) {
if (_end == FetchAllTopics) {
// If this is fetching all topics, then this is a superset
// of every other action... except those that also fetch all
@@ -48,8 +49,27 @@ void FetchTopicsAction::execute()
// After finishing this action, a new one will be enqueued with the next 50.
}
- _call = _board->service()->asyncCall("get_topic",
- QString::number(_forumId), _start, end);
+ switch (_type) {
+ case Board::Normal:
+ _call = _board->service()->asyncCall("get_topic",
+ QString::number(_forumId),
+ _start, end);
+ break;
+ case Board::Sticky:
+ _call = _board->service()->asyncCall("get_topic",
+ QString::number(_forumId),
+ _start, end,
+ QString("TOP"));
+ break;
+ case Board::Announcement:
+ _call = _board->service()->asyncCall("get_topic",
+ QString::number(_forumId),
+ _start, end,
+ QString("ANN"));
+ break;
+ }
+ Q_ASSERT(_call);
+
_call->setParent(this);
connect(_call, SIGNAL(finished(XmlRpcPendingCall*)), SLOT(handleFinishedCall()));
}
@@ -77,8 +97,8 @@ void FetchTopicsAction::handleFinishedCall()
int position = _start;
QSqlQuery query(db);
- query.prepare("INSERT OR REPLACE INTO topics (forum_id, topic_id, topic_title, topic_author_id, topic_author_name, is_subscribed, is_closed, icon_url, last_reply_time, reply_number, new_post, position, last_update_time) "
- "VALUES (:forum_id, :topic_id, :topic_title, :topic_author_id, :topic_author_name, :is_subscribed, :is_closed, :icon_url, :last_reply_time, :reply_number, :new_post, :position, :last_update_time)");
+ query.prepare("INSERT OR REPLACE INTO topics (forum_id, topic_id, topic_type, topic_title, topic_author_id, topic_author_name, is_subscribed, is_closed, icon_url, last_reply_time, reply_number, new_post, position, last_update_time) "
+ "VALUES (:forum_id, :topic_id, :topic_type, :topic_title, :topic_author_id, :topic_author_name, :is_subscribed, :is_closed, :icon_url, :last_reply_time, :reply_number, :new_post, :position, :last_update_time)");
foreach (const QVariant& topic_v, topics) {
@@ -99,6 +119,7 @@ void FetchTopicsAction::handleFinishedCall()
query.bindValue(":forum_id", forum_id);
query.bindValue(":topic_id", topic_id);
+ query.bindValue(":topic_type", _type);
query.bindValue(":topic_title", decodeTopicText(topic["topic_title"]));
query.bindValue(":topic_author_id", topic["topic_author_id"].toInt());
query.bindValue(":topic_author_name", decodeTopicText(topic["topic_author_name"]));
@@ -128,8 +149,11 @@ void FetchTopicsAction::handleFinishedCall()
if (eof) {
// Service did not return as many topics as we expected, thus we
// can safely delete any topics after the current position.
- query.prepare("DELETE FROM topics WHERE forum_id = :forum_id AND position >= :position");
+ query.prepare("DELETE FROM topics "
+ "WHERE forum_id = :forum_id AND topic_type = :topic_type "
+ " AND position >= :position");
query.bindValue(":forum_id", _forumId);
+ query.bindValue(":topic_type", _type);
query.bindValue(":position", position);
if (query.exec()) {
position += query.numRowsAffected(); // Advance the position counter
@@ -173,7 +197,7 @@ void FetchTopicsAction::handleFinishedCall()
db.commit();
if (position > _start) {
- _board->notifyForumTopicsChanged(_forumId,
+ _board->notifyForumTopicsChanged(_forumId, _type,
_start, position - 1);
}
if (_end == FetchAllTopics && !eof) {
@@ -181,6 +205,7 @@ void FetchTopicsAction::handleFinishedCall()
// there are probably more of them
int next_start = fetched_end + 1;
_board->enqueueAction(new FetchTopicsAction(_forumId,
+ _type,
next_start,
FetchAllTopics,
_board));
@@ -204,9 +229,11 @@ QList<int> FetchTopicsAction::getCurrentDbTopics(int start, int end)
{
QSqlQuery query(_board->database());
query.prepare("SELECT topic_id FROM topics "
- "WHERE forum_id = :forum_id AND position BETWEEN :start AND :end "
+ "WHERE forum_id = :forum_id AND topic_type = :topic_type AND "
+ " position BETWEEN :start AND :end "
"ORDER by position ASC");
query.bindValue(":forum_id", _forumId);
+ query.bindValue(":topic_type", _type);
query.bindValue(":start", start);
query.bindValue(":end", end);
if (query.exec()) {
diff --git a/fetchtopicsaction.h b/fetchtopicsaction.h
index 307e528..f028ccb 100644
--- a/fetchtopicsaction.h
+++ b/fetchtopicsaction.h
@@ -3,6 +3,8 @@
#include <QtCore/QVariant>
#include <QtSql/QSqlQuery>
+
+#include "board.h"
#include "action.h"
class XmlRpcPendingCall;
@@ -11,12 +13,12 @@ class FetchTopicsAction : public Action
{
Q_OBJECT
public:
- explicit FetchTopicsAction(int forumId, int start, int end, Board *board);
-
enum {
FetchAllTopics = -1
};
+ explicit FetchTopicsAction(int forumId, Board::TopicType type, int start, int end, Board *board);
+
bool isSupersetOf(Action *action) const;
void execute();
@@ -31,6 +33,7 @@ private:
private:
XmlRpcPendingCall *_call;
int _forumId;
+ Board::TopicType _type;
int _start;
int _end;
};
diff --git a/forummodel.cpp b/forummodel.cpp
index ea54f8e..14f053f 100644
--- a/forummodel.cpp
+++ b/forummodel.cpp
@@ -8,7 +8,8 @@
#include "forummodel.h"
ForumModel::ForumModel(QObject *parent) :
- QAbstractListModel(parent), _board(0), _forumId(-1), _eof(false)
+ QAbstractListModel(parent), _board(0), _forumId(-1),
+ _numAnnouncements(0), _numSticky(0), _eof(false)
{
QHash<int, QByteArray> roles = roleNames();
roles[TitleRole] = QByteArray("title");
@@ -27,15 +28,15 @@ Board * ForumModel::board() const
void ForumModel::setBoard(Board *board)
{
if (_board != board) {
- disconnect(this, SLOT(handleForumTopicsChanged(int,int,int)));
+ disconnect(this, SLOT(handleForumTopicsChanged(int,Board::TopicType,int,int)));
disconnect(this, SLOT(handleForumTopicChanged(int,int)));
clearModel();
_board = board;
if (_board) {
- connect(_board, SIGNAL(forumTopicsChanged(int,int,int)),
- SLOT(handleForumTopicsChanged(int,int,int)));
+ connect(_board, SIGNAL(forumTopicsChanged(int,Board::TopicType,int,int)),
+ SLOT(handleForumTopicsChanged(int,Board::TopicType,int,int)));
connect(_board, SIGNAL(forumTopicChanged(int,int)),
SLOT(handleForumTopicChanged(int,int)));
if (_forumId >= 0) {
@@ -86,6 +87,8 @@ QVariant ForumModel::data(const QModelIndex &index, int role) const
return _data[row].title;
case TopicIdRole:
return _data[row].topic_id;
+ case TopicTypeRole:
+ return _data[row].type;
case NumRepliesRole:
return _data[row].num_replies;
case UnreadRole:
@@ -107,15 +110,18 @@ void ForumModel::fetchMore(const QModelIndex &parent)
if (!_board || _forumId < 0) return;
if (_eof) return;
- const int start = _data.size();
- QList<Topic> topics = loadTopics(start, start + FORUM_PAGE_SIZE - 1);
- const int new_end = start + topics.size() - 1;
+ const int normal_offset = _numAnnouncements + _numSticky;
+ const int normal_start = _data.size() - normal_offset;
+ QList<Topic> topics = loadTopics(Board::Normal,
+ normal_start, normal_start + FORUM_PAGE_SIZE - 1);
+ const int normal_new_end = normal_start + topics.size() - 1;
if (topics.empty()) {
// We could not load anything more from DB!
_eof = true;
} else {
- beginInsertRows(QModelIndex(), start, new_end);
+ beginInsertRows(QModelIndex(),
+ normal_offset + normal_start, normal_offset + normal_new_end);
_data.append(topics);
_eof = topics.size() < FORUM_PAGE_SIZE; // If short read, we reached EOF.
endInsertRows();
@@ -127,10 +133,11 @@ void ForumModel::fetchMore(const QModelIndex &parent)
// If the topics we got from DB are too old, refresh online.
if (last.secsTo(QDateTime::currentDateTimeUtc()) > FORUM_TOPICS_TLL) {
qDebug() << "Fetching topics because of old";
- Q_ASSERT(new_end >= 0);
+ Q_ASSERT(normal_new_end >= 0);
_board->enqueueAction(new FetchTopicsAction(_forumId,
- start,
- new_end,
+ Board::Normal,
+ normal_start,
+ normal_new_end,
_board));
}
}
@@ -138,9 +145,11 @@ void ForumModel::fetchMore(const QModelIndex &parent)
// Try to fetch more topics if board is online and we reached the end of DB
if (_eof) {
qDebug() << "Fetching topics because of EOF";
+ const int normal_cur_end = _data.size() - 1 - normal_offset;
_board->enqueueAction(new FetchTopicsAction(_forumId,
- _data.size(),
- _data.size() + FORUM_PAGE_SIZE - 1,
+ Board::Normal,
+ normal_cur_end + 1,
+ normal_cur_end + FORUM_PAGE_SIZE,
_board));
}
}
@@ -150,6 +159,17 @@ void ForumModel::refresh()
{
// Forcefully refresh all topics on this forum
_board->enqueueAction(new FetchTopicsAction(_forumId,
+ Board::Announcement,
+ 0,
+ FetchTopicsAction::FetchAllTopics,
+ _board));
+ _board->enqueueAction(new FetchTopicsAction(_forumId,
+ Board::Sticky,
+ 0,
+ FetchTopicsAction::FetchAllTopics,
+ _board));
+ _board->enqueueAction(new FetchTopicsAction(_forumId,
+ Board::Normal,
0,
FetchTopicsAction::FetchAllTopics,
_board));
@@ -178,10 +198,8 @@ QDateTime ForumModel::lastTopPostUpdate()
if (!_board) return QDateTime();
QSqlDatabase db = _board->database();
QSqlQuery query(db);
- query.prepare("SELECT last_update_time FROM topics "
- "WHERE forum_id = :forum_id "
- "ORDER BY position ASC "
- "LIMIT 1");
+ query.prepare("SELECT MIN(last_update_time) FROM topics "
+ "WHERE forum_id = :forum_id AND position = 0");
query.bindValue(":forum_id", _forumId);
if (query.exec()) {
if (query.next()) {
@@ -193,15 +211,16 @@ QDateTime ForumModel::lastTopPostUpdate()
return QDateTime();
}
-QList<ForumModel::Topic> ForumModel::loadTopics(int start, int end)
+QList<ForumModel::Topic> ForumModel::loadTopics(Board::TopicType type, int start, int end)
{
Q_ASSERT(_board);
QList<Topic> topics;
QSqlQuery query(_board->database());
- query.prepare("SELECT topic_id, topic_title, reply_number, new_post, last_reply_time, last_update_time FROM topics "
- "WHERE forum_id = :forum_id AND position BETWEEN :start AND :end "
+ query.prepare("SELECT topic_id, topic_type, topic_title, reply_number, new_post, last_reply_time, last_update_time FROM topics "
+ "WHERE forum_id = :forum_id AND topic_type = :topic_type AND position BETWEEN :start AND :end "
"ORDER by position ASC ");
query.bindValue(":forum_id", _forumId);
+ query.bindValue(":topic_type", type);
query.bindValue(":start", start);
query.bindValue(":end", end);
if (query.exec()) {
@@ -209,11 +228,12 @@ QList<ForumModel::Topic> ForumModel::loadTopics(int start, int end)
while (query.next()) {
Topic topic;
topic.topic_id = query.value(0).toInt();
- topic.title = query.value(1).toString();
- topic.num_replies = query.value(2).toInt();
- topic.unread = query.value(3).toBool();
- topic.last_reply_time = parseDateTime(query.value(4));
- topic.last_update_time = parseDateTime(query.value(5));
+ topic.type = type;
+ topic.title = query.value(2).toString();
+ topic.num_replies = query.value(3).toInt();
+ topic.unread = query.value(4).toBool();
+ topic.last_reply_time = parseDateTime(query.value(5));
+ topic.last_update_time = parseDateTime(query.value(6));
topics.append(topic);
}
} else {
@@ -230,66 +250,130 @@ void ForumModel::clearModel()
endResetModel();
}
-void ForumModel::handleForumTopicsChanged(int forumId, int start, int end)
+void ForumModel::handleForumTopicsChanged(int forumId, Board::TopicType type,
+ int start, int end)
{
- if (forumId == _forumId) {
+ if (forumId != _forumId) {
+ return; // Not our topics
+ }
+ if (type == Board::Normal) {
// Yep, our topics list changed.
+ const int normal_offset = _numAnnouncements + _numSticky;
+ int current_normal_end = _data.size() - 1 - normal_offset;
+
qDebug() << "My topics changed" << start << end;
- if (end > _data.size()) {
+
+ if (end >= current_normal_end) {
// If for any reason we have more topics now, it means we might
// no longer be EOF...
_eof = false;
}
- if (start > _data.size() + 1) {
- // We are still not interested into these topics.
+ if (start > current_normal_end + 1) {
+ // On the other hand, if the topics are too far away,
+ // do not load them until we fetchMore().
qDebug() << "Topics too far";
return;
}
- QList<Topic> topics = loadTopics(start, end);
+ QList<Topic> topics = loadTopics(Board::Normal, start, end);
if (topics.size() < end - start + 1) {
_eof = true; // Short read
end = start + topics.size() - 1;
- if (_data.size() > end + 1) {
- beginRemoveRows(QModelIndex(), end + 1, _data.size());
- while (_data.size() > end + 1) {
+ if (current_normal_end > end) {
+ const int current_full_end = _data.size() - 1;
+ const int new_full_end = end + normal_offset;
+
+ Q_ASSERT(new_full_end < current_full_end);
+ beginRemoveRows(QModelIndex(),
+ new_full_end, current_full_end);
+ while (_data.size() > new_full_end) {
_data.removeLast();
}
+ current_normal_end = _data.size() - 1 - normal_offset;
+ Q_ASSERT(current_normal_end == end);
endRemoveRows();
}
}
- if (end >= _data.size()) {
- qDebug() << "Call insert rows" << _data.size() << end;
- beginInsertRows(QModelIndex(), _data.size(), end);
- _data.reserve(end + 1);
- for (int i = start; i < _data.size(); i++) {
- _data[i] = topics[i - start];
+ if (end > current_normal_end) {
+ const int current_full_end = _data.size() - 1;
+ const int new_full_end = end + normal_offset;
+ qDebug() << "Insert rows" << current_full_end + 1 << new_full_end;
+ beginInsertRows(QModelIndex(), current_full_end + 1, new_full_end);
+ _data.reserve(new_full_end + 1);
+ const int full_start = normal_offset + start;
+ for (int i = full_start; i <= current_full_end; i++) {
+ _data[i] = topics[i - full_start];
}
- for (int i = _data.size(); i <= end; i++) {
- Q_ASSERT(i >= start);
- _data.append(topics[i - start]);
+ Q_ASSERT(current_full_end + 1 >= full_start);
+ for (int i = current_full_end + 1; i <= new_full_end; i++) {
+ _data.append(topics[i - full_start]);
}
endInsertRows();
- emit dataChanged(createIndex(start, 0), createIndex(_data.size() - 1, 0));
+ Q_ASSERT(new_full_end == _data.size() - 1);
+ emit dataChanged(createIndex(full_start, 0), createIndex(new_full_end, 0));
} else {
qDebug() << "Just refresh the data";
- for (int i = start; i < end; i++) {
- _data[i] = topics[i - start];
+ const int full_start = normal_offset + start;
+ const int full_end = normal_offset + end;
+ for (int i = full_start; i < full_end; i++) {
+ _data[i] = topics[i - full_start];
+ }
+ emit dataChanged(createIndex(full_start, 0), createIndex(full_end, 0));
+ }
+ } else if (type == Board::Sticky || type == Board::Announcement) {
+ // We just reload these fully
+ QList<Topic> topics = loadTopics(type, 0, MAX_FORUM_PAGE_SIZE - 1);
+ const int offset = type == Board::Sticky ? _numAnnouncements : 0;
+ int * const cur_number_p = type == Board::Sticky ? &_numSticky : &_numAnnouncements;
+ const int cur_number = *cur_number_p;
+
+ if (topics.size() < cur_number) {
+ const int cur_end = offset + cur_number - 1;
+ const int new_end = offset + topics.size() - 1;
+ beginRemoveRows(QModelIndex(), new_end + 1, cur_end);
+ for (int i = new_end + 1; i <= cur_end; i++) {
+ _data.removeAt(i);
+ (*cur_number_p)--;
+ }
+ endRemoveRows();
+ } else if (topics.size() > cur_number) {
+ const int cur_end = offset + cur_number - 1;
+ const int new_end = offset + topics.size() - 1;
+ const int new_start = cur_end + 1;
+ Q_ASSERT(new_end - offset == topics.size() - 1);
+ beginInsertRows(QModelIndex(), new_start, new_end);
+ for (int i = new_start; i <= new_end; i++) {
+ _data.insert(i, topics.takeAt(new_start - offset));
+ (*cur_number_p)++;
}
- emit dataChanged(createIndex(start, 0), createIndex(end, 0));
+ endInsertRows();
+ Q_ASSERT(topics.size() == cur_number);
+ }
+
+ const int start = offset;
+ const int end = offset + topics.size() - 1;
+ for (int i = start; i <= end; i++) {
+ _data.insert(i, topics.at(i - offset));
}
+ emit dataChanged(createIndex(start, 0), createIndex(end, 0));
}
}
void ForumModel::handleForumTopicChanged(int forumId, int topicId)
{
if (forumId == _forumId) {
+ Board::TopicType type = Board::Announcement;
+ int pos = 0;
for (int i = 0; i < _data.size(); i++) {
Topic& topic = _data[i];
+ if (topic.type != type) {
+ type = topic.type;
+ pos = 0;
+ }
if (topic.topic_id == topicId) {
// Need to refresh this topic
- QList<Topic> topics = loadTopics(i, i);
+ QList<Topic> topics = loadTopics(type, pos, pos);
if (topics.size() == 1) {
_data[i] = topics[0];
emit dataChanged(createIndex(i, 0), createIndex(i, 0));
@@ -297,6 +381,7 @@ void ForumModel::handleForumTopicChanged(int forumId, int topicId)
qWarning() << "Topic changed yet not in DB";
}
}
+ pos++;
}
}
}
@@ -311,7 +396,12 @@ void ForumModel::update()
last.secsTo(QDateTime::currentDateTimeUtc()) > FORUM_TOP_TLL) {
// Outdated or empty, refresh.
qDebug() << "Fetching topics because the top are old";
- _board->enqueueAction(new FetchTopicsAction(_forumId, 0, FORUM_PAGE_SIZE - 1, _board));
+ _board->enqueueAction(new FetchTopicsAction(_forumId, Board::Announcement,
+ 0, FORUM_PAGE_SIZE - 1, _board));
+ _board->enqueueAction(new FetchTopicsAction(_forumId, Board::Sticky,
+ 0, FORUM_PAGE_SIZE - 1, _board));
+ _board->enqueueAction(new FetchTopicsAction(_forumId, Board::Normal,
+ 0, FORUM_PAGE_SIZE - 1, _board));
} else {
qDebug() << "Topics not outdated";
}
@@ -321,6 +411,28 @@ void ForumModel::reload()
{
Q_ASSERT(_data.empty());
Q_ASSERT(!_eof);
- // Fetch an initial bunch of topics
+ // Load announcements / sticky topics fully
+ QList<Topic> topics;
+ topics = loadTopics(Board::Announcement, 0, MAX_FORUM_PAGE_SIZE - 1);
+ if (!topics.empty()) {
+ beginInsertRows(QModelIndex(), 0, topics.size() - 1);
+ _data.append(topics);
+ _numAnnouncements = topics.size();
+ endInsertRows();
+ } else {
+ _numAnnouncements = 0;
+ }
+
+ topics = loadTopics(Board::Sticky, 0, MAX_FORUM_PAGE_SIZE - 1);
+ if (!topics.empty()) {
+ beginInsertRows(QModelIndex(), _numAnnouncements, _numAnnouncements + topics.size() - 1);
+ _data.append(topics);
+ _numSticky = topics.size();
+ endInsertRows();
+ } else {
+ _numSticky = 0;
+ }
+
+ // Fetch an initial bunch of normal topics
fetchMore();
}
diff --git a/forummodel.h b/forummodel.h
index 33a718e..709f5c4 100644
--- a/forummodel.h
+++ b/forummodel.h
@@ -5,7 +5,7 @@
#include <QtCore/QDateTime>
#include <QtSql/QSqlQuery>
-class Board;
+#include "board.h"
class ForumModel : public QAbstractListModel
{
@@ -48,6 +48,7 @@ signals:
protected:
struct Topic {
int topic_id;
+ Board::TopicType type;
QString title;
int num_replies;
bool unread;
@@ -59,11 +60,11 @@ private:
static QDateTime parseDateTime(const QVariant& v);
static QDateTime oldestPostUpdate(const QList<Topic>& topics);
QDateTime lastTopPostUpdate();
- QList<Topic> loadTopics(int start, int end);
+ QList<Topic> loadTopics(Board::TopicType type, int start, int end);
void clearModel();
private slots:
- void handleForumTopicsChanged(int forumId, int start, int end);
+ void handleForumTopicsChanged(int forumId, Board::TopicType type, int start, int end);
void handleForumTopicChanged(int forumId, int topicId);
void update();
void reload();
@@ -72,6 +73,8 @@ private:
Board *_board;
int _forumId;
QList<Topic> _data;
+ int _numAnnouncements;
+ int _numSticky;
bool _eof;
};
diff --git a/newtopicaction.cpp b/newtopicaction.cpp
index b984c15..6d030e6 100644
--- a/newtopicaction.cpp
+++ b/newtopicaction.cpp
@@ -45,6 +45,7 @@ void NewTopicAction::handleFinishedCall()
} else {
// Refresh topics
_board->enqueueAction(new FetchTopicsAction(_forumId,
+ Board::Normal,
0,
FORUM_PAGE_SIZE,
_board));