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 <kstandarddirs.h>
33 #include <kstaticdeleter.h>
34 #include <kurl.h>
35 
36 #include <tqdict.h>
37 #include <tqpixmap.h>
38 #include <tqvaluelist.h>
39 
40 namespace Akregator {
41 
42 class FeedIconManager::FeedIconManagerPrivate
43 {
44  public:
45  TQValueList<Feed*> registeredFeeds;
46  TQDict<Feed> urlDict;
47 };
48 
49 FeedIconManager *FeedIconManager::m_instance = 0;
50 
51 static KStaticDeleter<FeedIconManager> feediconmanagersd;
52 
53 FeedIconManager* FeedIconManager::self()
54 {
55  if (!m_instance)
56  m_instance = feediconmanagersd.setObject(m_instance, new FeedIconManager);
57  return m_instance;
58 }
59 
60 void 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 
72 FeedIconManager::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 
81 FeedIconManager::~FeedIconManager()
82 {
83  delete d;
84  d = 0;
85 }
86 
87 void 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  kapp->dcopClient()->send("kded", "favicons", "downloadHostIcon(KURL)",
99  data);
100  }
101  else
102  slotIconChanged(false, url, iconFile);
103 
104 }
105 
106 TQString FeedIconManager::getIconURL(const KURL& url)
107 {
108  return "http://" +url.host() + "/";
109 }
110 
111 TQString 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  kapp->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 
132 void 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 
140 void 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"