treemodel.cpp
author insilmaril
Thu, 30 Apr 2009 11:52:49 +0000
changeset 762 ffb95cd03156
parent 760 59614eaf5fbb
child 772 e3f722759c7e
permissions -rw-r--r--
further speedup during load. positions of branches are saved (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, int &d0)
   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 		previous=current;
   119 		d0=current->depth();
   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 	// Trying to go down again to siblings
   143 
   144 	BranchItem *sibling=current->getBranchNum (previous->num()+1);
   145 
   146 	if (sibling)
   147 	{	
   148 		// Found sibling of previous, go there
   149 		previous=current;
   150 		current=sibling;
   151 		return current;
   152 	} 
   153 
   154 	// Go up and try to find siblings of current
   155 	previous=current;
   156 	current=(BranchItem*)current->parent();
   157 
   158 	// Check if we still can go somewhere
   159 	if (!current) return current;
   160 	
   161 	while (current && current->depth() < previous->depth() )
   162 		next (current,previous,d0);
   163 		
   164 	return current;
   165 }
   166 
   167 bool TreeModel::insertRows ( int row, int count, const QModelIndex & parent)
   168 {
   169 	std::cout << "TreeModel insertRows()\n";
   170 	int last=row+count-1;
   171 	beginInsertRows (parent,row,last);
   172 
   173 	for (int i=row; i<=last; i++)
   174 	{
   175 		std::cout << "TreeModel::insertRows inserting i="<<i<<std::endl;
   176 	}
   177 	endInsertRows ();
   178 	return true;
   179 }
   180 
   181 bool TreeModel::removeRows ( int row, int count, const QModelIndex & parent)
   182 {
   183 	int last=row+count-1;
   184     TreeItem *pi= getItem (parent);
   185 	TreeItem *ti;
   186 
   187 	for (int i=row; i<=last; i++)
   188 	{
   189 		ti=pi->getChildNum (row);
   190 		pi->removeChild (row);	// does not delete object!
   191 		switch (ti->getType()) 
   192 		{
   193 			case TreeItem::MapCenter: 
   194 				delete (BranchItem*)ti; 
   195 				break;
   196 			case TreeItem::Branch:
   197 				delete (BranchItem*)ti; 
   198 				break;
   199 			default:
   200 				delete ti;
   201 				break;
   202 		}
   203 	}
   204 	return true;
   205 }
   206 
   207 TreeItem *TreeModel::getItem(const QModelIndex &index) const
   208 {
   209     if (index.isValid()) {
   210 		TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
   211 
   212         if (item) return item;
   213     }
   214     return rootItem;
   215 }
   216 
   217 TreeItem *TreeModel::getRootItem()
   218 {
   219 	return rootItem;
   220 }
   221 
   222 QModelIndex TreeModel::index (TreeItem* ti)
   223 {
   224 	return createIndex (ti->row(),ti->column(),ti);
   225 }
   226