diff options
Diffstat (limited to 'akregator/src/fetchqueue.cpp')
-rw-r--r-- | akregator/src/fetchqueue.cpp | 160 |
1 files changed, 160 insertions, 0 deletions
diff --git a/akregator/src/fetchqueue.cpp b/akregator/src/fetchqueue.cpp new file mode 100644 index 000000000..5a3634304 --- /dev/null +++ b/akregator/src/fetchqueue.cpp @@ -0,0 +1,160 @@ +/* + This file is part of Akregator. + + Copyright (C) 2004 Sashmit Bhaduri <smt@vfemail.net> + 2005 Frank Osterfeld <frank.osterfeld at kdemail.net> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + As a special exception, permission is given to link this program + with any edition of Qt, and distribute the resulting executable, + without including the source code for Qt in the source distribution. +*/ + +#include <qvaluelist.h> + +#include "akregatorconfig.h" +#include "fetchqueue.h" +#include "feed.h" +#include "treenode.h" + + +namespace Akregator { + +class FetchQueue::FetchQueuePrivate +{ + public: + + QValueList<Feed*> queuedFeeds; + QValueList<Feed*> fetchingFeeds; +}; + + +FetchQueue::FetchQueue(QObject* parent, const char* name): QObject(parent, name), d(new FetchQueuePrivate) {} + + +FetchQueue::~FetchQueue() +{ + slotAbort(); + delete d; + d = 0; +} + +void FetchQueue::slotAbort() +{ + for (QValueList<Feed*>::Iterator it = d->fetchingFeeds.begin(); it != d->fetchingFeeds.end(); ++it) + { + disconnectFromFeed(*it); + (*it)->slotAbortFetch(); + } + d->fetchingFeeds.clear(); + + for (QValueList<Feed*>::Iterator it = d->queuedFeeds.begin(); it != d->queuedFeeds.end(); ++it) + { + disconnectFromFeed(*it); + } + d->queuedFeeds.clear(); + + emit signalStopped(); +} + +void FetchQueue::addFeed(Feed *f) +{ + if (!d->queuedFeeds.contains(f) && !d->fetchingFeeds.contains(f)) + { + connectToFeed(f); + d->queuedFeeds.append(f); + fetchNextFeed(); + } +} + +void FetchQueue::fetchNextFeed() +{ + if (!d->queuedFeeds.isEmpty() && d->fetchingFeeds.count() < Settings::concurrentFetches()) + { + if (d->fetchingFeeds.isEmpty() && d->queuedFeeds.count() == 1) + emit signalStarted(); + Feed* f = *(d->queuedFeeds.begin()); + d->queuedFeeds.pop_front(); + d->fetchingFeeds.append(f); + f->fetch(false); + + } +} + +void FetchQueue::slotFeedFetched(Feed *f) +{ + emit fetched(f); + feedDone(f); +} + +void FetchQueue::slotFetchError(Feed *f) +{ + emit fetchError(f); + feedDone(f); +} + +void FetchQueue::slotFetchAborted(Feed *f) +{ + emit fetched(f); // FIXME: better use a signal like signalAborted(Feed*) + feedDone(f); +} + +bool FetchQueue::isEmpty() const +{ + return d->queuedFeeds.isEmpty() && d->fetchingFeeds.isEmpty(); +} + +void FetchQueue::feedDone(Feed *f) +{ + disconnectFromFeed(f); + d->fetchingFeeds.remove(f); + if (isEmpty()) + emit signalStopped(); + else + fetchNextFeed(); +} + +void FetchQueue::connectToFeed(Feed* feed) +{ + connect (feed, SIGNAL(fetched(Feed*)), this, SLOT(slotFeedFetched(Feed*))); + connect (feed, SIGNAL(fetchError(Feed*)), this, SLOT(slotFetchError(Feed*))); + connect (feed, SIGNAL(fetchAborted(Feed*)), this, SLOT(slotFetchAborted(Feed*))); + connect (feed, SIGNAL(signalDestroyed(TreeNode*)), this, SLOT(slotNodeDestroyed(TreeNode*))); +} + +void FetchQueue::disconnectFromFeed(Feed* feed) +{ + disconnect (feed, SIGNAL(fetched(Feed*)), this, SLOT(slotFeedFetched(Feed*))); + disconnect (feed, SIGNAL(fetchError(Feed*)), this, SLOT(slotFetchError(Feed*))); + disconnect (feed, SIGNAL(fetchAborted(Feed*)), this, SLOT(slotFetchAborted(Feed*))); + disconnect (feed, SIGNAL(signalDestroyed(TreeNode*)), this, SLOT(slotNodeDestroyed(TreeNode*))); +} + + +void FetchQueue::slotNodeDestroyed(TreeNode* node) +{ + Feed* feed = dynamic_cast<Feed*> (node); + + if (feed) + { + d->fetchingFeeds.remove(feed); + d->queuedFeeds.remove(feed); + } +} + +} // namespace Akregator + +#include "fetchqueue.moc" |