treemodel.cpp
author insilmaril
Thu, 03 Sep 2009 08:52:00 +0000
changeset 790 133e2ed6b9c5
parent 789 d85834ad8c54
child 791 f1006de05c54
permissions -rw-r--r--
More work on xLinks
     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 TreeItem(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::ItemIsEnabled;
    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(),ti->column(),ti);
    62 }
    63 
    64 QModelIndex TreeModel::index(int row, int column, const QModelIndex &parent)
    65             const
    66 {
    67     TreeItem *parentItem;
    68 
    69     if (!parent.isValid())
    70 	{	//FIXME-3 left here for testing only, seems to work now...
    71         parentItem = rootItem;
    72 		/*
    73 		cout << "TM::index()  no parent?! xxx\n";
    74 		cout << "   row="<<row<<"  col="<<column<<endl;
    75 		cout << "   parent.internal="<< parent.internalPointer()<<endl;
    76 		*/
    77 		//return QModelIndex();	//FIXME-3 this line is new (testing)
    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     if (childItem)
    88         return createIndex(row, column, childItem);
    89     else
    90         return QModelIndex();
    91 }
    92 
    93 QModelIndex TreeModel::parent(const QModelIndex &index) const
    94 {
    95     if (!index.isValid())
    96         return QModelIndex();
    97 
    98 	//FIXME-3 cout << "TM::parent  ri="<<rootItem<< "  row="<<index.row()<<"  col="<<index.column()<<endl;
    99     TreeItem *ti= getItem (index);
   100 	//cout << "            ti="<<ti<<endl;
   101 	//cout << "               "<<ti->getHeadingStd()<<endl;
   102     TreeItem *parentItem = ti->parent();
   103 	//cout << "            pi="<<parentItem<<endl;
   104 
   105 	//cout << "TreeModel::parent  ti="<<ti<<" "<<ti->getHeading().toStdString()<<"  pi="<<parentItem<<"  "<<endl;
   106     if (parentItem == rootItem)
   107         return QModelIndex();
   108 
   109 	if (!parentItem)
   110         return QModelIndex();	// FIXME-3 do this to avoid segfault, but why?
   111 		                        // see also my question on qt-interest in march
   112 
   113     return createIndex(parentItem->childNumber(), 0, parentItem);
   114 }
   115 
   116 int TreeModel::rowCount(const QModelIndex &parent) const
   117 {
   118     TreeItem *parentItem;
   119 
   120     if (!parent.isValid())
   121         parentItem = rootItem;
   122     else
   123         parentItem = getItem (parent);
   124 
   125     return parentItem->childCount();
   126 }
   127 
   128 int TreeModel::columnCount(const QModelIndex &parent) const
   129 {
   130     if (parent.isValid())
   131         return getItem (parent)->columnCount();
   132     else
   133         return rootItem->columnCount();
   134 }
   135 
   136 BranchItem* TreeModel::next(BranchItem* &current, BranchItem* &previous, BranchItem* start)
   137 {
   138 /*FIXME-3	cout << "TM::next \n"; 
   139 	std::string ch="()"; if (current) ch=current->getHeadingStd();
   140 	std::string ph="()"; if (previous) ph=previous->getHeadingStd();
   141 	cout << "  cur="<<ch << " prev="<<ph<<endl;
   142 */
   143 
   144 	// Walk through map beginning at current with previous==0
   145 	// Start at root, if current==NULL
   146 	if (!current) current=(BranchItem*)rootItem;
   147 
   148 	// Are we just beginning to walk the map?
   149 	if (!previous)
   150 	{
   151 		if (!start) start=current;
   152 		previous=current;
   153 		current=current->getFirstBranch();
   154 		return current;
   155 	}
   156 
   157 	// Going up or down (deeper)?
   158 	if (current->depth() > previous->depth() )
   159 	{	
   160 		// Coming from above
   161 		// Trying  to go down deeper
   162 //		cout << "  trying to go deeper\n";
   163 		if (current->branchCount() >0 )
   164 		{
   165 //			cout << "  yes, going deeper\n";
   166 			previous=current;
   167 			current=current->getFirstBranch();
   168 			return current;
   169 		}	
   170 		// turn around and go up again
   171 //		cout << "  sorry, turn around\n";
   172 		BranchItem *bi=current;
   173 		current=previous;
   174 		previous=bi;
   175 	}	
   176 
   177 /*
   178 	cout << "  coming from below\n";
   179 	ch="()"; if (current) ch=current->getHeadingStd();
   180 	ph="()"; if (previous) ph=previous->getHeadingStd();
   181 	cout << "  cur="<<ch << " prev="<<ph<<endl;
   182 */	
   183 	// Coming from below
   184 	// Trying to go down again to siblings
   185 
   186 	BranchItem *sibling=current->getBranchNum (previous->num()+1);
   187 //	cout <<"    prev->num()="<<previous->num()<<endl;
   188 
   189 	if (sibling)
   190 	{	
   191 		// Found sibling of previous, go there
   192 //		cout << "  sib=cur="<<sibling->getHeadingStd()<<endl;
   193 		previous=current;
   194 		current=sibling;
   195 		return current;
   196 	} 
   197 
   198 	// If we only needed to go through subtree, we are done now
   199 	if (start==current) return NULL;
   200 
   201 	// Go up and try to find siblings of current
   202 //	cout <<"  going up again...\n";
   203 	previous=current;
   204 	current=(BranchItem*)current->parent();
   205 
   206 	// Check if we still can go somewhere
   207 	if (!current) return current;
   208 	
   209 	while (current && current->depth() < previous->depth() )
   210 		current=next (current,previous,start);
   211 		
   212 	return current;
   213 }
   214 
   215 bool TreeModel::removeRows ( int row, int count, const QModelIndex & parent)
   216 {
   217 	int last=row+count-1;
   218     TreeItem *pi= getItem (parent);
   219 	TreeItem *ti;
   220 
   221 	cout << "TM::removeRows  row="<<row<<"  count="<<count<<endl;
   222 	for (int i=row; i<=last; i++)
   223 	{
   224 		ti=pi->getChildNum (row);
   225 		cout << "   pi="<<pi<<"  ti="<<ti<<endl;
   226 		pi->removeChild (row);	// does not delete object!
   227 		switch (ti->getType()) 
   228 		{
   229 			case TreeItem::MapCenter: 
   230 				delete (BranchItem*)ti; 
   231 				break;
   232 			case TreeItem::Branch:
   233 				delete (BranchItem*)ti; 
   234 				break;
   235 			case TreeItem::Image:
   236 				delete (ImageItem*)ti; 
   237 				break;
   238 			case TreeItem::Attribute:
   239 				delete (AttributeItem*)ti; 
   240 				break;
   241 			case TreeItem::XLink:
   242 				delete (XLinkItem*)ti; 
   243 				break;
   244 			default:
   245 				delete ti;
   246 				break;
   247 		}
   248 	}
   249 	return true;
   250 }
   251 
   252 TreeItem *TreeModel::getItem(const QModelIndex &index) const
   253 {
   254 //FIXME-3	cout << "TM::getItem  "<<index.internalPointer()<<endl;
   255     if (index.isValid()) {
   256 		TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
   257 
   258 //		cout << "   item="<<item<<endl;
   259         if (item) return item;
   260     }
   261     return rootItem;
   262 }
   263 
   264 TreeItem *TreeModel::getRootItem()
   265 {
   266 	return rootItem;
   267 }
   268