void AbstractTreeItem::removeAllChilds() { const int numChilds = childCount(); if(numChilds == 0) return; AbstractTreeItem *child; QList<AbstractTreeItem *>::iterator childIter; childIter = _childItems.begin(); while(childIter != _childItems.end()) { child = *childIter; child->setTreeItemFlags(0); // disable self deletion, as this would only f**k up consitency and the child gets deleted anyways child->removeAllChilds(); childIter++; } emit beginRemoveChilds(0, numChilds - 1); childIter = _childItems.begin(); while(childIter != _childItems.end()) { child = *childIter; childIter = _childItems.erase(childIter); delete child; } emit endRemoveChilds(); checkForDeletion(); }
bool AbstractTreeItem::reParent(AbstractTreeItem *newParent) { // currently we support only re parenting if the child that's about to be // adopted does not have any children itself. if(childCount() != 0) { qDebug() << "AbstractTreeItem::reParent(): cannot reparent" << this << "with children."; return false; } int oldRow = row(); if(oldRow == -1) return false; emit parent()->beginRemoveChilds(oldRow, oldRow); parent()->_childItems.removeAt(oldRow); emit parent()->endRemoveChilds(); AbstractTreeItem *oldParent = parent(); setParent(newParent); bool success = newParent->newChild(this); if(!success) qWarning() << "AbstractTreeItem::reParent(): failed to attach to new parent after removing from old parent! this:" << this << "new parent:" << newParent; if(oldParent) oldParent->checkForDeletion(); return success; }
QModelIndex Model::parent( const QModelIndex & child ) const { /* parent() Provides a model index corresponding to the parent of any given child item. If the model index specified corresponds to a top-level item in the model, or if there is no valid parent item in the model, the function must return an invalid model index, created with the empty QModelIndex() constructor. */ // fall 1: parentitem fuer invalid // qDebug() << "parent "; // << QString("%1").arg((unsigned int) child); if ( !child.isValid() ) { return QModelIndex(); } // qDebug() << "parent2or3"; AbstractTreeItem *childItem = static_cast<AbstractTreeItem*>( child.internalPointer() ); AbstractTreeItem *parentItem = childItem->parent(); // fall 2: parentitem fuer rootItem // if ( parentItem == NULL ) // return QModelIndex(); if ( parentItem == rootItem ) return QModelIndex(); // fall 3: parentitem fuer alle anderen // return index(r,c,parent model index); return createIndex( parentItem->row(), 0, parentItem ); }
QModelIndex Model::index( int row, int column, const QModelIndex & parent ) const { /* index() Given a model index for a parent item, this function allows views and delegates to access children of that item. If no valid child item - corresponding to the specified row, column, and parent model index, can be found, the function must return QModelIndex(), which is an invalid model index. */ // qDebug() << "index(" << row <<", " <<column<<")"; if ( !hasIndex( row, column, parent ) ) return QModelIndex(); AbstractTreeItem* parentItem; //BUG, parent is never valid if ( !parent.isValid() ) parentItem = rootItem; else { parentItem = static_cast<AbstractTreeItem*>( parent.internalPointer() ); } AbstractTreeItem* childItem = parentItem->child( row ); // qDebug() << "index: parentItem==" << (unsigned int) parentItem; // qDebug() << "index: childItem==" << (unsigned int) childItem; if ( childItem ) { // qDebug() << "createIndex(" << row << ", " << column << ", " << (unsigned int) childItem << ");"; return createIndex( row, column, childItem ); } // qDebug() << "invalid"; return QModelIndex(); }
bool Model::setData( const QModelIndex & index, const QVariant & value, int role ) { // qDebug() << "setData " << index.column(); if (( index.isValid() && getTreeItemType( index ) == NODE_CONNECTION && index.column() == 4 && role == Qt::EditRole ) || ( index.isValid() && getTreeItemType( index ) == NODE_CONNECTION && role == customRole::SymbolIndexRole ) ) { AbstractTreeItem* n = static_cast<AbstractTreeItem*>( index.internalPointer() ); node_connection* nc = static_cast<node_connection*>( n ); nc->setSymbol_index( symbol( value.toString() ) ); // qDebug() << __FUNCTION__ << value.toString() << " " << nc->symbol_index() << " " << symbol( nc->symbol_index() ); emit dataChanged( index, index ); return true; } // this code is used to redirect a node_connection's destination (source is fixed to the node the // node_connection is assigned to). if one would not have unique IDs then it would be impossible // to use a number to match a node with. say a node_connection connects from (source node id=2) to // (destination node id=4), the code below let's you use the TreeView editor to redirect it to (say node id=7) // if 7 exists if ( index.isValid() && getTreeItemType( index ) == NODE_CONNECTION && index.column() == 5 && role == Qt::EditRole ) { AbstractTreeItem* n = static_cast<AbstractTreeItem*>( index.internalPointer() ); node_connection* nc = static_cast<node_connection*>( n ); AbstractTreeItem* a = AbstractTreeItemFromId( value.toInt() ); if ( a == NULL ) { qDebug() << "can't redirect connection because the given node id was not found in the graph, please try again later!"; return false; } nc->setNext_node( a ); emit dataChanged( index, index ); return true; } if (( index.isValid() && index.column() == 6 && role == Qt::EditRole ) || ( index.isValid() && role == customRole::CustomLabelRole ) ) { AbstractTreeItem* nItem = static_cast<AbstractTreeItem*>( index.internalPointer() ); nItem->setProperty( "CustomLabelRole", value ); emit dataChanged( index, index ); return true; } if ( index.isValid() && getTreeItemType( index ) == NODE && (( role == customRole::StartRole ) || role == customRole::FinalRole ) ) { AbstractTreeItem* n = static_cast<AbstractTreeItem*>( index.internalPointer() ); QModelIndex correctedIndex; if ( role == customRole::StartRole ) { n->setProperty( "start", value ); correctedIndex = Model::index( index.row(), 1, index.parent() ); } if ( role == customRole::FinalRole ) { n->setProperty( "final", value ); correctedIndex = Model::index( index.row(), 2, index.parent() ); } emit dataChanged( correctedIndex, correctedIndex ); return true; } return false; }
void AbstractTreeItem::dumpChildList() { qDebug() << "==== Childlist for Item:" << this << "===="; if(childCount() > 0) { AbstractTreeItem *child; QList<AbstractTreeItem *>::const_iterator childIter = _childItems.constBegin(); while(childIter != _childItems.constEnd()) { child = *childIter; qDebug() << "Row:" << child->row() << child << child->data(0, Qt::DisplayRole); childIter++; } } qDebug() << "==== End Of Childlist ===="; }
int Model::rowCount( const QModelIndex & sibling ) const { // returns how many siblings this "sibling" node has AbstractTreeItem *parentItem; if ( sibling.column() > 0 ) { // qDebug() << "rowcount=0"; return 0; } if ( !sibling.isValid() ) parentItem = rootItem; else parentItem = static_cast<AbstractTreeItem*>( sibling.internalPointer() ); // qDebug() << "rowcount="<<parentItem->childCount(); return parentItem->childCount(); }
bool Model::insertRows( int row, int count, const QModelIndex & parent, QPoint pos ) { if (count > 1) { qDebug() << __PRETTY_FUNCTION__ << "FATAL: this might need some testing, exiting"; exit(1); } // no valid parent -> it's a node to add if ( !parent.isValid() ) { // a NODE beginInsertRows( parent, row, row + count - 1 ); { node* n = new node(rootItem); n->setProperty( "pos", pos ); if (n != NULL) { rootItem->appendChild( n ); } else { qDebug() << __PRETTY_FUNCTION__ << "FATAL ERROR: in insertRows(), exiting"; exit(1); } } endInsertRows(); return true; } if ( getTreeItemType( parent ) == NODE ) { AbstractTreeItem* abstractitem = static_cast<AbstractTreeItem*>( parent.internalPointer() ); // int id = abstractitem->getId(); // qDebug() << "beginInsertRows( n" << id << " , " << row << ", " << row + count - 1 << ");"; beginInsertRows( parent, row, row + count - 1 ); { int i = count ; while ( i-- ) { node_connection* nc = new node_connection( abstractitem ); abstractitem->appendChild( nc ); } } endInsertRows(); return true; } qDebug() << __PRETTY_FUNCTION__ << "FATAL ERROR: can't add object to the automate class since i don't know what to do, exiting"; exit(1); return false; }
QWidget *Data3DTreeDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option , const QModelIndex& index) const { const Data3DTreeModel* pData3DTreeModel = static_cast<const Data3DTreeModel*>(index.model()); const AbstractTreeItem* pAbstractItem = static_cast<const AbstractTreeItem*>(pData3DTreeModel->itemFromIndex(index)); switch(pAbstractItem->type()) { case MetaTreeItemTypes::SurfaceColorGyri: { QColorDialog *pColorDialog = new QColorDialog(parent); connect(pColorDialog, &QColorDialog::currentColorChanged, this, &Data3DTreeDelegate::onEditorEdited); pColorDialog->setWindowTitle("Select Gyri Color"); pColorDialog->show(); return pColorDialog; } case MetaTreeItemTypes::SurfaceColorSulci: { QColorDialog *pColorDialog = new QColorDialog(); connect(pColorDialog, &QColorDialog::currentColorChanged, this, &Data3DTreeDelegate::onEditorEdited); pColorDialog->setWindowTitle("Select Sulci Color"); pColorDialog->show(); return pColorDialog; } case MetaTreeItemTypes::RTDataColormapType: { QComboBox* pComboBox = new QComboBox(parent); connect(pComboBox, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &Data3DTreeDelegate::onEditorEdited); pComboBox->addItem("Hot Negative 1"); pComboBox->addItem("Hot Negative 2"); pComboBox->addItem("Hot"); return pComboBox; } case MetaTreeItemTypes::RTDataNormalizationValue: { Spline* pSpline = new Spline("Spline Histogram", 0); connect(pSpline, static_cast<void (Spline::*)(double, double, double)>(&Spline::borderChanged), this, &Data3DTreeDelegate::onEditorEdited); QStandardItem* pParentItem = static_cast<QStandardItem*>(pAbstractItem->QStandardItem::parent()); QModelIndex indexParent = pData3DTreeModel->indexFromItem(pParentItem); MatrixXd matRTData = index.model()->data(indexParent, Data3DTreeModelItemRoles::RTData).value<MatrixXd>(); Eigen::VectorXd resultClassLimit; Eigen::VectorXi resultFrequency; MNEMath::histcounts(matRTData, false, 50, resultClassLimit, resultFrequency, 0.0, 0.0); pSpline->setData(resultClassLimit, resultFrequency, 0); QVector3D vecThresholdValues = index.model()->data(index, MetaTreeItemRoles::RTDataNormalizationValue).value<QVector3D>(); pSpline->setThreshold(vecThresholdValues); AbstractTreeItem* pParentItemAbstract = static_cast<AbstractTreeItem*>(pParentItem); QList<QStandardItem*> pColormapItem = pParentItemAbstract->findChildren(MetaTreeItemTypes::RTDataColormapType); for(int i = 0; i < pColormapItem.size(); ++i) { QModelIndex indexColormapItem = pData3DTreeModel->indexFromItem(pColormapItem.at(i)); QString colorMap = index.model()->data(indexColormapItem, MetaTreeItemRoles::RTDataColormapType).value<QString>(); pSpline->setColorMap(colorMap); } return pSpline; } case MetaTreeItemTypes::RTDataTimeInterval: { QSpinBox* pSpinBox = new QSpinBox(parent); connect(pSpinBox, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), this, &Data3DTreeDelegate::onEditorEdited); pSpinBox->setSuffix(" mSec"); pSpinBox->setMinimum(17); pSpinBox->setMaximum(50000); pSpinBox->setSingleStep(10); pSpinBox->setValue(index.model()->data(index, MetaTreeItemRoles::RTDataTimeInterval).toInt()); return pSpinBox; } case MetaTreeItemTypes::RTDataVisualizationType: { QComboBox* pComboBox = new QComboBox(parent); pComboBox->addItem("Vertex based"); pComboBox->addItem("Smoothing based"); pComboBox->addItem("Annotation based"); return pComboBox; } case MetaTreeItemTypes::SurfaceColor: { QColorDialog *pColorDialog = new QColorDialog(); connect(pColorDialog, &QColorDialog::currentColorChanged, this, &Data3DTreeDelegate::onEditorEdited); pColorDialog->setWindowTitle("Select Surface Color"); pColorDialog->show(); return pColorDialog; } case MetaTreeItemTypes::PointColor: { QColorDialog *pColorDialog = new QColorDialog(); connect(pColorDialog, &QColorDialog::currentColorChanged, this, &Data3DTreeDelegate::onEditorEdited); pColorDialog->setWindowTitle("Select Point Color"); pColorDialog->show(); return pColorDialog; } case MetaTreeItemTypes::RTDataNumberAverages: { QSpinBox* pSpinBox = new QSpinBox(parent); connect(pSpinBox, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged), this, &Data3DTreeDelegate::onEditorEdited); pSpinBox->setMinimum(1); pSpinBox->setMaximum(100); pSpinBox->setSingleStep(1); pSpinBox->setValue(index.model()->data(index, MetaTreeItemRoles::RTDataNumberAverages).toInt()); return pSpinBox; } case MetaTreeItemTypes::SurfaceAlpha: { QDoubleSpinBox* pDoubleSpinBox = new QDoubleSpinBox(parent); connect(pDoubleSpinBox, static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged), this, &Data3DTreeDelegate::onEditorEdited); pDoubleSpinBox->setMinimum(0.01); pDoubleSpinBox->setMaximum(1.0); pDoubleSpinBox->setSingleStep(0.01); pDoubleSpinBox->setValue(index.model()->data(index, MetaTreeItemRoles::SurfaceAlpha).toDouble()); return pDoubleSpinBox; } case MetaTreeItemTypes::SurfaceTranslateX: { QDoubleSpinBox* pDoubleSpinBox = new QDoubleSpinBox(parent); connect(pDoubleSpinBox, static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged), this, &Data3DTreeDelegate::onEditorEdited); pDoubleSpinBox->setMinimum(-10000.0); pDoubleSpinBox->setMaximum(10000.0); pDoubleSpinBox->setSingleStep(0.01); pDoubleSpinBox->setValue(index.model()->data(index, MetaTreeItemRoles::SurfaceTranslateX).toDouble()); return pDoubleSpinBox; } case MetaTreeItemTypes::SurfaceTranslateY: { QDoubleSpinBox* pDoubleSpinBox = new QDoubleSpinBox(parent); connect(pDoubleSpinBox, static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged), this, &Data3DTreeDelegate::onEditorEdited); pDoubleSpinBox->setMinimum(-10000.0); pDoubleSpinBox->setMaximum(10000.0); pDoubleSpinBox->setSingleStep(0.01); pDoubleSpinBox->setValue(index.model()->data(index, MetaTreeItemRoles::SurfaceTranslateY).toDouble()); return pDoubleSpinBox; } case MetaTreeItemTypes::SurfaceTranslateZ: { QDoubleSpinBox* pDoubleSpinBox = new QDoubleSpinBox(parent); connect(pDoubleSpinBox, static_cast<void (QDoubleSpinBox::*)(double)>(&QDoubleSpinBox::valueChanged), this, &Data3DTreeDelegate::onEditorEdited); pDoubleSpinBox->setMinimum(-10000.0); pDoubleSpinBox->setMaximum(10000.0); pDoubleSpinBox->setSingleStep(0.01); pDoubleSpinBox->setValue(index.model()->data(index, MetaTreeItemRoles::SurfaceTranslateZ).toDouble()); return pDoubleSpinBox; } case MetaTreeItemTypes::NetworkThreshold: { Spline* pSpline = new Spline("Spline Histogram", 0); connect(pSpline, static_cast<void (Spline::*)(double, double, double)>(&Spline::borderChanged), this, &Data3DTreeDelegate::onEditorEdited); QStandardItem* pParentItem = static_cast<QStandardItem*>(pAbstractItem->QStandardItem::parent()); QModelIndex indexParent = pData3DTreeModel->indexFromItem(pParentItem); MatrixXd matRTData = index.model()->data(indexParent, Data3DTreeModelItemRoles::NetworkDataMatrix).value<MatrixXd>(); Eigen::VectorXd resultClassLimit; Eigen::VectorXi resultFrequency; MNEMath::histcounts(matRTData, false, 50, resultClassLimit, resultFrequency, 0.0, 0.0); pSpline->setData(resultClassLimit, resultFrequency, 0); QVector3D vecThresholdValues = index.model()->data(index, MetaTreeItemRoles::NetworkThreshold).value<QVector3D>(); pSpline->setThreshold(vecThresholdValues); return pSpline; } case MetaTreeItemTypes::NetworkMatrix: { QStandardItem* pParentItem = static_cast<QStandardItem*>(pAbstractItem->QStandardItem::parent()); QModelIndex indexParent = pData3DTreeModel->indexFromItem(pParentItem); MatrixXd matRTData = index.model()->data(indexParent, Data3DTreeModelItemRoles::NetworkDataMatrix).value<MatrixXd>(); ImageSc* pPlotLA = new ImageSc(matRTData); pPlotLA->show(); //return pPlotLA; } default: // do nothing; break; } return QItemDelegate::createEditor(parent, option, index); }
/*! ** this code should be read as table of generic cases (where row/column doesn't matter) ** which is important for the graphicsView. for the treeView there is a part of code where ** row/column matters, see the very long switch statement. */ QVariant Model::data( const QModelIndex &index, int role ) const { // qDebug() << __FUNCTION__; if ( !index.isValid() ) return QVariant(); AbstractTreeItem* n = static_cast<AbstractTreeItem*>( index.internalPointer() ); if ( role == customRole::CustomLabelRole ) return n->getProperty( "CustomLabelRole" ); // to understand customRole::TypeRole see the comment (Model.h - TreeItemType enum comment ) if ( role == customRole::TypeRole ) { if ( n->getObjectType() == AUTOMATE_ROOT ) return ViewTreeItemType::AUTOMATE_ROOT; if ( n->getObjectType() == NODE_CONNECTION ) return ViewTreeItemType::NODE_CONNECTION; if ( n->getObjectType() == NODE ) return ViewTreeItemType::NODE; return ViewTreeItemType::UNKNOWN; } if ( role == customRole::FinalRole ) if ( n->getObjectType() == NODE ) return n->getProperty( "final" ); if ( role == customRole::PosRole ) if ( n->getObjectType() == NODE ) return n->getProperty( "pos" ); if ( role == customRole::StartRole ) if ( n->getObjectType() == NODE ) return n->getProperty( "start" ); if ( role == customRole::SymbolIndexRole ) if ( n->getObjectType() == NODE_CONNECTION ) { node_connection* nc = static_cast<node_connection*>( index.internalPointer() ); // qDebug() << __FUNCTION__ << symbol( nc->symbol_index ) << nc->symbol_index; return symbol( nc->symbol_index() ) ; } if ( role == customRole::IdRole ) if ( n->getObjectType() == NODE || n->getObjectType() == NODE_CONNECTION ) return n->getId(); switch ( index.column() ) { case 0: switch ( role ) { case Qt::DecorationRole: if ( n->getObjectType() == NODE ) return QIcon( ":/icons/node.png" ); if ( n->getObjectType() == NODE_CONNECTION ) return QIcon( ":/icons/connect.png" ); } break; case 1: switch ( role ) { case Qt::ToolTipRole: break; case Qt::WhatsThisRole: break; case Qt::TextAlignmentRole: // if (index.column() == 1) // return Qt::AlignHCenter; // if (index.column() == 2) // return Qt::AlignHCenter; break; case customRole::SortRole: case Qt::DecorationRole: if ( n->getObjectType() == NODE ) { if ( n->getProperty( "start" ).toBool() ) { if ( role == customRole::SortRole ) return 1; return QIcon( ":/icons/startNode.png" ); } else { if ( role == customRole::SortRole ) return 0; } } break; // case Qt::BackgroundRole: // break; } break; case 2: switch ( role ) { case customRole::SortRole: case Qt::DecorationRole: if ( n->getObjectType() == NODE ) { if ( n->getProperty( "final" ).toBool() ) { if ( role == customRole::SortRole ) return 1; return QIcon( ":/icons/finalNode.png" ); } else { if ( role == customRole::SortRole ) return 0; } } break; } break; case 3: switch ( role ) { case customRole::SortRole: case Qt::DisplayRole: if ( n->getObjectType() == NODE ) { if ( role == customRole::SortRole ) { return n->getId(); } if ( role == Qt::DisplayRole ) return QString( "n%1" ).arg( n->getId() );// "node"; } if ( n->getObjectType() == NODE_CONNECTION ) { if ( role == customRole::SortRole ) return n->getId(); if ( role == Qt::DisplayRole ) return QString( "c%1" ).arg( n->getId() );// "node_connection"; } break; } case 4: switch ( role ) { case customRole::SortRole: case Qt::DisplayRole: if ( n->getObjectType() == NODE_CONNECTION ) { if ( role == customRole::SortRole ) return ( static_cast<node_connection*>( n ) )->symbol_index();// "node_connection"; if ( role == Qt::DisplayRole ) return symbol(( static_cast<node_connection*>( n ) )->symbol_index() );// "node_connection"; } } break; case 5: switch ( role ) { case Qt::BackgroundRole: if ( n->getObjectType() == NODE_CONNECTION ) if ((static_cast<node_connection*>( n ) )->next_node() == NULL) return QBrush( QColor( 255, 0, 0, 250 ) ); break; case customRole::SortRole: case Qt::DisplayRole: if ( n->getObjectType() == NODE_CONNECTION ) { if ((static_cast<node_connection*>( n ) )->next_node() == NULL) return "undefined"; AbstractTreeItem* next_node = ( static_cast<node_connection*>( n ) )->next_node(); if ( role == customRole::SortRole ) return next_node->getId();// "node_connection"; if ( role == Qt::DisplayRole ) return QString( "n%1" ).arg( next_node->getId() );// "node_connection"; } } break; case 6: if ( role == Qt::DisplayRole ) { return n->getProperty( "CustomLabelRole" ); } break; /* case 7: break;*/ } if ( role == Qt::BackgroundRole ) { if ( n->getObjectType() == NODE ) return QBrush( QColor( 50, 160, 170, 150 ) ); if ( n->getObjectType() == NODE_CONNECTION ) return QBrush( QColor( 180, 200, 200, 50 ) ); } return QVariant(); }