akregator/src

nodelist.cpp
1 /*
2  This file is part of Akregator.
3 
4  Copyright (C) 2005 Frank Osterfeld <frank.osterfeld at kdemail.net>
5 
6  This program is free software; you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation; either version 2 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program; if not, write to the Free Software
18  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 
20  As a special exception, permission is given to link this program
21  with any edition of TQt, and distribute the resulting executable,
22  without including the source code for TQt in the source distribution.
23 */
24 
25 #include "folder.h"
26 #include "nodelist.h"
27 #include "treenode.h"
28 #include "treenodevisitor.h"
29 
30 #include <tdeapplication.h>
31 
32 #include <tqmap.h>
33 #include <tqstring.h>
34 #include <tqvaluelist.h>
35 
36 namespace Akregator {
37 
38 class NodeList::NodeListPrivate
39 {
40  public:
41  TQValueList<TreeNode*> flatList;
42  Folder* rootNode;
43  TQString title;
44  TQMap<int, TreeNode*> idMap;
45  AddNodeVisitor* addNodeVisitor;
46  RemoveNodeVisitor* removeNodeVisitor;
47 };
48 
49 
50 class NodeList::AddNodeVisitor : public TreeNodeVisitor
51 {
52  public:
53  AddNodeVisitor(NodeList* list) : m_list(list) {}
54 
55 
56  virtual bool visitTreeNode(TreeNode* node)
57  {
58  if (!m_preserveID)
59  node->setId(m_list->generateID());
60  m_list->d->idMap[node->id()] = node;
61  m_list->d->flatList.append(node);
62 
63  connect(node, TQ_SIGNAL(signalDestroyed(TreeNode*)), m_list, TQ_SLOT(slotNodeDestroyed(TreeNode*) ));
64  m_list->signalNodeAdded(node); // emit
65 
66  return true;
67  }
68  virtual bool visitFolder(Folder* node)
69  {
70  connect(node, TQ_SIGNAL(signalChildAdded(TreeNode*)), m_list, TQ_SLOT(slotNodeAdded(TreeNode*) ));
71  connect(node, TQ_SIGNAL(signalChildRemoved(Folder*, TreeNode*)), m_list, TQ_SLOT(slotNodeRemoved(Folder*, TreeNode*) ));
72 
73  visitTreeNode(node);
74 
75  for (TreeNode* i = node->firstChild(); i && i != node; i = i->next() )
76  m_list->slotNodeAdded(i);
77 
78  return true;
79  }
80 
81  virtual void visit(TreeNode* node, bool preserveID)
82  {
83  m_preserveID = preserveID;
84  TreeNodeVisitor::visit(node);
85  }
86 
87  private:
88  NodeList* m_list;
89  bool m_preserveID;
90 };
91 
92 class NodeList::RemoveNodeVisitor : public TreeNodeVisitor
93 {
94  public:
95  RemoveNodeVisitor(NodeList* list) : m_list(list) {}
96 
97  virtual bool visitTreeNode(TreeNode* node)
98  {
99  m_list->d->idMap.remove(node->id());
100  m_list->d->flatList.remove(node);
101 
102  disconnect(node, TQ_SIGNAL(signalDestroyed(TreeNode*)), m_list, TQ_SLOT(slotNodeDestroyed(TreeNode*) ));
103  m_list->signalNodeRemoved(node); // emit signal
104 
105  return true;
106  }
107 
108  virtual bool visitFolder(Folder* node)
109  {
110 
111  disconnect(node, TQ_SIGNAL(signalChildAdded(TreeNode*)), m_list, TQ_SLOT(slotNodeAdded(TreeNode*) ));
112  disconnect(node, TQ_SIGNAL(signalChildRemoved(Folder*, TreeNode*)), m_list, TQ_SLOT(slotNodeRemoved(Folder*, TreeNode*) ));
113  visitTreeNode(node);
114 
115  return true;
116  }
117  private:
118  NodeList* m_list;
119 };
120 
121 NodeList::NodeList(TQObject *parent, const char *name) : d(new NodeListPrivate)
122 {
123  d->rootNode = 0;
124  d->addNodeVisitor = new AddNodeVisitor(this);
125  d->removeNodeVisitor = new RemoveNodeVisitor(this);
126 
127 }
128 
129 const TQString& NodeList::title() const
130 {
131  return d->title;
132 }
133 
134 TreeNode* NodeList::findByID(int id) const
135 {
136  return d->idMap[id];
137 }
138 
139 void NodeList::setTitle(const TQString& title)
140 {
141  d->title = title;
142 }
143 
144 Folder* NodeList::rootNode() const
145 {
146  return d->rootNode;
147 }
148 
149 const TQValueList<TreeNode*>& NodeList::asFlatList() const
150 {
151  return d->flatList;
152 }
153 
154 bool NodeList::isEmpty() const
155 {
156  return d->rootNode->firstChild() == 0;
157 }
158 
159 TQValueList<TreeNode*>* NodeList::flatList() const
160 {
161  return &(d->flatList);
162 }
163 
164 void NodeList::clear()
165 {
166  Q_ASSERT(rootNode());
167 
168  TQValueList<TreeNode*> children = rootNode()->children();
169 
170  for (TQValueList<TreeNode*>::ConstIterator it = children.begin(); it != children.end(); ++it)
171  delete *it; // emits signal "emitSignalDestroyed"
172 }
173 
174 TQMap<int, TreeNode*>* NodeList::idMap() const
175 {
176  return &(d->idMap);
177 }
178 
179 void NodeList::setRootNode(Folder* folder)
180 {
181  delete d->rootNode;
182  d->rootNode = folder;
183 
184  if (d->rootNode)
185  {
186  d->rootNode->setOpen(true);
187  connect(d->rootNode, TQ_SIGNAL(signalChildAdded(TreeNode*)), this, TQ_SLOT(slotNodeAdded(TreeNode*)));
188  connect(d->rootNode, TQ_SIGNAL(signalChildRemoved(Folder*, TreeNode*)), this, TQ_SLOT(slotNodeRemoved(Folder*, TreeNode*)));
189  }
190 }
191 
192 void NodeList::addNode(TreeNode* node, bool preserveID)
193 {
194  d->addNodeVisitor->visit(node, preserveID);
195 }
196 
197 void NodeList::removeNode(TreeNode* node)
198 {
199  d->removeNodeVisitor->visit(node);
200 }
201 
202 NodeList::~NodeList()
203 {
204  emit signalDestroyed(this);
205  delete d->addNodeVisitor;
206  delete d->removeNodeVisitor;
207  delete d;
208  d = 0;
209 }
210 
211 int NodeList::generateID()
212 {
213  return TDEApplication::random();
214 }
215 
216 void NodeList::slotNodeAdded(TreeNode* node)
217 {
218  Folder* parent = node->parent();
219  if ( !node || !d->flatList.contains(parent) || d->flatList.contains(node) )
220  return;
221 
222  addNode(node, false);
223 }
224 
225 void NodeList::slotNodeDestroyed(TreeNode* node)
226 {
227  if ( !node || !d->flatList.contains(node) )
228  return;
229 
230  removeNode(node);
231 }
232 
233 void NodeList::slotNodeRemoved(Folder* /*parent*/, TreeNode* node)
234 {
235  if ( !node || !d->flatList.contains(node) )
236  return;
237 
238  removeNode(node);
239 }
240 
241 }
242 
243 #include "nodelist.moc"