nodelist.cpp
00001 /* 00002 This file is part of Akregator. 00003 00004 Copyright (C) 2005 Frank Osterfeld <frank.osterfeld at kdemail.net> 00005 00006 This program is free software; you can redistribute it and/or modify 00007 it under the terms of the GNU General Public License as published by 00008 the Free Software Foundation; either version 2 of the License, or 00009 (at your option) any later version. 00010 00011 This program is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 GNU General Public License for more details. 00015 00016 You should have received a copy of the GNU General Public License 00017 along with this program; if not, write to the Free Software 00018 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00019 00020 As a special exception, permission is given to link this program 00021 with any edition of TQt, and distribute the resulting executable, 00022 without including the source code for TQt in the source distribution. 00023 */ 00024 00025 #include "folder.h" 00026 #include "nodelist.h" 00027 #include "treenode.h" 00028 #include "treenodevisitor.h" 00029 00030 #include <tdeapplication.h> 00031 00032 #include <tqmap.h> 00033 #include <tqstring.h> 00034 #include <tqvaluelist.h> 00035 00036 namespace Akregator { 00037 00038 class NodeList::NodeListPrivate 00039 { 00040 public: 00041 TQValueList<TreeNode*> flatList; 00042 Folder* rootNode; 00043 TQString title; 00044 TQMap<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, TQT_SIGNAL(signalDestroyed(TreeNode*)), m_list, TQT_SLOT(slotNodeDestroyed(TreeNode*) )); 00064 m_list->signalNodeAdded(node); // emit 00065 00066 return true; 00067 } 00068 virtual bool visitFolder(Folder* node) 00069 { 00070 connect(node, TQT_SIGNAL(signalChildAdded(TreeNode*)), m_list, TQT_SLOT(slotNodeAdded(TreeNode*) )); 00071 connect(node, TQT_SIGNAL(signalChildRemoved(Folder*, TreeNode*)), m_list, TQT_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, TQT_SIGNAL(signalDestroyed(TreeNode*)), m_list, TQT_SLOT(slotNodeDestroyed(TreeNode*) )); 00103 m_list->signalNodeRemoved(node); // emit signal 00104 00105 return true; 00106 } 00107 00108 virtual bool visitFolder(Folder* node) 00109 { 00110 00111 disconnect(node, TQT_SIGNAL(signalChildAdded(TreeNode*)), m_list, TQT_SLOT(slotNodeAdded(TreeNode*) )); 00112 disconnect(node, TQT_SIGNAL(signalChildRemoved(Folder*, TreeNode*)), m_list, TQT_SLOT(slotNodeRemoved(Folder*, TreeNode*) )); 00113 visitTreeNode(node); 00114 00115 return true; 00116 } 00117 private: 00118 NodeList* m_list; 00119 }; 00120 00121 NodeList::NodeList(TQObject *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 TQString& 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 TQString& title) 00140 { 00141 d->title = title; 00142 } 00143 00144 Folder* NodeList::rootNode() const 00145 { 00146 return d->rootNode; 00147 } 00148 00149 const TQValueList<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 TQValueList<TreeNode*>* NodeList::flatList() const 00160 { 00161 return &(d->flatList); 00162 } 00163 00164 void NodeList::clear() 00165 { 00166 Q_ASSERT(rootNode()); 00167 00168 TQValueList<TreeNode*> children = rootNode()->children(); 00169 00170 for (TQValueList<TreeNode*>::ConstIterator it = children.begin(); it != children.end(); ++it) 00171 delete *it; // emits signal "emitSignalDestroyed" 00172 } 00173 00174 TQMap<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, TQT_SIGNAL(signalChildAdded(TreeNode*)), this, TQT_SLOT(slotNodeAdded(TreeNode*))); 00188 connect(d->rootNode, TQT_SIGNAL(signalChildRemoved(Folder*, TreeNode*)), this, TQT_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 TDEApplication::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* /*parent*/, TreeNode* node) 00234 { 00235 if ( !node || !d->flatList.contains(node) ) 00236 return; 00237 00238 removeNode(node); 00239 } 00240 00241 } 00242 00243 #include "nodelist.moc"