akregator/src

feediconmanager.cpp
1/*
2 This file is part of Akregator.
3
4 Copyright (C) 2004 Sashmit Bhaduri <smt@vfemail.net>
5 2005 Frank Osterfeld <frank.osterfeld@kdemail.net>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20
21 As a special exception, permission is given to link this program
22 with any edition of TQt, and distribute the resulting executable,
23 without including the source code for TQt in the source distribution.
24*/
25
26#include "feed.h"
27#include "feediconmanager.h"
28
29#include <dcopclient.h>
30#include <tdeapplication.h>
31#include <kdebug.h>
32#include <tdestandarddirs.h>
33#include <kstaticdeleter.h>
34#include <kurl.h>
35
36#include <tqdict.h>
37#include <tqpixmap.h>
38#include <tqvaluelist.h>
39
40namespace Akregator {
41
42class FeedIconManager::FeedIconManagerPrivate
43{
44 public:
45 TQValueList<Feed*> registeredFeeds;
46 TQDict<Feed> urlDict;
47};
48
49FeedIconManager *FeedIconManager::m_instance = 0;
50
51static KStaticDeleter<FeedIconManager> feediconmanagersd;
52
53FeedIconManager* FeedIconManager::self()
54{
55 if (!m_instance)
56 m_instance = feediconmanagersd.setObject(m_instance, new FeedIconManager);
57 return m_instance;
58}
59
60void FeedIconManager::fetchIcon(Feed* feed)
61{
62 if (!d->registeredFeeds.contains(feed))
63 {
64 d->registeredFeeds.append(feed);
65 connect(feed, TQ_SIGNAL(signalDestroyed(TreeNode*)), this, TQ_SLOT(slotFeedDestroyed(TreeNode*)));
66 }
67 TQString iconURL = getIconURL(KURL(feed->xmlUrl()));
68 d->urlDict.insert(iconURL, feed);
69 loadIcon(iconURL);
70}
71
72FeedIconManager::FeedIconManager(TQObject * parent, const char *name)
73: TQObject(parent, name), DCOPObject("FeedIconManager"), d(new FeedIconManagerPrivate)
74{
75 connectDCOPSignal("kded",
76 "favicons", "iconChanged(bool, TQString, TQString)",
77 "slotIconChanged(bool, TQString, TQString)", false);
78}
79
80
81FeedIconManager::~FeedIconManager()
82{
83 delete d;
84 d = 0;
85}
86
87void FeedIconManager::loadIcon(const TQString & url)
88{
89 KURL u(url);
90
91 TQString iconFile = iconLocation(u);
92
93 if (iconFile.isNull())
94 {
95 TQByteArray data;
96 TQDataStream ds(data, IO_WriteOnly);
97 ds << u;
98 tdeApp->dcopClient()->send("kded", "favicons", "downloadHostIcon(KURL)",
99 data);
100 }
101 else
102 slotIconChanged(false, url, iconFile);
103
104}
105
106TQString FeedIconManager::getIconURL(const KURL& url)
107{
108 return "http://" +url.host() + "/";
109}
110
111TQString FeedIconManager::iconLocation(const KURL & url) const
112{
113 TQByteArray data, reply;
114 TQCString replyType;
115 TQDataStream ds(data, IO_WriteOnly);
116
117 ds << url;
118
119 tdeApp->dcopClient()->call("kded", "favicons", "iconForURL(KURL)", data,
120 replyType, reply);
121
122 if (replyType == "TQString") {
123 TQDataStream replyStream(reply, IO_ReadOnly);
124 TQString result;
125 replyStream >> result;
126 return result;
127 }
128
129 return TQString();
130}
131
132void FeedIconManager::slotFeedDestroyed(TreeNode* node)
133{
134 Feed* feed = dynamic_cast<Feed*>(node);
135 if (feed)
136 while (d->registeredFeeds.contains(feed))
137 d->registeredFeeds.remove(d->registeredFeeds.find(feed));
138}
139
140void FeedIconManager::slotIconChanged(bool /*isHost*/, const TQString& hostOrURL,
141 const TQString& iconName)
142{
143 TQString iconFile = TDEGlobal::dirs()->findResource("cache",
144 iconName+".png");
145 Feed* f;
146 TQPixmap p = TQPixmap(iconFile);
147 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
148 {
149 while (( f = d->urlDict.take(hostOrURL) ))
150 if (d->registeredFeeds.contains(f))
151 f->setFavicon(p);
152 }
153 emit signalIconChanged(hostOrURL, iconFile);
154}
155
156} // namespace Akregator
157#include "feediconmanager.moc"