QtAstModel.cpp

Go to the documentation of this file.
00001 #include "rose.h"
00002 
00003 #include "QtAstModel.h"
00004 
00005 #include <QDebug>
00006 #include <QList>
00007 
00008 #include "ItemTreeNode.h"
00009 #include "ItemModelHelper.h"
00010 
00011 #include "AstDisplayInfo.h"
00012 
00013 // ------------------ ModelNode ------------------------
00014 
00020 class QtAstModel::ModelNode : public ItemTreeNode
00021 {
00022     public:
00023         //Constructor only for RootElement!
00024         ModelNode(SgNode * proj);
00025         virtual ~ModelNode() {}
00026 
00027         SgNode * sgNode() const             { return sg; }
00028         const QString & getDispName() const { return dispName; }
00029 
00030 
00031         QtAstModel::ModelNode * addChild(const QString & name,SgNode * s);
00032 
00033         virtual QVariant data(int role, int column=0) const;
00034 
00036         bool isBuildUp() const  { return buildUp; }
00037 
00039         void buildUpFinished()  { buildUp=true; }
00040 
00041         virtual void deleteChildren();
00042 
00043     protected:
00044 
00045         ModelNode() {}
00046 
00048         QIcon icon;
00049 
00051         SgNode * sg;
00052 
00053 
00054         /* this member is shown in the first column of the view
00055          * it usually is some description obtained by AstDisplayInfo,
00056          * but if there is none available it's set to the successorName
00057          * see SgNode function get_traversalSuccessorNamesContainer() */
00058         QString dispName;
00059 
00063         void setInfo(SgNode * node);
00064 
00065         // the tree structure is build up "on demand" from the rose AST
00066         // in the row() function, the children are added and finalized is set to true
00067         // when the node is visited again, the children are not added anymore
00068         bool buildUp;
00069 };
00070 
00071 QtAstModel::ModelNode::ModelNode(SgNode * s)
00072 {
00073     sg=s;
00074 
00075 
00076     if(s)
00077         setInfo(s);
00078     else
00079         dispName=tr("Empty");
00080 
00081 
00082     buildUp=false;
00083 }
00084 
00085 
00086 void QtAstModel::ModelNode::deleteChildren()
00087 {
00088     qDeleteAll(children);
00089     buildUp=false;
00090     children.clear();
00091 }
00092 
00093 QVariant QtAstModel::ModelNode::data(int role, int column) const
00094 {
00095     if( role== Qt::DisplayRole)
00096     {
00097         switch(column)
00098         {
00099             case 0 : return dispName;
00100             case 1 : return sg ? QString( sg->class_name().c_str() ) : QString("NULL");
00101             default: return QVariant();
00102         }
00103     }
00104     else if( role==SgNodeRole)
00105     {
00106         return sg ? QVariant::fromValue<SgNode*>(sg) : QVariant();
00107     }
00108     else if (role == Qt::DecorationRole && column ==0)
00109         return icon;
00110 
00111 
00112     return QVariant();
00113 }
00114 
00115 
00116 
00117 QtAstModel::ModelNode * QtAstModel::ModelNode::addChild(const QString & name,SgNode * s)
00118 {
00119     // when the tree is buildUp then all children have already been added
00120     Q_ASSERT(!buildUp);
00121 
00122     ModelNode * newChild = new ModelNode();
00123     ItemTreeNode::addChild(newChild);
00124 
00125     newChild->sg=s;
00126     newChild->dispName=name;
00127     newChild->buildUp=false;
00128 
00129     newChild->setInfo(s);
00130 
00131     return newChild;
00132 }
00133 
00134 void QtAstModel::ModelNode::setInfo(SgNode * s)
00135 {
00136     icon = AstDisplayInfo::nodeIcon(s);
00137 
00138     QString newName = AstDisplayInfo::getShortNodeNameDesc(s);
00139     if(! newName.isEmpty())
00140         dispName=newName;
00141 
00142 }
00143 
00144 // ------------------ ASTTreeModel ------------------------
00145 
00146 QtAstModel::QtAstModel(SgNode * node, QObject * p)
00147     : QAbstractItemModel(p),filter(NULL)
00148 {
00149     treeRoot = new ModelNode(node);
00150 }
00151 
00152 QtAstModel::~QtAstModel()
00153 {
00154     delete treeRoot;
00155     if(filter)
00156         delete filter;
00157 }
00158 
00159 
00160 void QtAstModel::setFilter(AstFilterInterface * f)
00161 {
00162     if(filter)
00163         delete filter;
00164 
00165     filter=f;
00166 
00167     treeRoot->deleteChildren();
00168     reset();
00169 }
00170 
00171 void QtAstModel::setNode(SgNode * node)
00172 {
00173     delete treeRoot;
00174     treeRoot = new ModelNode(node);
00175     reset();
00176 }
00177 
00178 Qt::ItemFlags QtAstModel::flags (const QModelIndex & i) const
00179 {
00180     if(!i.isValid())
00181         return 0;
00182 
00183     return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
00184 }
00185 
00186 QVariant QtAstModel::data  (const QModelIndex & ind, int role) const
00187 {
00188     if(!ind.isValid())
00189         return QVariant();
00190 
00191     ModelNode * node = static_cast<ModelNode *>(ind.internalPointer());
00192     Q_ASSERT(node);
00193 
00194     return node->data(role,ind.column());
00195 }
00196 
00197 QVariant QtAstModel::headerData (int section, Qt::Orientation orientation, int role) const
00198 {
00199     if(role == Qt::DisplayRole && orientation==Qt::Horizontal)
00200     {
00201         switch(section)
00202         {
00203             case 0:  return QString("Title");
00204             case 1:  return QString("SgClassName");
00205             default: return QVariant();
00206         }
00207     }
00208     return QVariant();
00209 }
00210 
00211 int  QtAstModel::columnCount (const QModelIndex & par) const
00212 {
00213     return 2;
00214 }
00215 
00216 int  QtAstModel::rowCount(const QModelIndex & par) const
00217 {
00218     //Root of the tree, one row..
00219     if(! par.isValid())
00220         return 1;
00221 
00222 
00223     //Only the first column has children
00224     if(par.column()>=1)
00225         return 0;
00226 
00227 
00228     ModelNode * node = static_cast<ModelNode *>(par.internalPointer());
00229     Q_ASSERT(node != NULL);
00230 
00231     if (!node->isBuildUp())
00232     {
00233         // build up the tree
00234         if(node->sgNode() != NULL) //test if it's a NULL leaf -> no children to buildup
00235         {
00236             std::vector< SgNode * >  successorPointer = node->sgNode()->get_traversalSuccessorContainer();
00237             std::vector< std::string > successorNames = node->sgNode()->get_traversalSuccessorNamesContainer();
00238 
00239             Q_ASSERT(successorPointer.size() == successorNames.size());
00240             for(unsigned int i=0; i < successorPointer.size(); i++)
00241             {
00242                 if(filter!=NULL)
00243                 {
00244                     if(! filter->displayNode(successorPointer[i]))
00245                         continue;
00246 
00247                 }
00248 
00249                 node->addChild(successorNames[i].c_str(),successorPointer[i]);
00250             }
00251         }
00252 
00253         node->buildUpFinished();
00254     }
00255 
00256     return node->childrenCount();
00257 }
00258 
00259 QModelIndex QtAstModel::index ( int row, int column, const QModelIndex & par) const
00260 {
00261     if(row<0 || column<0)
00262         return QModelIndex();
00263 
00264     if(row>= rowCount(par) || column>=columnCount(par))
00265         return QModelIndex();
00266 
00267     if(!par.isValid() )
00268     {
00269         Q_ASSERT(treeRoot!=NULL);
00270         return createIndex(row,column,treeRoot);
00271     }
00272     else
00273     {
00274         Q_ASSERT(par.internalPointer()!=NULL);
00275 
00276         ModelNode * parentNode = static_cast<ModelNode *>(par.internalPointer());
00277         Q_ASSERT(parentNode != NULL);
00278 
00279 
00280         Q_ASSERT(parentNode->isBuildUp());
00281         Q_ASSERT(parentNode->childrenCount() > row);
00282 
00283         return createIndex(row,column,parentNode->child(row));
00284     }
00285 }
00286 
00287 
00288 QModelIndex QtAstModel::parent ( const QModelIndex & ind ) const
00289 {
00290     if(! ind.isValid())
00291         return QModelIndex();
00292 
00293 
00294     ModelNode * node = static_cast<ModelNode *>(ind.internalPointer());
00295     Q_ASSERT(node != NULL);
00296 
00297     ItemTreeNode * parentNode = node->getParent();
00298     if(parentNode==NULL)
00299     {
00300         Q_ASSERT(node==treeRoot);
00301         return QModelIndex();
00302     }
00303 
00304     return createIndex(parentNode->getRow(),0,parentNode);
00305 }
00306 
00307 SgNode * QtAstModel::getNodeFromIndex(const QModelIndex & ind)
00308 {
00309     ModelNode * ret = static_cast<ModelNode *>(ind.internalPointer());
00310     Q_ASSERT(ret!=NULL);
00311     return ret->sgNode();
00312 }
00313 

Generated on Tue Sep 15 14:48:47 2009 for RoseQtWidgets by  doxygen 1.4.7