akregator/src

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 Qt, and distribute the resulting executable,
00022     without including the source code for Qt 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 <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); // emit
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); // emit signal
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; // emits signal "emitSignalDestroyed"
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* /*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"
KDE Home | KDE Accessibility Home | Description of Access Keys