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