00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "folder.h"
00026 #include "nodelist.h"
00027 #include "treenode.h"
00028 #include "treenodevisitor.h"
00029
00030 #include <kapplication.h>
00031
00032 #include <qmap.h>
00033 #include <qstring.h>
00034 #include <qvaluelist.h>
00035
00036 namespace Akregator {
00037
00038 class NodeList::NodeListPrivate
00039 {
00040 public:
00041 QValueList<TreeNode*> flatList;
00042 Folder* rootNode;
00043 QString title;
00044 QMap<int, TreeNode*> idMap;
00045 AddNodeVisitor* addNodeVisitor;
00046 RemoveNodeVisitor* removeNodeVisitor;
00047 };
00048
00049
00050 class NodeList::AddNodeVisitor : public TreeNodeVisitor
00051 {
00052 public:
00053 AddNodeVisitor(NodeList* list) : m_list(list) {}
00054
00055
00056 virtual bool visitTreeNode(TreeNode* node)
00057 {
00058 if (!m_preserveID)
00059 node->setId(m_list->generateID());
00060 m_list->d->idMap[node->id()] = node;
00061 m_list->d->flatList.append(node);
00062
00063 connect(node, SIGNAL(signalDestroyed(TreeNode*)), m_list, SLOT(slotNodeDestroyed(TreeNode*) ));
00064 m_list->signalNodeAdded(node);
00065
00066 return true;
00067 }
00068 virtual bool visitFolder(Folder* node)
00069 {
00070 connect(node, SIGNAL(signalChildAdded(TreeNode*)), m_list, SLOT(slotNodeAdded(TreeNode*) ));
00071 connect(node, SIGNAL(signalChildRemoved(Folder*, TreeNode*)), m_list, SLOT(slotNodeRemoved(Folder*, TreeNode*) ));
00072
00073 visitTreeNode(node);
00074
00075 for (TreeNode* i = node->firstChild(); i && i != node; i = i->next() )
00076 m_list->slotNodeAdded(i);
00077
00078 return true;
00079 }
00080
00081 virtual void visit(TreeNode* node, bool preserveID)
00082 {
00083 m_preserveID = preserveID;
00084 TreeNodeVisitor::visit(node);
00085 }
00086
00087 private:
00088 NodeList* m_list;
00089 bool m_preserveID;
00090 };
00091
00092 class NodeList::RemoveNodeVisitor : public TreeNodeVisitor
00093 {
00094 public:
00095 RemoveNodeVisitor(NodeList* list) : m_list(list) {}
00096
00097 virtual bool visitTreeNode(TreeNode* node)
00098 {
00099 m_list->d->idMap.remove(node->id());
00100 m_list->d->flatList.remove(node);
00101
00102 disconnect(node, SIGNAL(signalDestroyed(TreeNode*)), m_list, SLOT(slotNodeDestroyed(TreeNode*) ));
00103 m_list->signalNodeRemoved(node);
00104
00105 return true;
00106 }
00107
00108 virtual bool visitFolder(Folder* node)
00109 {
00110
00111 disconnect(node, SIGNAL(signalChildAdded(TreeNode*)), m_list, SLOT(slotNodeAdded(TreeNode*) ));
00112 disconnect(node, SIGNAL(signalChildRemoved(Folder*, TreeNode*)), m_list, SLOT(slotNodeRemoved(Folder*, TreeNode*) ));
00113 visitTreeNode(node);
00114
00115 return true;
00116 }
00117 private:
00118 NodeList* m_list;
00119 };
00120
00121 NodeList::NodeList(QObject *parent, const char *name) : d(new NodeListPrivate)
00122 {
00123 d->rootNode = 0;
00124 d->addNodeVisitor = new AddNodeVisitor(this);
00125 d->removeNodeVisitor = new RemoveNodeVisitor(this);
00126
00127 }
00128
00129 const QString& NodeList::title() const
00130 {
00131 return d->title;
00132 }
00133
00134 TreeNode* NodeList::findByID(int id) const
00135 {
00136 return d->idMap[id];
00137 }
00138
00139 void NodeList::setTitle(const QString& title)
00140 {
00141 d->title = title;
00142 }
00143
00144 Folder* NodeList::rootNode() const
00145 {
00146 return d->rootNode;
00147 }
00148
00149 const QValueList<TreeNode*>& NodeList::asFlatList() const
00150 {
00151 return d->flatList;
00152 }
00153
00154 bool NodeList::isEmpty() const
00155 {
00156 return d->rootNode->firstChild() == 0;
00157 }
00158
00159 QValueList<TreeNode*>* NodeList::flatList() const
00160 {
00161 return &(d->flatList);
00162 }
00163
00164 void NodeList::clear()
00165 {
00166 Q_ASSERT(rootNode());
00167
00168 QValueList<TreeNode*> children = rootNode()->children();
00169
00170 for (QValueList<TreeNode*>::ConstIterator it = children.begin(); it != children.end(); ++it)
00171 delete *it;
00172 }
00173
00174 QMap<int, TreeNode*>* NodeList::idMap() const
00175 {
00176 return &(d->idMap);
00177 }
00178
00179 void NodeList::setRootNode(Folder* folder)
00180 {
00181 delete d->rootNode;
00182 d->rootNode = folder;
00183
00184 if (d->rootNode)
00185 {
00186 d->rootNode->setOpen(true);
00187 connect(d->rootNode, SIGNAL(signalChildAdded(TreeNode*)), this, SLOT(slotNodeAdded(TreeNode*)));
00188 connect(d->rootNode, SIGNAL(signalChildRemoved(Folder*, TreeNode*)), this, SLOT(slotNodeRemoved(Folder*, TreeNode*)));
00189 }
00190 }
00191
00192 void NodeList::addNode(TreeNode* node, bool preserveID)
00193 {
00194 d->addNodeVisitor->visit(node, preserveID);
00195 }
00196
00197 void NodeList::removeNode(TreeNode* node)
00198 {
00199 d->removeNodeVisitor->visit(node);
00200 }
00201
00202 NodeList::~NodeList()
00203 {
00204 emit signalDestroyed(this);
00205 delete d->addNodeVisitor;
00206 delete d->removeNodeVisitor;
00207 delete d;
00208 d = 0;
00209 }
00210
00211 int NodeList::generateID()
00212 {
00213 return KApplication::random();
00214 }
00215
00216 void NodeList::slotNodeAdded(TreeNode* node)
00217 {
00218 Folder* parent = node->parent();
00219 if ( !node || !d->flatList.contains(parent) || d->flatList.contains(node) )
00220 return;
00221
00222 addNode(node, false);
00223 }
00224
00225 void NodeList::slotNodeDestroyed(TreeNode* node)
00226 {
00227 if ( !node || !d->flatList.contains(node) )
00228 return;
00229
00230 removeNode(node);
00231 }
00232
00233 void NodeList::slotNodeRemoved(Folder* , TreeNode* node)
00234 {
00235 if ( !node || !d->flatList.contains(node) )
00236 return;
00237
00238 removeNode(node);
00239 }
00240
00241 }
00242
00243 #include "nodelist.moc"