|
|
|
/*
|
|
|
|
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 <tqvaluelist.h>
|
|
|
|
|
|
|
|
#include "akregatorconfig.h"
|
|
|
|
#include "fetchqueue.h"
|
|
|
|
#include "feed.h"
|
|
|
|
#include "treenode.h"
|
|
|
|
|
|
|
|
|
|
|
|
namespace Akregator {
|
|
|
|
|
|
|
|
class FetchQueue::FetchQueuePrivate
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
|
|
|
TQValueList<Feed*> queuedFeeds;
|
|
|
|
TQValueList<Feed*> fetchingFeeds;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
FetchQueue::FetchQueue(TQObject* parent, const char* name): TQObject(parent, name), d(new FetchQueuePrivate) {}
|
|
|
|
|
|
|
|
|
|
|
|
FetchQueue::~FetchQueue()
|
|
|
|
{
|
|
|
|
slotAbort();
|
|
|
|
delete d;
|
|
|
|
d = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void FetchQueue::slotAbort()
|
|
|
|
{
|
|
|
|
for (TQValueList<Feed*>::Iterator it = d->fetchingFeeds.begin(); it != d->fetchingFeeds.end(); ++it)
|
|
|
|
{
|
|
|
|
disconnectFromFeed(*it);
|
|
|
|
(*it)->slotAbortFetch();
|
|
|
|
}
|
|
|
|
d->fetchingFeeds.clear();
|
|
|
|
|
|
|
|
for (TQValueList<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.tqcontains(f) && !d->fetchingFeeds.tqcontains(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, TQT_SIGNAL(fetched(Feed*)), this, TQT_SLOT(slotFeedFetched(Feed*)));
|
|
|
|
connect (feed, TQT_SIGNAL(fetchError(Feed*)), this, TQT_SLOT(slotFetchError(Feed*)));
|
|
|
|
connect (feed, TQT_SIGNAL(fetchAborted(Feed*)), this, TQT_SLOT(slotFetchAborted(Feed*)));
|
|
|
|
connect (feed, TQT_SIGNAL(signalDestroyed(TreeNode*)), this, TQT_SLOT(slotNodeDestroyed(TreeNode*)));
|
|
|
|
}
|
|
|
|
|
|
|
|
void FetchQueue::disconnectFromFeed(Feed* feed)
|
|
|
|
{
|
|
|
|
disconnect (feed, TQT_SIGNAL(fetched(Feed*)), this, TQT_SLOT(slotFeedFetched(Feed*)));
|
|
|
|
disconnect (feed, TQT_SIGNAL(fetchError(Feed*)), this, TQT_SLOT(slotFetchError(Feed*)));
|
|
|
|
disconnect (feed, TQT_SIGNAL(fetchAborted(Feed*)), this, TQT_SLOT(slotFetchAborted(Feed*)));
|
|
|
|
disconnect (feed, TQT_SIGNAL(signalDestroyed(TreeNode*)), this, TQT_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"
|