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