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