akregator/src

fetchqueue.cpp

00001 /*
00002     This file is part of Akregator.
00003 
00004     Copyright (C) 2004 Sashmit Bhaduri <smt@vfemail.net>
00005                   2005 Frank Osterfeld <frank.osterfeld at kdemail.net>
00006 
00007     This program is free software; you can redistribute it and/or modify
00008     it under the terms of the GNU General Public License as published by
00009     the Free Software Foundation; either version 2 of the License, or
00010     (at your option) any later version.
00011 
00012     This program is distributed in the hope that it will be useful,
00013     but WITHOUT ANY WARRANTY; without even the implied warranty of
00014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00015     GNU General Public License for more details.
00016 
00017     You should have received a copy of the GNU General Public License
00018     along with this program; if not, write to the Free Software
00019     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00020 
00021     As a special exception, permission is given to link this program
00022     with any edition of Qt, and distribute the resulting executable,
00023     without including the source code for Qt in the source distribution.
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); // FIXME: better use a signal like signalAborted(Feed*)
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 } // namespace Akregator
00159 
00160 #include "fetchqueue.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys