26 #include <tqdatetime.h>
29 #include <tqvaluelist.h>
32 #include <tdelocale.h>
38 #include "treenodevisitor.h"
42 class FeedList::FeedListPrivate
46 TQMap<TQString, TQValueList<Feed*> > urlMap;
47 AddNodeVisitor* addNodeVisitor;
48 RemoveNodeVisitor* removeNodeVisitor;
51 class FeedList::AddNodeVisitor :
public TreeNodeVisitor
54 AddNodeVisitor(FeedList* list) : m_list(list) {}
55 virtual ~AddNodeVisitor() {}
58 virtual bool visitFeed(Feed* node)
60 m_list->idMap()->insert(node->id(), node);
61 m_list->flatList()->append(node);
69 class FeedList::RemoveNodeVisitor :
public TreeNodeVisitor
72 RemoveNodeVisitor(FeedList* list) : m_list(list) {}
73 virtual ~RemoveNodeVisitor() {}
75 virtual bool visitFeed(Feed* node)
77 m_list->d->urlMap[node->xmlUrl()].remove(node);
85 FeedList::FeedList(TQObject *parent,
const char *name)
86 : NodeList(parent, name), d(new FeedListPrivate)
88 d->addNodeVisitor =
new AddNodeVisitor(
this);
89 d->removeNodeVisitor =
new RemoveNodeVisitor(
this);
91 Folder* rootNode =
new Folder(i18n(
"All Feeds"));
93 setRootNode(rootNode);
94 addNode(rootNode,
true);
97 void FeedList::addNode(TreeNode* node,
bool preserveID)
99 NodeList::addNode(node, preserveID);
100 d->addNodeVisitor->visit(node);
103 void FeedList::removeNode(TreeNode* node)
105 NodeList::removeNode(node);
106 d->removeNodeVisitor->visit(node);
109 void FeedList::parseChildNodes(TQDomNode &node, Folder* parent)
111 TQDomElement e = node.toElement();
115 TQString title = e.hasAttribute(
"text") ? e.attribute(
"text") : e.attribute(
"title");
117 if (e.hasAttribute(
"xmlUrl") || e.hasAttribute(
"xmlurl") || e.hasAttribute(
"xmlURL") )
119 Feed* feed = Feed::fromOPML(e);
122 if (!d->urlMap[feed->xmlUrl()].contains(feed))
123 d->urlMap[feed->xmlUrl()].append(feed);
124 parent->appendChild(feed);
129 Folder* fg = Folder::fromOPML(e);
130 parent->appendChild(fg);
132 if (e.hasChildNodes())
134 TQDomNode child = e.firstChild();
135 while(!child.isNull())
137 parseChildNodes(child, fg);
138 child = child.nextSibling();
145 bool FeedList::readFromXML(
const TQDomDocument& doc)
147 TQDomElement root = doc.documentElement();
149 kdDebug() <<
"loading OPML feed " << root.tagName().lower() << endl;
151 kdDebug() <<
"measuring startup time: START" << endl;
155 if (root.tagName().lower() !=
"opml")
159 TQDomNode bodyNode = root.firstChild();
161 while (!bodyNode.isNull() && bodyNode.toElement().tagName().lower() !=
"body")
162 bodyNode = bodyNode.nextSibling();
165 if (bodyNode.isNull())
167 kdDebug() <<
"Failed to acquire body node, markup broken?" << endl;
171 TQDomElement body = bodyNode.toElement();
173 TQDomNode i = body.firstChild();
177 parseChildNodes(i, rootNode());
181 for (
TreeNode* i = rootNode()->firstChild(); i && i != rootNode(); i = i->next() )
184 uint
id = generateID();
186 idMap()->insert(
id, i);
189 kdDebug() <<
"measuring startup time: STOP, " << spent.elapsed() <<
"ms" << endl;
190 kdDebug() <<
"Number of articles loaded: " << rootNode()->totalCount() << endl;
194 FeedList::~FeedList()
196 emit signalDestroyed(
this);
198 delete d->addNodeVisitor;
199 delete d->removeNodeVisitor;
204 Feed* FeedList::findByURL(
const TQString& feedURL)
const
206 if (d->urlMap[feedURL].isEmpty())
209 return *(d->urlMap[feedURL].begin());
212 Article FeedList::findArticle(
const TQString& feedURL,
const TQString& guid)
const
214 Feed* feed = findByURL(feedURL);
224 if ( !flatList()->contains(parent) )
227 TQValueList<TreeNode*> children = list->rootNode()->children();
229 TQValueList<TreeNode*>::ConstIterator end( children.end() );
230 for (TQValueList<TreeNode*>::ConstIterator it = children.begin(); it != end; ++it)
232 list->rootNode()->removeChild(*it);
238 TQDomDocument FeedList::toXML()
const
241 doc.appendChild( doc.createProcessingInstruction(
"xml",
"version=\"1.0\" encoding=\"UTF-8\"" ) );
243 TQDomElement root = doc.createElement(
"opml" );
244 root.setAttribute(
"version",
"1.0" );
245 doc.appendChild( root );
247 TQDomElement head = doc.createElement(
"head" );
248 root.appendChild( head );
250 TQDomElement ti = doc.createElement(
"text" );
251 head.appendChild( ti );
253 TQDomText t = doc.createTextNode( title() );
256 TQDomElement body = doc.createElement(
"body" );
257 root.appendChild( body );
259 TQValueList<TreeNode*> children = rootNode()->children();
261 TQValueList<TreeNode*>::ConstIterator end( children.end() );
263 for (TQValueList<TreeNode*>::ConstIterator it = children.begin(); it != end; ++it)
264 body.appendChild( (*it)->toOPML(body, doc) );
270 #include "feedlist.moc"
A proxy class for RSS::Article with some additional methods to assist sorting.
The model of a feed tree, represents an OPML document.
virtual Article findArticle(const TQString &guid) const
returns the article with the given guid, or a null article if it not exists
Represents a folder (containing feeds and/or other folders)
virtual void insertChild(TreeNode *node, TreeNode *after)
inserts node as child after child node after.
Abstract base class for all kind of elements in the feed tree, like feeds and feed groups (and search...