proper loading indicator, now directly managed via the c++ networkaccess manager => no ugly qml code with flags or counters :)

This commit is contained in:
Hauke Schade 2013-07-26 19:36:59 +02:00
parent c5750d8b6f
commit 8bf5c1305b
10 changed files with 82 additions and 67 deletions

View file

@ -31,8 +31,8 @@ Q_DECL_EXPORT int main(int argc, char *argv[])
QmlApplicationViewer viewer;
//QObject::connect(viewer.engine(), SIGNAL(quit()), viewer.data, SLOT(close()));
viewer.setNetworkAccessManagerFactory(new MyNetworkManager);
viewer.setNetworkAccessManagerFactory(MyNetworkManager::instance());
viewer.rootContext()->setContextProperty("network", MyNetworkManager::instance());
viewer.rootContext()->setContextProperty("APP_VERSION", APP_VERSION);

View file

@ -13,11 +13,22 @@
#include <QtNetwork/QNetworkDiskCache>
#include <QDesktopServices>
QScopedPointer<MyNetworkManager> MyNetworkManager::m_instance(0);
MyNetworkManager *MyNetworkManager::instance() {
if (m_instance.isNull())
m_instance.reset(new MyNetworkManager);
m_instance->_numRequests = 0;
return m_instance.data();
}
QNetworkAccessManager* MyNetworkManager::create(QObject *parent) {
QNetworkAccessManager *nam = new MyNetworkAccessManager(parent);
connect(nam, SIGNAL(sslErrors(QNetworkReply*,QList<QSslError>)), this, SLOT(onSslErrors(QNetworkReply*,QList<QSslError>)));
// connect(nam, SIGNAL(finished(QNetworkReply*)), this, SLOT(onReplyFinished(QNetworkReply*)));
connect(nam, SIGNAL(finished(QNetworkReply*)), this, SLOT(onReplyFinished(QNetworkReply*)));
connect(nam, SIGNAL(started()), this, SLOT(onStarted()));
QNetworkDiskCache* diskCache = new QNetworkDiskCache(parent);
diskCache->setCacheDirectory(QDesktopServices::storageLocation(QDesktopServices::CacheLocation));
@ -28,6 +39,7 @@ QNetworkAccessManager* MyNetworkManager::create(QObject *parent) {
}
QNetworkReply *MyNetworkAccessManager::createRequest( QNetworkAccessManager::Operation op, const QNetworkRequest & req, QIODevice * outgoingData) {
this->started();
QNetworkRequest request(req);
request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache);
return QNetworkAccessManager::createRequest(op, request, outgoingData);
@ -38,6 +50,18 @@ void MyNetworkManager::onSslErrors(QNetworkReply *reply, const QList<QSslError>
reply->ignoreSslErrors(errors);
}
void MyNetworkManager::onStarted() {
_numRequests++;
if (_numRequests > 0)
loadingChanged();
}
void MyNetworkManager::onReplyFinished(QNetworkReply *reply) {
_numRequests--;
if (_numRequests == 0)
loadingChanged();
}
//void MyNetworkManager::onReplyFinished(QNetworkReply *reply) {
// Q_ASSERT(reply);
// if (!reply)

View file

@ -20,18 +20,37 @@ class MyNetworkManager : public QObject, public QDeclarativeNetworkAccessManager
{
Q_OBJECT
Q_PROPERTY(bool loading READ loading NOTIFY loadingChanged)
public: // QDeclarativeNetworkAccessManagerFactory
QNetworkAccessManager *create(QObject *parent);
static MyNetworkManager *instance();
bool loading() const {
return this->_numRequests > 0;
}
signals:
void loadingChanged();
private slots:
void onSslErrors(QNetworkReply *reply, const QList<QSslError> &errors);
// void onReplyFinished(QNetworkReply *reply);
void onReplyFinished(QNetworkReply *reply);
void onStarted();
private:
static QScopedPointer<MyNetworkManager> m_instance;
int _numRequests;
};
class MyNetworkAccessManager : public QNetworkAccessManager {
Q_OBJECT
public:
MyNetworkAccessManager(QObject *parent = 0) : QNetworkAccessManager(parent) { }
signals:
void started();
protected:
QNetworkReply *createRequest(Operation op, const QNetworkRequest &request, QIODevice *outgoingData = 0);

View file

@ -19,6 +19,7 @@ Item{
property string text
property string logourl: ''
property bool hasUpdateAction: false
property bool busy: false
signal updateActionActivated()
@ -78,20 +79,20 @@ Item{
Image {
id: updateIcon
source: "image://theme/icon-m-toolbar-refresh"
visible: hasUpdateAction&& rootWindow.loading <= 0
visible: hasUpdateAction && !network.loading && !busy
}
BusyIndicator {
id: busyIndicator
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
visible: rootWindow.loading > 0
running: rootWindow.loading > 0
visible: network.loading || busy
running: network.loading || busy
platformStyle: BusyIndicatorStyle { size: 'medium' }
}
MouseArea {
enabled: rootWindow.loading <= 0 && hasUpdateAction
enabled: !network.loading && !busy && hasUpdateAction
anchors.fill: parent
onClicked: {
root.updateActionActivated()

View file

@ -8,10 +8,8 @@ ListModel {
property int selectedIndex: -1
function update() {
rootWindow.loading++
var ttrss = rootWindow.getTTRSS();
ttrss.updateCategories(function() {
rootWindow.loading--
root.load();
});
}

View file

@ -26,8 +26,8 @@ Page {
property bool rss: false
property bool previousId: false
property bool nextId: false
property bool progressDidStop: true
property bool progressDidStart: false
// property bool progressDidStop: true
// property bool progressDidStart: false
anchors.margins: 0
@ -62,18 +62,18 @@ Page {
document.body.style.color='" + constant.colorWebviewText + "';\
");
}
onProgressChanged: {
if (progress < 1 && !progressDidStart) {
progressDidStop = false
progressDidStart = true
rootWindow.loading++
}
if (!progress < 1 && !progressDidStop) {
progressDidStop = true
progressDidStart = false
rootWindow.loading--
}
}
// onProgressChanged: {
// if (progress < 1 && !progressDidStart) {
// progressDidStop = false
// progressDidStart = true
// rootWindow.loading++
// }
// if (!progress < 1 && !progressDidStop) {
// progressDidStop = true
// progressDidStart = false
// rootWindow.loading--
// }
// }
onUrlChanged: {
if (url != "") {
@ -188,21 +188,21 @@ Page {
} }
ToolIcon {
iconSource: "resources/ic_star_"+(marked?"enabled":"disabled")+".png"
enabled: !rootWindow.loading
enabled: !network.loading
onClicked: {
feedItems.toggleStar()
marked = !marked
} }
ToolIcon {
iconSource: "resources/ic_rss_"+(rss?"enabled":"disabled")+".png"
enabled: !rootWindow.loading
enabled: !network.loading
onClicked: {
feedItems.togglePublished()
rss = !rss
} }
ToolIcon {
iconSource: "resources/ic_"+(unread?"unread":"read")+".png"
enabled: !rootWindow.loading
enabled: !network.loading
onClicked: {
feedItems.toggleRead()
unread = !unread
@ -217,7 +217,7 @@ Page {
ToolIcon {
iconId: "toolbar-view-menu" ;
onClicked: (itemMenu.status === DialogStatus.Closed) ? itemMenu.open() : itemMenu.close()
enabled: !rootWindow.loading
enabled: !network.loading
}
}

View file

@ -13,10 +13,8 @@ ListModel {
signal itemStarChanged(variant item)
function update() {
rootWindow.loading++
var ttrss = rootWindow.getTTRSS();
ttrss.updateFeedItems(feed.feedId, feed.isCat, function() {
rootWindow.loading--
root.load();
})
}
@ -77,46 +75,39 @@ ListModel {
function toggleRead() {
var ttrss = rootWindow.getTTRSS()
rootWindow.loading++
var m = root.get(root.selectedIndex)
ttrss.updateFeedUnread(m.id,
!m.unread,
function() {
root.setProperty(root.selectedIndex, "unread", !m.unread)
root.itemUnreadChanged(m)
rootWindow.loading--
})
}
function toggleStar() {
var ttrss = rootWindow.getTTRSS()
rootWindow.loading++
var m = root.get(root.selectedIndex)
ttrss.updateFeedStar(m.id,
!m.marked,
function() {
root.setProperty(root.selectedIndex, "marked", !m.marked)
root.itemStarChanged(m)
rootWindow.loading--
})
}
function togglePublished() {
var ttrss = rootWindow.getTTRSS()
rootWindow.loading++
var m = root.get(root.selectedIndex)
ttrss.updateFeedRSS(m.id,
!m.rss,
function() {
root.setProperty(root.selectedIndex, "rss", !m.rss)
root.itemPublishedChanged(m)
rootWindow.loading--
})
}
function catchUp() {
var ttrss = rootWindow.getTTRSS()
rootWindow.loading++
ttrss.catchUp(feed.feedId, function() {
for(var feeditem = 0; feeditem < root.count; feeditem++) {
var item = root.get(feeditem)
@ -125,7 +116,6 @@ ListModel {
root.itemUnreadChanged(item)
}
}
rootWindow.loading--
})
}

View file

@ -11,20 +11,17 @@ ListModel {
signal feedUnreadChanged(variant feed, int oldAmount)
function update() {
rootWindow.loading++
var ttrss = rootWindow.getTTRSS();
ttrss.updateFeeds(root.category.categoryId, function() {
rootWindow.loading--
root.load();
})
}
function load() {
var ttrss = rootWindow.getTTRSS();
var feeds = ttrss.getFeeds(category.categoryId);
var showAll = ttrss.getShowAll();
rootWindow.showAll = showAll;
root.clear();
var ttrss = rootWindow.getTTRSS()
var feeds = ttrss.getFeeds(category.categoryId)
rootWindow.showAll = ttrss.getShowAll()
root.clear()
if(feeds && feeds.length) {
//First add feed with unread items
@ -78,13 +75,11 @@ ListModel {
function catchUp() {
var ttrss = rootWindow.getTTRSS()
rootWindow.loading++
var m = root.getSelectedItem()
ttrss.catchUp(m.feedId, function() {
var oldAmount = m.unreadcount
root.setProperty(m, "unreadcount", 0)
root.feedUnreadChanged(m, oldAmount)
rootWindow.loading--
})
}

View file

@ -14,8 +14,6 @@ import com.nokia.meego 1.0
import "../components" 1.0
Page {
property bool loading: false
orientationLock: Screen.Portrait
tools: commonTools
@ -48,7 +46,7 @@ Page {
id: server
text: ""
width: parent.width
enabled: !loading
enabled: !network.loading
}
Label {
id: usernameLabel
@ -60,7 +58,7 @@ Page {
id: username
text: ""
width: parent.width
enabled: !loading
enabled: !network.loading
}
Label {
id: passwordLabel
@ -72,13 +70,13 @@ Page {
id: password
echoMode: TextInput.Password
width: parent.width
enabled: !loading
enabled: !network.loading
}
}
BusyIndicator {
id: busyindicator1
visible: loading
running: loading
visible: network.loading
running: network.loading
anchors {
horizontalCenter: parent.horizontalCenter
verticalCenter: parent.verticalCenter
@ -104,7 +102,7 @@ Page {
settings.username = username.text
settings.password = password.text
}
enabled: !loading
enabled: !network.loading
}
ToolButton {
id: loginButton
@ -127,14 +125,14 @@ Page {
startLogin();
}
enabled: !loading
enabled: !network.loading
}
ToolIcon {
id: menuButton
platformIconId: "toolbar-view-menu"
anchors.right: (parent === undefined) ? undefined : parent.right
onClicked: (myMenu.status === DialogStatus.Closed) ? myMenu.open() : myMenu.close()
enabled: !loading
enabled: !network.loading
}
}
@ -164,9 +162,6 @@ Page {
if (myMenu.status !== DialogStatus.Closed)
myMenu.close()
//Start the loading anim
loading = true;
var ttrss = rootWindow.getTTRSS();
ttrss.clearState();
ttrss.setLoginDetails(username.text, password.text, server.text);
@ -184,9 +179,6 @@ Page {
//login failed....don't autlogin
settings.autologin = false
//stop the loading anim
loading = false;
//Let the user know
loginErrorDialog.text = text;
loginErrorDialog.open();
@ -199,9 +191,6 @@ Page {
}
function configSuccessfull(retcode, text) {
//stop the loading anim
loading = false;
if(retcode) {
//Let the user know
loginErrorDialog.text = text;

View file

@ -33,7 +33,6 @@ PageStackWindow {
}
property bool showAll: false
property int loading: 0
Binding {
target: theme