treemodel.cpp
author insilmaril
Wed, 03 Jun 2009 20:37:17 +0000
changeset 775 6e4b586aa88a
parent 773 340bc29da9a0
child 776 25e634a7e1dc
permissions -rw-r--r--
Unscrolling temporary works again
     1 #include <QtGui>
     2 
     3 #include <iostream>
     4 using namespace std;
     5 
     6 #include "branchitem.h"
     7 #include "treeitem.h"
     8 #include "treemodel.h"
     9 
    10 TreeModel::TreeModel(QObject *parent)
    11     : QAbstractItemModel(parent)
    12 {
    13     QList<QVariant> rootData;
    14     rootData << "Heading" << "Type" <<"Note";
    15     rootItem = new TreeItem(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::ItemIsEnabled;
    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(int row, int column, const QModelIndex &parent)
    54             const
    55 {
    56     TreeItem *parentItem;
    57 
    58     if (!parent.isValid())
    59         parentItem = rootItem;
    60     else
    61         parentItem = getItem (parent);
    62 
    63     TreeItem *childItem = parentItem->child(row);
    64     if (childItem)
    65         return createIndex(row, column, childItem);
    66     else
    67         return QModelIndex();
    68 }
    69 
    70 QModelIndex TreeModel::parent(const QModelIndex &index) const
    71 {
    72     if (!index.isValid())
    73         return QModelIndex();
    74 
    75     TreeItem *ti= getItem (index);
    76     TreeItem *parentItem = ti->parent();
    77 
    78 	//cout << "TreeModel::parent  ti="<<ti<<" "<<ti->getHeading().toStdString()<<"  pi="<<parentItem<<"  "<<endl;
    79     if (parentItem == rootItem)
    80         return QModelIndex();
    81 
    82 	if (!parentItem)
    83         return QModelIndex();	// FIXME-3 do this to avoid segfault, but why?
    84 		                        // see also my question on qt-interest in march
    85 
    86     return createIndex(parentItem->childNumber(), 0, parentItem);
    87 }
    88 
    89 int TreeModel::rowCount(const QModelIndex &parent) const
    90 {
    91     TreeItem *parentItem;
    92 
    93     if (!parent.isValid())
    94         parentItem = rootItem;
    95     else
    96         parentItem = getItem (parent);
    97 
    98     return parentItem->childCount();
    99 }
   100 
   101 int TreeModel::columnCount(const QModelIndex &parent) const
   102 {
   103     if (parent.isValid())
   104         return getItem (parent)->columnCount();
   105     else
   106         return rootItem->columnCount();
   107 }
   108 
   109 BranchItem* TreeModel::next(BranchItem* &current, BranchItem* &previous, BranchItem* start)
   110 {
   111 	// Walk through map beginning at current with previous==0
   112 	// Start at root, if current==NULL
   113 	if (!current) current=(BranchItem*)rootItem;
   114 
   115 	// Are we just beginning to walk the map?
   116 	if (!previous)
   117 	{
   118 		if (!start) start=current;
   119 		previous=current;
   120 		current=current->getFirstBranch();
   121 		return current;
   122 	}
   123 
   124 	//std::cout << " cur="<<current->getHeading().toStdString();
   125 	//std::cout << " prev="<<previous->getHeading().toStdString()<<std::endl;
   126 
   127 	// Going up or down (deeper)?
   128 	if (current->depth() > previous->depth() )
   129 	{	
   130 		// Coming from above
   131 		// Trying  to go down deeper
   132 		if (current->branchCount() >0 )
   133 		{
   134 			previous=current;
   135 			current=current->getFirstBranch();
   136 			return current;
   137 		}	
   138 		// turn around and go up again
   139 	}	
   140 
   141 	// Coming from below
   142 
   143 	// Trying to go down again to siblings
   144 
   145 	BranchItem *sibling=current->getBranchNum (previous->num()+1);
   146 
   147 	if (sibling)
   148 	{	
   149 		// Found sibling of previous, go there
   150 		previous=current;
   151 		current=sibling;
   152 		return current;
   153 	} 
   154 
   155 	// If we only needed to go through subtree, we are done now
   156 	if (start==current) return NULL;
   157 
   158 	// Go up and try to find siblings of current
   159 	previous=current;
   160 	current=(BranchItem*)current->parent();
   161 
   162 	// Check if we still can go somewhere
   163 	if (!current) return current;
   164 	
   165 	while (current && current->depth() < previous->depth() )
   166 		current=next (current,previous,start);
   167 		
   168 	return current;
   169 }
   170 
   171 bool TreeModel::removeRows ( int row, int count, const QModelIndex & parent)
   172 {
   173 	int last=row+count-1;
   174     TreeItem *pi= getItem (parent);
   175 	TreeItem *ti;
   176 
   177 	for (int i=row; i<=last; i++)
   178 	{
   179 		ti=pi->getChildNum (row);
   180 		pi->removeChild (row);	// does not delete object!
   181 		switch (ti->getType()) 
   182 		{
   183 			case TreeItem::MapCenter: 
   184 				delete (BranchItem*)ti; 
   185 				break;
   186 			case TreeItem::Branch:
   187 				delete (BranchItem*)ti; 
   188 				break;
   189 			default:
   190 				delete ti;
   191 				break;
   192 		}
   193 	}
   194 	return true;
   195 }
   196 
   197 TreeItem *TreeModel::getItem(const QModelIndex &index) const
   198 {
   199     if (index.isValid()) {
   200 		TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
   201 
   202         if (item) return item;
   203     }
   204     return rootItem;
   205 }
   206 
   207 TreeItem *TreeModel::getRootItem()
   208 {
   209 	return rootItem;
   210 }
   211 
   212 QModelIndex TreeModel::index (TreeItem* ti)
   213 {
   214 	return createIndex (ti->row(),ti->column(),ti);
   215 }
   216