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 TQt, and distribute the resulting executable, 00023 without including the source code for TQt in the source distribution. 00024 */ 00025 00026 #include "feed.h" 00027 #include "feediconmanager.h" 00028 00029 #include <dcopclient.h> 00030 #include <tdeapplication.h> 00031 #include <kdebug.h> 00032 #include <kstandarddirs.h> 00033 #include <kstaticdeleter.h> 00034 #include <kurl.h> 00035 00036 #include <tqdict.h> 00037 #include <tqpixmap.h> 00038 #include <tqvaluelist.h> 00039 00040 namespace Akregator { 00041 00042 class FeedIconManager::FeedIconManagerPrivate 00043 { 00044 public: 00045 TQValueList<Feed*> registeredFeeds; 00046 TQDict<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, TQT_SIGNAL(signalDestroyed(TreeNode*)), this, TQT_SLOT(slotFeedDestroyed(TreeNode*))); 00066 } 00067 TQString iconURL = getIconURL(KURL(feed->xmlUrl())); 00068 d->urlDict.insert(iconURL, feed); 00069 loadIcon(iconURL); 00070 } 00071 00072 FeedIconManager::FeedIconManager(TQObject * parent, const char *name) 00073 : TQObject(parent, name), DCOPObject("FeedIconManager"), d(new FeedIconManagerPrivate) 00074 { 00075 connectDCOPSignal("kded", 00076 "favicons", "iconChanged(bool, TQString, TQString)", 00077 "slotIconChanged(bool, TQString, TQString)", false); 00078 } 00079 00080 00081 FeedIconManager::~FeedIconManager() 00082 { 00083 delete d; 00084 d = 0; 00085 } 00086 00087 void FeedIconManager::loadIcon(const TQString & url) 00088 { 00089 KURL u(url); 00090 00091 TQString iconFile = iconLocation(u); 00092 00093 if (iconFile.isNull()) 00094 { 00095 TQByteArray data; 00096 TQDataStream 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 TQString FeedIconManager::getIconURL(const KURL& url) 00107 { 00108 return "http://" +url.host() + "/"; 00109 } 00110 00111 TQString FeedIconManager::iconLocation(const KURL & url) const 00112 { 00113 TQByteArray data, reply; 00114 TQCString replyType; 00115 TQDataStream 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 == TQSTRING_OBJECT_NAME_STRING) { 00123 TQDataStream replyStream(reply, IO_ReadOnly); 00124 TQString result; 00125 replyStream >> result; 00126 return result; 00127 } 00128 00129 return TQString(); 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 TQString& hostOrURL, 00141 const TQString& iconName) 00142 { 00143 TQString iconFile = TDEGlobal::dirs()->findResource("cache", 00144 iconName+".png"); 00145 Feed* f; 00146 TQPixmap p = TQPixmap(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"