File indexing completed on 2024-05-05 04:48:48
0001 /**************************************************************************************** 0002 * Copyright (c) 2008-2010 Soren Harward <stharward@gmail.com> * 0003 * * 0004 * This program is free software; you can redistribute it and/or modify it under * 0005 * the terms of the GNU General Public License as published by the Free Software * 0006 * Foundation; either version 2 of the License, or (at your option) any later * 0007 * version. * 0008 * * 0009 * This program is distributed in the hope that it will be useful, but WITHOUT ANY * 0010 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * 0011 * PARTICULAR PURPOSE. See the GNU General Public License for more details. * 0012 * * 0013 * You should have received a copy of the GNU General Public License along with * 0014 * this program. If not, see <http://www.gnu.org/licenses/>. * 0015 ****************************************************************************************/ 0016 0017 #include "TreeModel.h" 0018 0019 #include "Constraint.h" 0020 #include "ConstraintFactory.h" 0021 0022 #include <KLocalizedString> 0023 0024 APG::TreeModel::TreeModel( ConstraintNode* r, QObject* p ) : QAbstractItemModel( p ), m_rootNode( r ) 0025 { 0026 if ( m_rootNode->getRowCount() < 1 ) 0027 ConstraintFactory::instance()->createGroup( m_rootNode, 0 ); 0028 0029 connectDCSlotToNode( m_rootNode ); 0030 } 0031 0032 APG::TreeModel::~TreeModel() 0033 { 0034 } 0035 0036 QVariant 0037 APG::TreeModel::data( const QModelIndex &index, int role ) const 0038 { 0039 if ( !index.isValid() || ( role != Qt::DisplayRole ) ) 0040 return QVariant(); 0041 0042 ConstraintNode* n = static_cast<ConstraintNode*>( index.internalPointer() ); 0043 if ( index.column() == 0 ) { 0044 return QVariant( n->getName() ); 0045 } else { 0046 return QVariant(); 0047 } 0048 } 0049 0050 Qt::ItemFlags 0051 APG::TreeModel::flags( const QModelIndex &index ) const 0052 { 0053 if ( !index.isValid() ) 0054 return {}; 0055 0056 return Qt::ItemIsEnabled | Qt::ItemIsSelectable; 0057 } 0058 0059 QVariant 0060 APG::TreeModel::headerData( int section, Qt::Orientation orientation, int role ) const 0061 { 0062 if ( orientation == Qt::Horizontal && role == Qt::DisplayRole ) { 0063 if ( section == 0 ) { 0064 return QVariant( i18n("Name") ); 0065 } else { 0066 return QVariant(); 0067 } 0068 } 0069 0070 return QVariant(); 0071 } 0072 0073 QModelIndex 0074 APG::TreeModel::index( int row, int column, const QModelIndex& parent ) const 0075 { 0076 if ( !hasIndex( row, column, parent ) ) 0077 return QModelIndex(); 0078 0079 ConstraintNode* parentItem; 0080 0081 if ( !parent.isValid() ) 0082 parentItem = m_rootNode; 0083 else 0084 parentItem = static_cast<ConstraintNode*>( parent.internalPointer() ); 0085 0086 ConstraintNode* childItem = parentItem->getChild( row ); 0087 if ( childItem ) 0088 return createIndex( row, column, childItem ); 0089 else 0090 return QModelIndex(); 0091 } 0092 0093 QModelIndex 0094 APG::TreeModel::parent( const QModelIndex& child ) const 0095 { 0096 if ( !child.isValid() ) 0097 return QModelIndex(); 0098 0099 ConstraintNode* childItem = static_cast<ConstraintNode*>( child.internalPointer() ); 0100 ConstraintNode* parentItem = static_cast<ConstraintNode*>( childItem->parent() ); 0101 0102 if ( !parentItem || parentItem == m_rootNode ) 0103 return QModelIndex(); 0104 0105 return createIndex( parentItem->row(), 0, parentItem ); 0106 } 0107 0108 int 0109 APG::TreeModel::rowCount( const QModelIndex& parent ) const 0110 { 0111 if ( parent.column() > 0 ) 0112 return 0; 0113 0114 ConstraintNode* parentItem; 0115 if ( !parent.isValid() ) 0116 parentItem = m_rootNode; 0117 else 0118 parentItem = static_cast<ConstraintNode*>( parent.internalPointer() ); 0119 0120 return parentItem->getRowCount(); 0121 } 0122 0123 bool 0124 APG::TreeModel::removeNode( const QModelIndex& index ) 0125 { 0126 int row = index.row(); 0127 bool r = false; 0128 0129 QModelIndex parentIndex = index.parent(); 0130 // prevent removal of root node 0131 if ( parentIndex.isValid() ) { 0132 ConstraintNode* parent; 0133 parent = static_cast<ConstraintNode*>( parentIndex.internalPointer() ); 0134 beginRemoveRows( parentIndex, row, row ); 0135 r = parent->removeChild( row ); 0136 endRemoveRows(); 0137 return r; 0138 } else { 0139 return r; 0140 } 0141 } 0142 0143 QModelIndex 0144 APG::TreeModel::insertGroup( const QModelIndex& thisIdx ) 0145 { 0146 int row = thisIdx.row(); 0147 ConstraintNode* p = nullptr; 0148 ConstraintNode* n = nullptr; 0149 0150 if ( thisIdx.isValid() ) 0151 p = static_cast<ConstraintNode*>( thisIdx.internalPointer() ); 0152 else 0153 p = m_rootNode; 0154 0155 if ( p->getNodeType() == Constraint::ConstraintGroupType ) { 0156 beginInsertRows( thisIdx, 0, 0 ); 0157 n = ConstraintFactory::instance()->createGroup( p, 0 ); 0158 endInsertRows(); 0159 if ( n != nullptr ) { 0160 connectDCSlotToNode( n ); 0161 return createIndex( 0, 0, n ); 0162 } 0163 } else { 0164 p = p->parent(); 0165 QModelIndex parentIdx = parent( thisIdx ); 0166 beginInsertRows( parentIdx, row + 1, row + 1 ); 0167 n = ConstraintFactory::instance()->createGroup( p, row + 1 ); 0168 endInsertRows(); 0169 if ( n != nullptr ) { 0170 connectDCSlotToNode( n ); 0171 return createIndex( row + 1, 0, n ); 0172 } 0173 } 0174 return thisIdx; 0175 } 0176 0177 QModelIndex 0178 APG::TreeModel::insertConstraint( const QModelIndex& thisIdx, const QString& constraintName ) 0179 { 0180 int row = thisIdx.row(); 0181 if ( thisIdx.isValid() ) { 0182 ConstraintNode* p = static_cast<ConstraintNode*>( thisIdx.internalPointer() ); 0183 ConstraintNode* n = nullptr; 0184 if ( p->getNodeType() == Constraint::ConstraintGroupType ) { 0185 beginInsertRows( thisIdx, 0, 0 ); 0186 QString constraintType = ConstraintFactory::instance()->untranslateName( constraintName ); 0187 n = ConstraintFactory::instance()->createConstraint( constraintType, p, 0 ); 0188 endInsertRows(); 0189 if ( n != nullptr ) { 0190 connectDCSlotToNode( n ); 0191 return createIndex( 0, 0, n ); 0192 } 0193 } else { 0194 p = p->parent(); 0195 QModelIndex parentIdx = parent( thisIdx ); 0196 beginInsertRows( parentIdx, row + 1, row + 1 ); 0197 QString constraintType = ConstraintFactory::instance()->untranslateName( constraintName ); 0198 n = ConstraintFactory::instance()->createConstraint( constraintType, p, row + 1 ); 0199 endInsertRows(); 0200 if ( n != nullptr ) { 0201 connectDCSlotToNode( n ); 0202 return createIndex( row + 1, 0, n ); 0203 } 0204 } 0205 } 0206 return thisIdx; 0207 } 0208 0209 void 0210 APG::TreeModel::slotConstraintDataChanged() 0211 { 0212 ConstraintNode* n = static_cast<ConstraintNode*>( sender() ); 0213 if ( n ) { 0214 QModelIndex idx = createIndex( n->row(), 0, n ); 0215 Q_EMIT dataChanged( idx, idx ); 0216 } 0217 } 0218 0219 void 0220 APG::TreeModel::connectDCSlotToNode( ConstraintNode* n ) 0221 { 0222 if ( n ) { 0223 connect( n, &ConstraintNode::dataChanged, this, &TreeModel::slotConstraintDataChanged ); 0224 int rc = n->getRowCount(); 0225 for ( int i = 0; i < rc; i++ ) { 0226 connectDCSlotToNode( n->getChild( i ) ); 0227 } 0228 } 0229 }