akregator/src

feediconmanager.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@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 "feed.h"
00027 #include "feediconmanager.h"
00028 
00029 #include <dcopclient.h>
00030 #include <kapplication.h>
00031 #include <kdebug.h>
00032 #include <kstandarddirs.h>
00033 #include <kstaticdeleter.h>
00034 #include <kurl.h>
00035 
00036 #include <qdict.h>
00037 #include <qpixmap.h>
00038 #include <qvaluelist.h>
00039 
00040 namespace Akregator {
00041 
00042 class FeedIconManager::FeedIconManagerPrivate
00043 {
00044     public:
00045     QValueList<Feed*> registeredFeeds;
00046     QDict<Feed> urlDict;
00047 };
00048 
00049 FeedIconManager *FeedIconManager::m_instance = 0;
00050 
00051 static KStaticDeleter<FeedIconManager> feediconmanagersd;
00052 
00053 FeedIconManager* FeedIconManager::self()
00054 {
00055     if (!m_instance)
00056         m_instance = feediconmanagersd.setObject(m_instance, new FeedIconManager);
00057     return m_instance;
00058 }
00059 
00060 void FeedIconManager::fetchIcon(Feed* feed)
00061 {
00062     if (!d->registeredFeeds.contains(feed))
00063     {
00064         d->registeredFeeds.append(feed);
00065         connect(feed, SIGNAL(signalDestroyed(TreeNode*)), this, SLOT(slotFeedDestroyed(TreeNode*)));
00066     }
00067     QString iconURL = getIconURL(KURL(feed->xmlUrl()));
00068     d->urlDict.insert(iconURL, feed);
00069     loadIcon(iconURL);
00070 }
00071 
00072 FeedIconManager::FeedIconManager(QObject * parent, const char *name)
00073 :  QObject(parent, name), DCOPObject("FeedIconManager"), d(new FeedIconManagerPrivate)
00074 {
00075     connectDCOPSignal("kded",
00076                       "favicons", "iconChanged(bool, QString, QString)",
00077                       "slotIconChanged(bool, QString, QString)", false);
00078 }
00079 
00080 
00081 FeedIconManager::~FeedIconManager()
00082 {
00083     delete d;
00084     d = 0;
00085 }
00086 
00087 void FeedIconManager::loadIcon(const QString & url)
00088 {
00089     KURL u(url);
00090 
00091     QString iconFile = iconLocation(u);
00092     
00093     if (iconFile.isNull())
00094     {
00095         QByteArray data;
00096         QDataStream ds(data, IO_WriteOnly);
00097         ds << u;
00098         kapp->dcopClient()->send("kded", "favicons", "downloadHostIcon(KURL)",
00099                                  data);
00100     }
00101     else
00102         slotIconChanged(false, url, iconFile);
00103 
00104 }
00105 
00106 QString FeedIconManager::getIconURL(const KURL& url)
00107 {
00108     return "http://" +url.host() + "/";
00109 }
00110 
00111 QString FeedIconManager::iconLocation(const KURL & url) const
00112 {
00113     QByteArray data, reply;
00114     QCString replyType;
00115     QDataStream ds(data, IO_WriteOnly);
00116 
00117     ds << url;
00118 
00119     kapp->dcopClient()->call("kded", "favicons", "iconForURL(KURL)", data,
00120                              replyType, reply);
00121 
00122     if (replyType == "QString") {
00123         QDataStream replyStream(reply, IO_ReadOnly);
00124         QString result;
00125         replyStream >> result;
00126         return result;
00127     }
00128 
00129     return QString::null;
00130 }
00131 
00132 void FeedIconManager::slotFeedDestroyed(TreeNode* node)
00133 {
00134     Feed* feed = dynamic_cast<Feed*>(node);
00135     if (feed)
00136         while (d->registeredFeeds.contains(feed))
00137             d->registeredFeeds.remove(d->registeredFeeds.find(feed));
00138 }
00139 
00140 void FeedIconManager::slotIconChanged(bool /*isHost*/, const QString& hostOrURL,
00141                                   const QString& iconName)
00142 {
00143     QString iconFile = KGlobal::dirs()->findResource("cache",
00144                                  iconName+".png");
00145     Feed* f;
00146     QPixmap p = QPixmap(iconFile);
00147     if (!p.isNull()) // we don't set null pixmaps, as feed checks pixmap.isNull() to find out whether the icon was already loaded or not. It would request the icon another time, resulting an infinite loop (until stack overflow that is
00148     {
00149         while (( f = d->urlDict.take(hostOrURL) ))
00150             if (d->registeredFeeds.contains(f))
00151                 f->setFavicon(p);
00152     }
00153     emit signalIconChanged(hostOrURL, iconFile);
00154 }
00155 
00156 } // namespace Akregator
00157 #include "feediconmanager.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys