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