treemodel.cpp
author insilmaril
Fri, 09 Apr 2010 14:24:04 +0000
changeset 846 f0fe7c36ec5c
parent 825 1ad892c1a709
child 847 43268373032d
permissions -rw-r--r--
Version 1.13.3 and added treeeditor.png
     1 #include <QtGui>
     2 
     3 #include "attributeitem.h"
     4 #include "branchitem.h"
     5 #include "imageitem.h"
     6 #include "treeitem.h"
     7 #include "treemodel.h"
     8 #include "xlinkitem.h"
     9 
    10 TreeModel::TreeModel(QObject *parent)
    11     : QAbstractItemModel(parent)
    12 {
    13     QList<QVariant> rootData;
    14     rootData << "Heading" << "Type";
    15     rootItem = new BranchItem(rootData);
    16 }
    17 
    18 TreeModel::~TreeModel()
    19 {
    20     delete rootItem;
    21 }
    22 
    23 QVariant TreeModel::data(const QModelIndex &index, int role) const
    24 {
    25     if (!index.isValid())
    26         return QVariant();
    27 
    28     if (role != Qt::DisplayRole)
    29         return QVariant();
    30 
    31     TreeItem *item = getItem (index);
    32 
    33     return item->data(index.column());
    34 }
    35 
    36 Qt::ItemFlags TreeModel::flags(const QModelIndex &index) const
    37 {
    38     if (!index.isValid())
    39         return Qt::NoItemFlags;
    40 
    41     return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
    42 }
    43 
    44 QVariant TreeModel::headerData(int section, Qt::Orientation orientation,
    45                                int role) const
    46 {
    47     if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
    48         return rootItem->data(section);
    49 
    50     return QVariant();
    51 }
    52 
    53 QModelIndex TreeModel::index (TreeItem* ti)
    54 {
    55 	if (!ti->parent())
    56 		return QModelIndex();
    57 	else	
    58 		return createIndex (ti->row(),0,ti);
    59 }
    60 
    61 QModelIndex TreeModel::index(int row, int column, const QModelIndex &parent)
    62             const
    63 {
    64 	// Make sure to return invalid index for invalid values (see modeltest)
    65 	if (row<0 || column<0) return QModelIndex();
    66 	if (column!=0) return QModelIndex();
    67 
    68     TreeItem *parentItem;
    69 
    70     if (!parent.isValid())
    71 	{
    72         parentItem = rootItem;
    73 		/*
    74 		cout << "TM::index()  no parent?! xxx\n";
    75 		cout << "   row="<<row<<"  col="<<column<<endl;
    76 		cout << "   parent.internal="<< parent.internalPointer()<<endl;
    77 		*/
    78 		// Somehow index is requested where parentIndex is invalid.
    79 		// what's happening here...?
    80 		// Check if Qt examples also return index of rootIem then...
    81 
    82 	}	
    83     else
    84         parentItem = getItem (parent);
    85 
    86     TreeItem *childItem = parentItem->child(row);
    87 	//cout << "TM::index  parentItem="<<parentItem<<"  childItem="<<childItem<<"  row="<<row<<" col="<<column<<endl;
    88     if (childItem)
    89         return createIndex(row, column, childItem);
    90     else
    91         return QModelIndex();
    92 }
    93 
    94 QModelIndex TreeModel::parent(const QModelIndex &index) const
    95 {
    96     if (!index.isValid())
    97         return QModelIndex();
    98 
    99 	//FIXME-3 cout << "TM::parent  ri="<<rootItem<< "  row="<<index.row()<<"  col="<<index.column()<<endl;
   100     TreeItem *ti= getItem (index);
   101 	//cout << "            ti="<<ti<<endl;
   102 	//cout << "               "<<ti->getHeadingStd()<<endl;
   103     TreeItem *parentItem = ti->parent();
   104 	//cout << "            pi="<<parentItem<<endl;
   105 
   106 	//cout << "TreeModel::parent  ti="<<ti<<" "<<ti->getHeading().toStdString()<<"  pi="<<parentItem<<"  "<<endl;
   107     if (parentItem == rootItem)
   108         return QModelIndex();
   109 
   110 /*
   111 	if (!parentItem)
   112         return QModelIndex();	// FIXME-3 do this to avoid segfault, but why?
   113 		                        // see also my question on qt-interest in march
   114 */
   115     return createIndex(parentItem->childNumber(), 0, parentItem);
   116 }
   117 
   118 int TreeModel::rowCount(const QModelIndex &parent) const
   119 {
   120     TreeItem *parentItem;
   121 
   122     if (!parent.isValid())
   123         parentItem = rootItem;
   124     else
   125         parentItem = getItem (parent);
   126 
   127     return parentItem->childCount();
   128 }
   129 
   130 int TreeModel::columnCount(const QModelIndex &parent) const
   131 {
   132 	int c;
   133     if (parent.isValid())
   134 	{
   135         c= getItem (parent)->columnCount();
   136 		//cout << "TM::colCount  c="<<c<<"  parent="<<getItem (parent)<<endl;	
   137 	}
   138     else
   139 	{
   140         c= rootItem->columnCount();
   141 		//cout << "TM::colCount  c="<<c<<"  parent=invalid"<<endl;	
   142 	}
   143 	return c;
   144 }
   145 
   146 BranchItem* TreeModel::nextBranch (BranchItem* &current, BranchItem* &previous, bool deepLevelsFirst, BranchItem *start)	
   147 {
   148 	// Walk through map beginning at current with previous==0
   149 	// Start at root, if current==NULL
   150 	if (!current) current=(BranchItem*)rootItem;
   151 
   152 	// Are we just beginning to walk the map?
   153 	if (!previous)
   154 	{
   155 		if (!start) start=current;
   156 		previous=current;
   157 		current=current->getFirstBranch();
   158 		return current;
   159 	}
   160 	if (deepLevelsFirst)
   161 	{
   162 		// Going up or down (deeper)?
   163 		if (current->depth() > previous->depth() )
   164 		{	
   165 			// Coming from above
   166 			// Trying  to go down deeper
   167 			if (current->branchCount() >0 )
   168 			{
   169 				previous=current;
   170 				current=current->getFirstBranch();
   171 				return current;
   172 			}	
   173 			// turn around and go up again
   174 			BranchItem *bi=current;
   175 			current=previous;
   176 			previous=bi;
   177 		}	
   178 
   179 		// Coming from below
   180 		// Trying to go down again to siblings
   181 
   182 		BranchItem *sibling=current->getBranchNum (previous->num()+1);
   183 
   184 		if (sibling)
   185 		{	
   186 			// Found sibling of previous, go there
   187 			previous=current;
   188 			current=sibling;
   189 			return current;
   190 		} 
   191 
   192 		// If we only needed to go through subtree, we are done now
   193 		if (start==current) return NULL;
   194 
   195 		// Go up and try to find siblings of current
   196 		previous=current;
   197 		current=(BranchItem*)current->parent();
   198 
   199 		// Check if we still can go somewhere
   200 		if (!current) return current;
   201 		
   202 		while (current && current->depth() < previous->depth() )
   203 			current=nextBranch (current,previous,true,start);
   204 			
   205 		return current;
   206 
   207 	} else
   208 	{
   209 /*FIXME-3
   210 		cout << "TM::nextBranch shallow\n"; 
   211 		std::string ch="()"; if (current) ch=current->getHeadingStd();
   212 		std::string ph="()"; if (previous) ph=previous->getHeadingStd();
   213 		cout << "  cur="<<ch << " prev="<<ph<<endl;
   214 */
   215 
   216 		// Try to find sibling with same depth
   217 		BranchItem *sibling=current->parent()->getBranchNum (current->num()+1);
   218 		if (sibling)
   219 		{	
   220 			// Found sibling of previous, go there
   221 			previous=current;
   222 			current=sibling;
   223 			return current;
   224 		}  else
   225 		{	
   226 			// Try to find next branch with same depth or greater
   227 			
   228 
   229 			current=NULL;
   230 			return current;
   231 		}
   232 
   233 
   234 		/*
   235 	while (ix.isValid())
   236 	{
   237 		TreeItem *ti=model->getItem (ix);
   238 		cout << "  level="<<level<<"  ix=";
   239 		if (ti) cout << ti->getHeadingStd();
   240 		row=ix.row();
   241 		col=ix.column();
   242 		if (! treeEditor->isExpanded(ix))
   243 			cout <<"  expand!";
   244 		else	
   245 			cout <<"  is expanded.";
   246 		cout <<endl;
   247 		ix=ix.sibling(row+1,col);
   248 	}
   249 	*/
   250 
   251 	}
   252 }
   253 
   254 bool TreeModel::removeRows ( int row, int count, const QModelIndex & parent)
   255 {
   256 	int last=row+count-1;
   257     TreeItem *pi;
   258 	if (parent.isValid())
   259 		pi=getItem (parent);
   260 	else
   261 		pi=rootItem;
   262 	TreeItem *ti;
   263 
   264 	//cout << "TM::removeRows  pi="<<pi<<"  row="<<row<<"  count="<<count<<endl;
   265 	for (int i=row; i<=last; i++)
   266 	{
   267 		ti=pi->getChildNum (row);
   268 		pi->removeChild (row);	// does not delete object!
   269 		delete ti;
   270 	}
   271 	return true;
   272 }
   273 
   274 TreeItem *TreeModel::getItem(const QModelIndex &index) const
   275 {
   276     if (index.isValid()) {
   277 		TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
   278         if (item) return item;
   279     }
   280     return NULL;
   281 }
   282 
   283 BranchItem *TreeModel::getRootItem()
   284 {
   285 	return rootItem;
   286 }
   287