akregator/src
fetchqueue.cpp00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include <qvaluelist.h>
00027
00028 #include "akregatorconfig.h"
00029 #include "fetchqueue.h"
00030 #include "feed.h"
00031 #include "treenode.h"
00032
00033
00034 namespace Akregator {
00035
00036 class FetchQueue::FetchQueuePrivate
00037 {
00038 public:
00039
00040 QValueList<Feed*> queuedFeeds;
00041 QValueList<Feed*> fetchingFeeds;
00042 };
00043
00044
00045 FetchQueue::FetchQueue(QObject* parent, const char* name): QObject(parent, name), d(new FetchQueuePrivate) {}
00046
00047
00048 FetchQueue::~FetchQueue()
00049 {
00050 slotAbort();
00051 delete d;
00052 d = 0;
00053 }
00054
00055 void FetchQueue::slotAbort()
00056 {
00057 for (QValueList<Feed*>::Iterator it = d->fetchingFeeds.begin(); it != d->fetchingFeeds.end(); ++it)
00058 {
00059 disconnectFromFeed(*it);
00060 (*it)->slotAbortFetch();
00061 }
00062 d->fetchingFeeds.clear();
00063
00064 for (QValueList<Feed*>::Iterator it = d->queuedFeeds.begin(); it != d->queuedFeeds.end(); ++it)
00065 {
00066 disconnectFromFeed(*it);
00067 }
00068 d->queuedFeeds.clear();
00069
00070 emit signalStopped();
00071 }
00072
00073 void FetchQueue::addFeed(Feed *f)
00074 {
00075 if (!d->queuedFeeds.contains(f) && !d->fetchingFeeds.contains(f))
00076 {
00077 connectToFeed(f);
00078 d->queuedFeeds.append(f);
00079 fetchNextFeed();
00080 }
00081 }
00082
00083 void FetchQueue::fetchNextFeed()
00084 {
00085 if (!d->queuedFeeds.isEmpty() && d->fetchingFeeds.count() < Settings::concurrentFetches())
00086 {
00087 if (d->fetchingFeeds.isEmpty() && d->queuedFeeds.count() == 1)
00088 emit signalStarted();
00089 Feed* f = *(d->queuedFeeds.begin());
00090 d->queuedFeeds.pop_front();
00091 d->fetchingFeeds.append(f);
00092 f->fetch(false);
00093
00094 }
00095 }
00096
00097 void FetchQueue::slotFeedFetched(Feed *f)
00098 {
00099 emit fetched(f);
00100 feedDone(f);
00101 }
00102
00103 void FetchQueue::slotFetchError(Feed *f)
00104 {
00105 emit fetchError(f);
00106 feedDone(f);
00107 }
00108
00109 void FetchQueue::slotFetchAborted(Feed *f)
00110 {
00111 emit fetched(f);
00112 feedDone(f);
00113 }
00114
00115 bool FetchQueue::isEmpty() const
00116 {
00117 return d->queuedFeeds.isEmpty() && d->fetchingFeeds.isEmpty();
00118 }
00119
00120 void FetchQueue::feedDone(Feed *f)
00121 {
00122 disconnectFromFeed(f);
00123 d->fetchingFeeds.remove(f);
00124 if (isEmpty())
00125 emit signalStopped();
00126 else
00127 fetchNextFeed();
00128 }
00129
00130 void FetchQueue::connectToFeed(Feed* feed)
00131 {
00132 connect (feed, SIGNAL(fetched(Feed*)), this, SLOT(slotFeedFetched(Feed*)));
00133 connect (feed, SIGNAL(fetchError(Feed*)), this, SLOT(slotFetchError(Feed*)));
00134 connect (feed, SIGNAL(fetchAborted(Feed*)), this, SLOT(slotFetchAborted(Feed*)));
00135 connect (feed, SIGNAL(signalDestroyed(TreeNode*)), this, SLOT(slotNodeDestroyed(TreeNode*)));
00136 }
00137
00138 void FetchQueue::disconnectFromFeed(Feed* feed)
00139 {
00140 disconnect (feed, SIGNAL(fetched(Feed*)), this, SLOT(slotFeedFetched(Feed*)));
00141 disconnect (feed, SIGNAL(fetchError(Feed*)), this, SLOT(slotFetchError(Feed*)));
00142 disconnect (feed, SIGNAL(fetchAborted(Feed*)), this, SLOT(slotFetchAborted(Feed*)));
00143 disconnect (feed, SIGNAL(signalDestroyed(TreeNode*)), this, SLOT(slotNodeDestroyed(TreeNode*)));
00144 }
00145
00146
00147 void FetchQueue::slotNodeDestroyed(TreeNode* node)
00148 {
00149 Feed* feed = dynamic_cast<Feed*> (node);
00150
00151 if (feed)
00152 {
00153 d->fetchingFeeds.remove(feed);
00154 d->queuedFeeds.remove(feed);
00155 }
00156 }
00157
00158 }
00159
00160 #include "fetchqueue.moc"
|