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