Blokkal
an Extendable KDE Blogging Client
SourceForge.net Logo

blokkaltreemodel.cpp

00001 /***************************************************************************
00002  *   Copyright (C) 2007 by Martin Mueller                                  *
00003  *   orvio@orvio.de                                                        *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU General Public License as published by  *
00007  *   the Free Software Foundation; either version 2 of the License, or     *
00008  *   (at your option) any later version.                                   *
00009  *                                                                         *
00010  *   This program is distributed in the hope that it will be useful,       *
00011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00013  *   GNU General Public License for more details.                          *
00014  *                                                                         *
00015  *   You should have received a copy of the GNU General Public License     *
00016  *   along with this program; if not, write to the                         *
00017  *   Free Software Foundation, Inc.,                                       *
00018  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
00019  ***************************************************************************/
00020 #include "blokkaltreemodel.h"
00021 #include "blokkaltreemodel.moc"
00022 
00023 #include <kdebug.h>
00024 
00025 Blokkal::TreeModel::TreeItemNode::TreeItemNode( TreeItemNode * parent, void * data ):
00026 parent( parent ),
00027 data( QVariant::fromValue( (qulonglong) data ) ),
00028 checked( Qt::Unchecked ){
00029         if( parent ) {
00030                 parent->children.append( this );
00031         }
00032 }
00033 
00034 Blokkal::TreeModel::TreeItemNode::~TreeItemNode( void )
00035 {
00036         qDeleteAll( children );
00037 }
00038 
00039 class Blokkal::TreeModel::Private {
00040 public:
00041         Private( TreeItemNode * root ) :
00042         root( root ){}
00043 
00044         ~Private( void ) {
00045                 delete root;
00046         }
00047 
00048         TreeItemNode * const root;
00049 };
00050 
00051 Blokkal::TreeModel::TreeModel( Blokkal::TreeModel::TreeItemNode * root, QObject * parent ):
00052 QAbstractItemModel( parent ),
00053 d(new Private( root ? root : new TreeItemNode( 0, 0 ) ) )
00054 {
00055 }
00056 
00057 Blokkal::TreeModel::~TreeModel( void )
00058 {
00059         delete d;
00060 }
00061 
00062 QModelIndex Blokkal::TreeModel::index( int row, int column, const QModelIndex & parent ) const
00063 {
00064         if ( !hasIndex( row, column, parent ) ) {
00065                 return QModelIndex();
00066         }
00067 
00068         TreeItemNode * parentNode;
00069 
00070         if ( !parent.isValid() ) {
00071                 parentNode = d->root;
00072         }
00073         else {
00074                 parentNode = static_cast<TreeItemNode*>( parent.internalPointer() );
00075         }
00076 
00077 
00078         TreeItemNode * childNode = parentNode->children.at( row );
00079         if( childNode ) {
00080                 return createIndex( row, column, childNode );
00081         }
00082         
00083         return QModelIndex();   
00084 }
00085 
00086 QModelIndex Blokkal::TreeModel::parent( const QModelIndex & index ) const
00087 {
00088         if ( !index.isValid() ) {
00089                  return QModelIndex();
00090         }
00091 
00092         TreeItemNode * childNode = static_cast<TreeItemNode*>( index.internalPointer() );
00093         TreeItemNode * parentNode = childNode->parent;
00094 
00095         if( parentNode == d->root ) {
00096                 return QModelIndex();
00097         }
00098 
00099         if( childNode == d->root ) {
00100                 kError() << "parent of root requested" << endl;
00101                 return QModelIndex();
00102         }
00103 
00104         return createIndex( parentNode->parent->children.indexOf(parentNode), 0, parentNode );
00105 }
00106 
00107 int Blokkal::TreeModel::rowCount( const QModelIndex & parent ) const
00108 {
00109         TreeItemNode * parentNode;
00110         if( parent.column() > 0 ) {
00111                 return 0;
00112         }
00113  
00114         if ( !parent.isValid() ) {
00115                 parentNode = d->root;
00116         }
00117         else {
00118                 parentNode = static_cast<TreeItemNode*>( parent.internalPointer() );
00119         }
00120 
00121         return parentNode->children.size();     
00122 }
00123 
00124 int Blokkal::TreeModel::columnCount( const QModelIndex & parent ) const
00125 {
00126         Q_UNUSED( parent );
00127         return 1;
00128 }
00129 
00130 QVariant Blokkal::TreeModel::data( const QModelIndex & index, int role ) const
00131 {
00132         if( !index.isValid() ) {
00133                 return QVariant();
00134         }
00135 
00136         if( role == Qt::DisplayRole ) {
00137                 return static_cast<TreeItemNode*>(index.internalPointer())->data;
00138         }
00139         if( role == Qt::CheckStateRole ) {
00140                 return static_cast<TreeItemNode*>(index.internalPointer())->checked;
00141         }
00142 
00143         return QVariant();
00144 }
00145 
00146 Blokkal::TreeModel::TreeItemNode * Blokkal::TreeModel::root( void ) const
00147 {
00148         return d->root;
00149 }
00150 
00151 Qt::ItemFlags Blokkal::TreeModel::flags( const QModelIndex & index ) const
00152 {
00153         if (!index.isValid()) {
00154                 return Qt::ItemIsEnabled;
00155         }
00156         
00157         return QAbstractItemModel::flags(index) | Qt::ItemIsUserCheckable;
00158 }
00159 
00160 bool Blokkal::TreeModel::setData( const QModelIndex & index, const QVariant & value, int role )
00161 {
00162         if( role != Qt::CheckStateRole ) {
00163                 return FALSE;
00164         }
00165 
00166         if( !index.isValid() ) {
00167                 return FALSE;
00168         }
00169 
00170         if( !value.isValid() ) {
00171                 return FALSE;
00172         }
00173 
00174         static_cast<TreeItemNode*>(index.internalPointer())->checked = static_cast<Qt::CheckState>( value.toInt() );
00175         emit dataChanged( index, index );
00176         return TRUE;
00177 }