From 5d8d6fed3fd7dd796a5a3093a7dbd46fab8d380a Mon Sep 17 00:00:00 2001 From: "Javier S. Pedro" Date: Thu, 4 Apr 2013 00:00:38 +0200 Subject: pass Board objects instead of boardUrls around QML --- board.cpp | 82 +++++++++++++++++++++++++++++++++++++++----- board.h | 41 +++++++++++++++++++--- boardmanager.cpp | 18 ++++++---- boardmanager.h | 5 +-- boardmodel.cpp | 52 ++++++++++++++++------------ boardmodel.h | 24 +++++++------ favoritesmodel.cpp | 2 +- favoritesmodel.h | 5 ++- fetchconfigaction.cpp | 1 + fetchforumsaction.cpp | 1 + fetchpostsaction.cpp | 1 + fetchtopicsaction.cpp | 1 + forummodel.cpp | 23 ++++++------- forummodel.h | 9 +++-- loginaction.cpp | 50 +++++++++++++++++++++++++++ loginaction.h | 28 +++++++++++++++ main.cpp | 4 +++ qml/tapasboard/BoardPage.qml | 14 ++++---- qml/tapasboard/ForumPage.qml | 6 ++-- qml/tapasboard/MainPage.qml | 7 ++-- qml/tapasboard/TopicPage.qml | 4 +-- tapasboard.pro | 6 ++-- topicmodel.cpp | 23 ++++++------- topicmodel.h | 9 +++-- 24 files changed, 313 insertions(+), 103 deletions(-) create mode 100644 loginaction.cpp create mode 100644 loginaction.h diff --git a/board.cpp b/board.cpp index 2df4711..1a82a91 100644 --- a/board.cpp +++ b/board.cpp @@ -12,8 +12,13 @@ const QLatin1String Board::CURRENT_DB_VERSION("testing2"); -Board::Board(const QString& forumUrl, QObject *parent) : - QObject(parent), _url(forumUrl), _slug(createSlug(forumUrl)), +Board::Board(QObject *parent) : + QObject(parent) +{ +} + +Board::Board(const QUrl& url, const QString& username, const QString& password, QObject *parent) : + QObject(parent), _url(url), _slug(createSlug(url)), _db(QSqlDatabase::addDatabase("QSQLITE", _slug)), _iface(new XmlRpcInterface(QUrl(_url), this)) { @@ -35,6 +40,9 @@ Board::Board(const QString& forumUrl, QObject *parent) : initializeDb(); } fetchConfigIfOutdated(); + if (!username.isEmpty()) { + login(username, password); + } fetchForumsIfOutdated(); initializeBbCode(); // TODO This might depend on board config initializeSmilies(); @@ -43,7 +51,9 @@ Board::Board(const QString& forumUrl, QObject *parent) : Board::~Board() { disconnect(this, SLOT(handleActionFinished(Action*))); - QSqlDatabase::removeDatabase(_slug); + if (!_slug.isEmpty()) { + QSqlDatabase::removeDatabase(_slug); + } } void Board::enqueueAction(Action *action) @@ -68,6 +78,7 @@ void Board::enqueueAction(Action *action) if (_queue.size() == 1) { // There were no actions queued, so start by executing this one. executeActionFromQueue(); + emit busyChanged(); } } @@ -98,7 +109,6 @@ QString Board::getConfig(const QString &key) const void Board::setConfig(const QString &key, const QString &value) { - // Try config cache first QHash::const_iterator i = _config.find(key); if (i != _config.end()) { @@ -121,6 +131,21 @@ void Board::setConfig(const QString &key, const QString &value) notifyConfigChanged(key); } +QVariant Board::getLoginInfo(const QString &key) const +{ + return _loginInfo[key]; +} + +void Board::login(const QString &username, const QString &password) +{ + // TODO +} + +void Board::logout() +{ + // TODO +} + QString Board::removeHtml(QString text) const { static const QRegExp regexp("<[a-zA-Z\\/][^>]*>"); @@ -187,6 +212,15 @@ QString Board::renderHumanTime(const QDateTime &dateTime) return dateTime.toLocalTime().time().toString(Qt::DefaultLocaleShortDate); } +void Board::cancelAllActions() +{ + disconnect(this, SLOT(handleActionFinished(Action*))); + while (!_queue.isEmpty()) { + Action *action = _queue.dequeue(); + delete action; + } +} + void Board::notifyConfigChanged(const QString& key) { if (!key.isEmpty()) { @@ -215,12 +249,33 @@ void Board::notifyTopicPostsChanged(int topicId, int start, int end) emit topicPostsChanged(topicId, start, end); } -QString Board::createSlug(const QString &forumUrl) +void Board::notifyLogin(const QMap &info) +{ + if (_loginInfo.empty()) { + _loginInfo = info; + qDebug() << "Now logged in as" << _loginInfo["username"].toString(); + emit loggedInChanged(); + } else { + // Double login? + _loginInfo = info; + } +} + +void Board::notifyLogout() +{ + if (!_loginInfo.empty()) { + _loginInfo.clear(); + emit loggedInChanged(); + } +} + +QString Board::createSlug(const QUrl& url) { static const QRegExp regexp("[^a-z0-9]+"); - QString url = forumUrl.toLower(); - url.replace(regexp, "_"); - return url; + QString slug = url.toString(QUrl::RemoveScheme | QUrl::RemoveUserInfo | QUrl::StripTrailingSlash); + slug = slug.toLower(); + slug.replace(regexp, "_"); + return slug; } QString Board::getDbPathFor(const QString &slug) @@ -242,6 +297,12 @@ bool Board::checkCompatibleDb() bool Board::initializeDb() { QSqlQuery q(_db); + + if (!q.exec("PRAGMA synchronous = OFF")) { + qWarning() << "Could not disable synchronous flag:" << q.lastError().text(); + // Not fatal + } + if (!q.exec("CREATE TABLE IF NOT EXISTS config (key TEXT PRIMARY KEY, value TEXT)")) { qWarning() << "Could not create config table:" << q.lastError().text(); return false; @@ -338,6 +399,11 @@ bool Board::removeFromActionQueue(Action *action) executeActionFromQueue(); } action->deleteLater(); + // Don't use delete here because this might be called in response to + // error() or finished() QNetworkReply signals. + if (_queue.isEmpty()) { + emit busyChanged(); + } return true; } return false; diff --git a/board.h b/board.h index deb1dfb..588219c 100644 --- a/board.h +++ b/board.h @@ -3,10 +3,11 @@ #include #include -#include #include #include #include +#include +#include #include class Action; @@ -15,22 +16,36 @@ class XmlRpcInterface; class Board : public QObject { Q_OBJECT + Q_PROPERTY(bool busy READ busy NOTIFY busyChanged) + Q_PROPERTY(bool loggedIn READ loggedIn NOTIFY loggedInChanged) + Q_PROPERTY(int rootForumId READ rootForumId CONSTANT) + public: - explicit Board(const QString& boardUrl, QObject *parent = 0); + explicit Board(QObject *parent = 0); + Board(const QUrl& url, const QString& username, const QString& password, QObject *parent = 0); ~Board(); static const QLatin1String CURRENT_DB_VERSION; bool busy() const; + void enqueueAction(Action* action); QSqlDatabase database(); XmlRpcInterface *service(); + int rootForumId() const; + // Configuration table QString getConfig(const QString& key) const; void setConfig(const QString& key, const QString &value); + // Login/logout stuff + QVariant getLoginInfo(const QString& key) const; + bool loggedIn() const; + void login(const QString& username, const QString& password); + void logout(); + // Some helper functions QString removeHtml(QString text) const; QString removeBbcode(QString text) const; @@ -40,20 +55,27 @@ public: QString renderHumanDate(const QDateTime& dateTime); QString renderHumanTime(const QDateTime& dateTime); +public slots: + void cancelAllActions(); + // These functions wrap emitting the signals below void notifyConfigChanged(const QString& key = QString()); void notifyForumsChanged(); void notifyForumTopicsChanged(int forumId, int start, int end); void notifyTopicPostsChanged(int topicId, int start, int end); + void notifyLogin(const QMap& info); + void notifyLogout(); signals: + void busyChanged(); + void loggedInChanged(); void configChanged(const QString& key); void forumsChanged(); void forumTopicsChanged(int forumId, int start, int end); void topicPostsChanged(int topicId, int start, int end); private: - static QString createSlug(const QString& forumUrl); + static QString createSlug(const QUrl& url); static QString getDbPathFor(const QString& slug); static QString getTempDbPathFor(const QString& slug); bool checkCompatibleDb(); @@ -72,13 +94,14 @@ private slots: void handleActionError(Action *action, const QString& message); private: - QString _url; + QUrl _url; QString _slug; QSqlDatabase _db; XmlRpcInterface *_iface; QQueue _queue; /** Configuration cache */ mutable QHash _config; + QMap _loginInfo; QList< QPair > _bbcodes; QHash _smilies; QRegExp _smilieRegexp; @@ -89,6 +112,16 @@ inline bool Board::busy() const return !_queue.empty(); } +inline bool Board::loggedIn() const +{ + return !_loginInfo.empty(); +} + +inline int Board::rootForumId() const +{ + return 0; +} + inline QSqlDatabase Board::database() { return _db; diff --git a/boardmanager.cpp b/boardmanager.cpp index 5fbcf07..ca4dad1 100644 --- a/boardmanager.cpp +++ b/boardmanager.cpp @@ -10,15 +10,21 @@ BoardManager::BoardManager(QObject *parent) : { } -Board* BoardManager::getBoard(const QString &url) +Board* BoardManager::getBoard(const QUrl &url, const QString& username, const QString& password) { - QHash::iterator i = _boards.find(url); + Board *b; + QHash::iterator i = _boards.find(url); if (i != _boards.end()) { - return i.value(); + b = i.value(); + if (!b->loggedIn() && !username.isEmpty()) { + // If requested to login but wasn't before, login now. + b->login(username, password); + } + } else { + b = new Board(url, username, password, this); + _boards.insert(url, b); } - Board *db = new Board(url, this); - _boards.insert(url, db); - return db; + return b; } QString BoardManager::getCachePath() const diff --git a/boardmanager.h b/boardmanager.h index 30ebafc..fcbfa3d 100644 --- a/boardmanager.h +++ b/boardmanager.h @@ -3,6 +3,7 @@ #include #include +#include class Board; @@ -12,12 +13,12 @@ class BoardManager : public QObject public: explicit BoardManager(QObject *parent = 0); - Board *getBoard(const QString& url); + Q_INVOKABLE Board *getBoard(const QUrl& url, const QString& username = QString(), const QString& password = QString()); QString getCachePath() const; private: - QHash _boards; + QHash _boards; }; diff --git a/boardmodel.cpp b/boardmodel.cpp index c2421f7..c8d8bd3 100644 --- a/boardmodel.cpp +++ b/boardmodel.cpp @@ -3,11 +3,11 @@ #include "global.h" #include "board.h" +#include "fetchforumsaction.h" #include "boardmodel.h" BoardModel::BoardModel(QObject *parent) : - QAbstractListModel(parent), - _rootForumId(0) + QAbstractListModel(parent), _board(0), _forumId(-1) { QHash roles = roleNames(); roles[NameRole] = QByteArray("title"); @@ -19,32 +19,35 @@ BoardModel::BoardModel(QObject *parent) : setRoleNames(roles); } -QString BoardModel::boardUrl() const +Board * BoardModel::board() const { - return _boardUrl; + return _board; } -void BoardModel::setBoardUrl(const QString &url) +void BoardModel::setBoard(Board *board) { - if (_boardUrl != url) { + if (_board != board) { disconnect(this, SLOT(reload())); - _boardUrl = url; + _board = board; + if (_board) { + connect(board, SIGNAL(forumsChanged()), SLOT(reload())); + } reload(); - emit boardUrlChanged(); + emit boardChanged(); } } -int BoardModel::rootForumId() const +int BoardModel::forumId() const { - return _rootForumId; + return _forumId; } -void BoardModel::setRootForumId(const int id) +void BoardModel::setForumId(const int id) { - if (_rootForumId != id) { - _rootForumId = id; + if (_forumId != id) { + _forumId = id; reload(); - emit rootForumIdChanged(); + emit forumIdChanged(); } } @@ -56,6 +59,7 @@ int BoardModel::rowCount(const QModelIndex &parent) const 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(); @@ -113,6 +117,13 @@ void BoardModel::fetchMore(const QModelIndex &parent) } } +void BoardModel::refresh() +{ + if (_board) { + _board->enqueueAction(new FetchForumsAction(_board)); + } +} + void BoardModel::reload() { beginResetModel(); @@ -120,22 +131,21 @@ void BoardModel::reload() _records = 0; _query.clear(); - if (!_boardUrl.isEmpty()) { - Board *board = board_manager->getBoard(_boardUrl); - connect(board, SIGNAL(forumsChanged()), SLOT(reload())); - _query = QSqlQuery(board->database()); + if (_board && _forumId >= 0) { + qDebug() << "Reloading" << _board << _forumId; + _query = QSqlQuery(_board->database()); _query.prepare("SELECT f1.forum_id,f1.forum_name,f1.logo_url,f1.description,f1.sub_only,f2.forum_name 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.sort_index ASC;"); - _query.bindValue(0, _rootForumId); - _query.bindValue(1, _rootForumId); + _query.bindValue(0, _forumId); + _query.bindValue(1, _forumId); if (!_query.exec()) { qWarning() << "Coult not select forums: " << _query.lastError().text(); } } endResetModel(); - fetchMore(); + fetchMore(); // So that at least a few rows are sent } diff --git a/boardmodel.h b/boardmodel.h index 3662642..56d127d 100644 --- a/boardmodel.h +++ b/boardmodel.h @@ -9,8 +9,8 @@ class Board; class BoardModel : public QAbstractListModel { Q_OBJECT - Q_PROPERTY(QString boardUrl READ boardUrl WRITE setBoardUrl NOTIFY boardUrlChanged) - Q_PROPERTY(int rootForumId READ rootForumId WRITE setRootForumId NOTIFY rootForumIdChanged) + Q_PROPERTY(Board * board READ board WRITE setBoard NOTIFY boardChanged) + Q_PROPERTY(int forumId READ forumId WRITE setForumId NOTIFY forumIdChanged) public: BoardModel(QObject *parent = 0); @@ -25,11 +25,11 @@ public: CategoryRole }; - QString boardUrl() const; - void setBoardUrl(const QString& url); + Board * board() const; + void setBoard(Board *board); - int rootForumId() const; - void setRootForumId(const int id); + int forumId() const; + void setForumId(const int id); int rowCount(const QModelIndex &parent = QModelIndex()) const; QVariant data(const QModelIndex &index, int role) const; @@ -37,16 +37,20 @@ public: bool canFetchMore(const QModelIndex &parent = QModelIndex()) const; void fetchMore(const QModelIndex &parent = QModelIndex()); +public slots: + void refresh(); + signals: - void boardUrlChanged(); - void rootForumIdChanged(); + void boardChanged(); + void forumIdChanged(); private slots: void reload(); private: - QString _boardUrl; - int _rootForumId; + Board *_board; + int _forumId; + mutable QSqlQuery _query; int _records; bool _eof; diff --git a/favoritesmodel.cpp b/favoritesmodel.cpp index de4bf2d..5c0f51a 100644 --- a/favoritesmodel.cpp +++ b/favoritesmodel.cpp @@ -55,7 +55,7 @@ void FavoritesModel::load() settings.setArrayIndex(i); FavoriteBoard board; board.name = settings.value("name").toString(); - board.url = settings.value("url").toString(); + board.url = settings.value("url").toUrl(); _boards.append(board); } settings.endArray(); diff --git a/favoritesmodel.h b/favoritesmodel.h index 59959d4..a18b1dc 100644 --- a/favoritesmodel.h +++ b/favoritesmodel.h @@ -2,6 +2,7 @@ #define FAVORITESMODEL_H #include +#include class FavoritesModel : public QAbstractListModel { @@ -22,7 +23,9 @@ public: protected: struct FavoriteBoard { QString name; - QString url; + QUrl url; + QString username; + QString password; }; private: diff --git a/fetchconfigaction.cpp b/fetchconfigaction.cpp index 8c0ac63..787810c 100644 --- a/fetchconfigaction.cpp +++ b/fetchconfigaction.cpp @@ -21,6 +21,7 @@ bool FetchConfigAction::isSupersetOf(Action *action) const void FetchConfigAction::execute() { _call = _board->service()->asyncCall("get_config"); + _call->setParent(this); connect(_call, SIGNAL(finished(XmlRpcPendingCall*)), SLOT(handleFinishedCall())); } diff --git a/fetchforumsaction.cpp b/fetchforumsaction.cpp index 7b496c3..53f1f12 100644 --- a/fetchforumsaction.cpp +++ b/fetchforumsaction.cpp @@ -22,6 +22,7 @@ bool FetchForumsAction::isSupersetOf(Action *action) const void FetchForumsAction::execute() { _call = _board->service()->asyncCall("get_forum"); + _call->setParent(this); connect(_call, SIGNAL(finished(XmlRpcPendingCall*)), SLOT(handleFinishedCall())); } diff --git a/fetchpostsaction.cpp b/fetchpostsaction.cpp index 7ed9140..0e4284b 100644 --- a/fetchpostsaction.cpp +++ b/fetchpostsaction.cpp @@ -30,6 +30,7 @@ void FetchPostsAction::execute() { _call = _board->service()->asyncCall("get_thread", QString::number(_topicId), _start, _end); + _call->setParent(this); connect(_call, SIGNAL(finished(XmlRpcPendingCall*)), SLOT(handleFinishedCall())); } diff --git a/fetchtopicsaction.cpp b/fetchtopicsaction.cpp index 31a507a..ead8d4d 100644 --- a/fetchtopicsaction.cpp +++ b/fetchtopicsaction.cpp @@ -30,6 +30,7 @@ void FetchTopicsAction::execute() { _call = _board->service()->asyncCall("get_topic", QString::number(_forumId), _start, _end); + _call->setParent(this); connect(_call, SIGNAL(finished(XmlRpcPendingCall*)), SLOT(handleFinishedCall())); } diff --git a/forummodel.cpp b/forummodel.cpp index c66d3a8..bdc2d17 100644 --- a/forummodel.cpp +++ b/forummodel.cpp @@ -8,7 +8,7 @@ #include "forummodel.h" ForumModel::ForumModel(QObject *parent) : - QAbstractListModel(parent), _boardUrl(), _board(0), _forumId(-1) + QAbstractListModel(parent), _board(0), _forumId(-1), _eof(false) { QHash roles = roleNames(); roles[TitleRole] = QByteArray("title"); @@ -17,21 +17,20 @@ ForumModel::ForumModel(QObject *parent) : setRoleNames(roles); } -QString ForumModel::boardUrl() const +Board * ForumModel::board() const { - return _boardUrl; + return _board; } -void ForumModel::setBoardUrl(const QString &url) +void ForumModel::setBoard(Board *board) { - if (_boardUrl != url) { + if (_board != board) { disconnect(this, SLOT(handleForumTopicsChanged(int,int,int))); clearModel(); - _board = 0; - _boardUrl = url; - if (!_boardUrl.isEmpty()) { - _board = board_manager->getBoard(_boardUrl); + _board = board; + + if (_board) { connect(_board, SIGNAL(forumTopicsChanged(int,int,int)), SLOT(handleForumTopicsChanged(int,int,int))); if (_forumId >= 0) { @@ -39,7 +38,7 @@ void ForumModel::setBoardUrl(const QString &url) reload(); } } - emit boardUrlChanged(); + emit boardChanged(); } } @@ -91,14 +90,14 @@ QVariant ForumModel::data(const QModelIndex &index, int role) const bool ForumModel::canFetchMore(const QModelIndex &parent) const { - if (parent.isValid() || !_board) return false; // Invalid state + if (parent.isValid() || !_board || _forumId < 0) return false; // Invalid state return !_eof; } void ForumModel::fetchMore(const QModelIndex &parent) { if (parent.isValid()) return; - if (!_board) return; + if (!_board || _forumId < 0) return; if (_eof) return; const int start = _data.size(); diff --git a/forummodel.h b/forummodel.h index 8cde5cf..5a84f64 100644 --- a/forummodel.h +++ b/forummodel.h @@ -10,7 +10,7 @@ class Board; class ForumModel : public QAbstractListModel { Q_OBJECT - Q_PROPERTY(QString boardUrl READ boardUrl WRITE setBoardUrl NOTIFY boardUrlChanged) + Q_PROPERTY(Board * board READ board WRITE setBoard NOTIFY boardChanged) Q_PROPERTY(int forumId READ forumId WRITE setForumId NOTIFY forumIdChanged) public: @@ -24,8 +24,8 @@ public: TopicTypeRole }; - QString boardUrl() const; - void setBoardUrl(const QString& url); + Board * board() const; + void setBoard(Board *board); int forumId() const; void setForumId(const int id); @@ -37,7 +37,7 @@ public: void fetchMore(const QModelIndex &parent = QModelIndex()); signals: - void boardUrlChanged(); + void boardChanged(); void forumIdChanged(); protected: @@ -61,7 +61,6 @@ private slots: void reload(); private: - QString _boardUrl; Board *_board; int _forumId; QList _data; diff --git a/loginaction.cpp b/loginaction.cpp new file mode 100644 index 0000000..445b812 --- /dev/null +++ b/loginaction.cpp @@ -0,0 +1,50 @@ +#include + +#include "board.h" +#include "xmlrpcinterface.h" +#include "xmlrpcreply.h" +#include "loginaction.h" + +LoginAction::LoginAction(const QString &name, const QString &password, Board *board) + : Action(board), _username(name), _password(password) +{ +} + +bool LoginAction::isSupersetOf(Action *action) const +{ + LoginAction *other = qobject_cast(action); + if (other) { + if (other->_username == _username && other->_password == _password) { + return true; + } + } + return false; +} + +void LoginAction::execute() +{ + qDebug() << "Sending login call.."; + _call = _board->service()->asyncCall("login", + _username.toUtf8(), _password.toUtf8()); + _call->setParent(this); + connect(_call, SIGNAL(finished(XmlRpcPendingCall*)), SLOT(handleFinishedCall())); +} + +void LoginAction::handleFinishedCall() +{ + XmlRpcReply result(_call); + if (result.isValid()) { + QVariantMap map = result; + bool login_ok = map["result"].toBool(); + if (login_ok) { + _board->notifyLogin(map); + } else { + qWarning() << "Could not login to board as:" << _username; + } + } else { + qWarning() << "Could not fetch posts"; + // TODO emit error ... + } + emit finished(this); + _call->deleteLater(); +} diff --git a/loginaction.h b/loginaction.h new file mode 100644 index 0000000..cedb910 --- /dev/null +++ b/loginaction.h @@ -0,0 +1,28 @@ +#ifndef LOGINACTION_H +#define LOGINACTION_H + +#include "action.h" + +class XmlRpcPendingCall; + +class LoginAction : public Action +{ + Q_OBJECT +public: + explicit LoginAction(const QString& name, const QString& password, Board *board); + + bool isSupersetOf(Action *action) const; + + void execute(); + +private slots: + void handleFinishedCall(); + +private: + XmlRpcPendingCall *_call; + QString _username; + QString _password; +}; + + +#endif // LOGINACTION_H diff --git a/main.cpp b/main.cpp index 52086e4..ccb6fbd 100644 --- a/main.cpp +++ b/main.cpp @@ -25,6 +25,9 @@ Q_DECL_EXPORT int main(int argc, char *argv[]) QScopedPointer image_nam_factory(new ImageNetworkAccessManagerFactory); + qmlRegisterUncreatableType("com.javispedro.tapasboard", 1, 0, "Board", + "BoardManager must be accessed through boardManager"); + qmlRegisterType("com.javispedro.tapasboard", 1, 0, "Board"); qmlRegisterType("com.javispedro.tapasboard", 1, 0, "FavoritesModel"); qmlRegisterType("com.javispedro.tapasboard", 1, 0, "BoardModel"); qmlRegisterType("com.javispedro.tapasboard", 1, 0, "ForumModel"); @@ -32,6 +35,7 @@ Q_DECL_EXPORT int main(int argc, char *argv[]) QmlApplicationViewer viewer; viewer.engine()->setNetworkAccessManagerFactory(image_nam_factory.data()); + viewer.rootContext()->setContextProperty("boardManager", board_manager); viewer.setOrientation(QmlApplicationViewer::ScreenOrientationAuto); viewer.setMainQmlFile(QLatin1String("qml/tapasboard/main.qml")); viewer.showExpanded(); diff --git a/qml/tapasboard/BoardPage.qml b/qml/tapasboard/BoardPage.qml index 4aeba79..dd1bd24 100644 --- a/qml/tapasboard/BoardPage.qml +++ b/qml/tapasboard/BoardPage.qml @@ -9,8 +9,8 @@ Page { anchors.leftMargin: UiConstants.DefaultMargin anchors.rightMargin: UiConstants.DefaultMargin - property string boardUrl; - property int rootForumId; + property Board board : null; + property int forumId; tools: ToolBarLayout { ToolIcon { @@ -25,8 +25,8 @@ Page { id: forumsView anchors.fill: parent model: BoardModel { - boardUrl: boardPage.boardUrl - rootForumId: boardPage.rootForumId + board: boardPage.board + forumId: boardPage.forumId } section.criteria: ViewSection.FullString section.property: "category" @@ -71,12 +71,12 @@ Page { onClicked: { if (model.subOnly) { pageStack.push(Qt.resolvedUrl("BoardPage.qml"), { - boardUrl: boardPage.boardUrl, - rootForumId: model.forumId + board: boardPage.board, + forumId: model.forumId }); } else { pageStack.push(Qt.resolvedUrl("ForumPage.qml"), { - boardUrl: boardPage.boardUrl, + board: boardPage.board, forumId: model.forumId }); } diff --git a/qml/tapasboard/ForumPage.qml b/qml/tapasboard/ForumPage.qml index 6e39fe2..18953cb 100644 --- a/qml/tapasboard/ForumPage.qml +++ b/qml/tapasboard/ForumPage.qml @@ -9,7 +9,7 @@ Page { anchors.leftMargin: UiConstants.DefaultMargin anchors.rightMargin: UiConstants.DefaultMargin - property string boardUrl; + property Board board: null; property int forumId; tools: ToolBarLayout { @@ -25,7 +25,7 @@ Page { id: topicsView anchors.fill: parent model: ForumModel { - boardUrl: forumPage.boardUrl + board: forumPage.board forumId: forumPage.forumId } delegate: EmptyListDelegate { @@ -56,7 +56,7 @@ Page { onClicked: { pageStack.push(Qt.resolvedUrl("TopicPage.qml"), { - boardUrl: forumPage.boardUrl, + board: forumPage.board, topicId: model.topicId }); } diff --git a/qml/tapasboard/MainPage.qml b/qml/tapasboard/MainPage.qml index de3240a..f94b505 100644 --- a/qml/tapasboard/MainPage.qml +++ b/qml/tapasboard/MainPage.qml @@ -21,9 +21,12 @@ Page { } onClicked: { + var board = boardManager.getBoard(model.boardUrl, + model.loginUsername, + model.loginPassword); pageStack.push(Qt.resolvedUrl("BoardPage.qml"), { - boardUrl: model.boardUrl, - rootForumId: 0 + board: board, + forumId: board.rootForumId }); } } diff --git a/qml/tapasboard/TopicPage.qml b/qml/tapasboard/TopicPage.qml index 805154f..ba132b5 100644 --- a/qml/tapasboard/TopicPage.qml +++ b/qml/tapasboard/TopicPage.qml @@ -9,7 +9,7 @@ Page { anchors.leftMargin: UiConstants.DefaultMargin anchors.rightMargin: UiConstants.DefaultMargin - property string boardUrl; + property Board board; property int topicId; tools: ToolBarLayout { @@ -25,7 +25,7 @@ Page { id: postsView anchors.fill: parent model: TopicModel { - boardUrl: topicPage.boardUrl + board: topicPage.board topicId: topicPage.topicId } section.property: "humanDate" diff --git a/tapasboard.pro b/tapasboard.pro index 8430ba0..1cba839 100644 --- a/tapasboard.pro +++ b/tapasboard.pro @@ -47,7 +47,8 @@ SOURCES += main.cpp \ fetchpostsaction.cpp \ favoritesmodel.cpp \ imagecache.cpp \ - imagenetworkaccessmanager.cpp + imagenetworkaccessmanager.cpp \ + loginaction.cpp HEADERS += \ action.h \ @@ -66,7 +67,8 @@ HEADERS += \ fetchpostsaction.h \ favoritesmodel.h \ imagecache.h \ - imagenetworkaccessmanager.h + imagenetworkaccessmanager.h \ + loginaction.h OTHER_FILES += \ qtc_packaging/debian_harmattan/rules \ diff --git a/topicmodel.cpp b/topicmodel.cpp index 0c7541e..965481f 100644 --- a/topicmodel.cpp +++ b/topicmodel.cpp @@ -8,7 +8,7 @@ #include "topicmodel.h" TopicModel::TopicModel(QObject *parent) : - QAbstractListModel(parent), _boardUrl(), _board(0), _topicId(-1) + QAbstractListModel(parent), _board(0), _topicId(-1), _eof(false) { QHash roles = roleNames(); roles[TitleRole] = QByteArray("title"); @@ -23,21 +23,20 @@ TopicModel::TopicModel(QObject *parent) : setRoleNames(roles); } -QString TopicModel::boardUrl() const +Board * TopicModel::board() const { - return _boardUrl; + return _board; } -void TopicModel::setBoardUrl(const QString &url) +void TopicModel::setBoard(Board *board) { - if (_boardUrl != url) { + if (_board != board) { disconnect(this, SLOT(handleTopicPostsChanged(int,int,int))); clearModel(); - _board = 0; - _boardUrl = url; - if (!_boardUrl.isEmpty()) { - _board = board_manager->getBoard(_boardUrl); + _board = board; + + if (_board) { connect(_board, SIGNAL(topicPostsChanged(int,int,int)), SLOT(handleTopicPostsChanged(int,int,int))); if (_topicId >= 0) { @@ -45,7 +44,7 @@ void TopicModel::setBoardUrl(const QString &url) reload(); } } - emit boardUrlChanged(); + emit boardChanged(); } } @@ -109,14 +108,14 @@ QVariant TopicModel::data(const QModelIndex &index, int role) const bool TopicModel::canFetchMore(const QModelIndex &parent) const { - if (parent.isValid() || !_board) return false; // Invalid state + if (parent.isValid() || !_board || _topicId < 0) return false; // Invalid state return !_eof; } void TopicModel::fetchMore(const QModelIndex &parent) { if (parent.isValid()) return; - if (!_board) return; + if (!_board || _topicId < 0) return; if (_eof) return; const int start = _data.size(); diff --git a/topicmodel.h b/topicmodel.h index 39dcdee..6f1e99f 100644 --- a/topicmodel.h +++ b/topicmodel.h @@ -10,7 +10,7 @@ class Board; class TopicModel : public QAbstractListModel { Q_OBJECT - Q_PROPERTY(QString boardUrl READ boardUrl WRITE setBoardUrl NOTIFY boardUrlChanged) + Q_PROPERTY(Board * board READ board WRITE setBoard NOTIFY boardChanged) Q_PROPERTY(int topicId READ topicId WRITE setTopicId NOTIFY topicIdChanged) public: @@ -29,8 +29,8 @@ public: HumanTimeRole }; - QString boardUrl() const; - void setBoardUrl(const QString& url); + Board * board() const; + void setBoard(Board * board); int topicId() const; void setTopicId(const int id); @@ -42,7 +42,7 @@ public: void fetchMore(const QModelIndex &parent = QModelIndex()); signals: - void boardUrlChanged(); + void boardChanged(); void topicIdChanged(); protected: @@ -69,7 +69,6 @@ private slots: void reload(); private: - QString _boardUrl; Board *_board; int _topicId; QList _data; -- cgit v1.2.3