X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FSUIT%2FSUIT_TreeModel.cxx;h=8feae8ad9c52626ec22b390dfef5df30d1aff769;hb=944a88161c28aa3414d534728169b4f21f68de47;hp=53c9a94ba94ebca5eafcb0722fe757acce19fc85;hpb=8c5294030a4c11ca0a18be48fc0165466861adad;p=modules%2Fgui.git diff --git a/src/SUIT/SUIT_TreeModel.cxx b/src/SUIT/SUIT_TreeModel.cxx old mode 100755 new mode 100644 index 53c9a94ba..8feae8ad9 --- a/src/SUIT/SUIT_TreeModel.cxx +++ b/src/SUIT/SUIT_TreeModel.cxx @@ -1,9 +1,9 @@ -// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2019 CEA/DEN, EDF R&D, OPEN CASCADE // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either -// version 2.1 of the License. +// version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -483,6 +483,8 @@ SUIT_TreeModel::~SUIT_TreeModel() this, SLOT( onInserted( SUIT_DataObject*, SUIT_DataObject* ) ) ); SUIT_DataObject::disconnect( SIGNAL( removed( SUIT_DataObject*, SUIT_DataObject* ) ), this, SLOT( onRemoved( SUIT_DataObject*, SUIT_DataObject* ) ) ); + SUIT_DataObject::disconnect( SIGNAL( modifed( SUIT_DataObject* ) ), + this, SLOT( onModified( SUIT_DataObject* ) ) ); delete myRoot; } @@ -498,6 +500,7 @@ SUIT_TreeModel::~SUIT_TreeModel() void SUIT_TreeModel::registerColumn( const int group_id, const QString& name, const int custom_id ) { bool found = false; + beginResetModel(); for ( int i=0, n=myColumns.size(); i 0; } - if ( needSignal ) { + if ( emitChanged && needSignal ) { QModelIndexList lst; if ( searcher() ) { SUIT_DataObject* o = searcher()->findObject( id ); @@ -703,39 +709,12 @@ void SUIT_TreeModel::setVisibilityState( const QString& id, Qtx::VisibilityState /*! \brief Set visibility state for all objects. - \param id - column name \param state - visible state */ void SUIT_TreeModel::setVisibilityStateForAll( Qtx::VisibilityState state ) { - if ( state != Qtx::UnpresentableState ) { - VisibilityMap::ConstIterator it = myVisibilityMap.begin(); - while ( it != myVisibilityMap.end() ) { - if ( it.value() != state ) - setVisibilityState( it.key(), state ); - it++; - } - } - else { - QList anIds = myVisibilityMap.keys(); - myVisibilityMap.clear(); - QList::ConstIterator it = anIds.begin(); - while ( it != anIds.end() ) { - QModelIndexList lst; - if ( searcher() ) { - SUIT_DataObject* o = searcher()->findObject( *it ); - if ( o ) lst << index( o ); - } - else { - lst = match( index( 0, root()->customData( Qtx::IdType ).toInt() ), DisplayRole, (*it), 1, Qt::MatchExactly | Qt::MatchRecursive ); - } - if ( !lst.isEmpty() ) { - QModelIndex idx = index( lst.first().row(), SUIT_DataObject::VisibilityId ,lst.first().parent() ); - emit dataChanged( idx, idx ); - } - it++; - } - } + foreach( QString id, myVisibilityMap.keys() ) + setVisibilityState( id, state ); } /*! @@ -769,19 +748,28 @@ void SUIT_TreeModel::setRoot( SUIT_DataObject* r ) { if ( root() == r ) return; + beginResetModel(); if ( autoDeleteTree() ) { SUIT_DataObject::disconnect( SIGNAL( inserted( SUIT_DataObject*, SUIT_DataObject* ) ), this, SLOT( onInserted( SUIT_DataObject*, SUIT_DataObject* ) ) ); SUIT_DataObject::disconnect( SIGNAL( removed( SUIT_DataObject*, SUIT_DataObject* ) ), this, SLOT( onRemoved( SUIT_DataObject*, SUIT_DataObject* ) ) ); + SUIT_DataObject::disconnect( SIGNAL( modified( SUIT_DataObject* ) ), + this, SLOT( onModified( SUIT_DataObject* ) ) ); delete myRoot; + + if ( myRootItem ) { + QList items = myRootItem->children(); + for ( QList::iterator anIt = items.begin(); anIt != items.end(); anIt++ ) + delete *anIt; + } } myRoot = r; //initialize(); - reset(); + endResetModel(); emit modelUpdated(); } @@ -956,12 +944,15 @@ bool SUIT_TreeModel::setData( const QModelIndex& index, } break; case EditRole: { - QString val = value.toString(); + QString val = value.toString(); + bool mod = obj->name() != val; if ( !val.isEmpty() && obj->setName(val) ) { emit( dataChanged( index, index ) ); - return true; - } - return false; + if (mod) + emit ( renamed(obj) ); + return true; + } + return false; break; } default: @@ -1212,6 +1203,8 @@ void SUIT_TreeModel::setAutoUpdate( const bool on ) this, SLOT( onInserted( SUIT_DataObject*, SUIT_DataObject* ) ) ); SUIT_DataObject::disconnect( SIGNAL( removed( SUIT_DataObject*, SUIT_DataObject* ) ), this, SLOT( onRemoved( SUIT_DataObject*, SUIT_DataObject* ) ) ); + SUIT_DataObject::disconnect( SIGNAL( modified( SUIT_DataObject* ) ), + this, SLOT( onModified( SUIT_DataObject* ) ) ); myAutoUpdate = on; if ( myAutoUpdate ) { @@ -1219,6 +1212,8 @@ void SUIT_TreeModel::setAutoUpdate( const bool on ) this, SLOT( onInserted( SUIT_DataObject*, SUIT_DataObject* ) ) ); SUIT_DataObject::connect( SIGNAL( removed( SUIT_DataObject*, SUIT_DataObject* ) ), this, SLOT( onRemoved( SUIT_DataObject*, SUIT_DataObject* ) ) ); + SUIT_DataObject::connect( SIGNAL( modified( SUIT_DataObject* ) ), + this, SLOT( onModified( SUIT_DataObject* ) ) ); updateTree(); } @@ -1412,11 +1407,15 @@ void SUIT_TreeModel::initialize() this, SLOT( onInserted( SUIT_DataObject*, SUIT_DataObject* ) ) ); SUIT_DataObject::disconnect( SIGNAL( removed( SUIT_DataObject*, SUIT_DataObject* ) ), this, SLOT( onRemoved( SUIT_DataObject*, SUIT_DataObject* ) ) ); + SUIT_DataObject::disconnect( SIGNAL( modified( SUIT_DataObject* ) ), + this, SLOT( onModified( SUIT_DataObject* ) ) ); if ( autoUpdate() ) { SUIT_DataObject::connect( SIGNAL( inserted( SUIT_DataObject*, SUIT_DataObject* ) ), this, SLOT( onInserted( SUIT_DataObject*, SUIT_DataObject* ) ) ); SUIT_DataObject::connect( SIGNAL( removed( SUIT_DataObject*, SUIT_DataObject* ) ), this, SLOT( onRemoved( SUIT_DataObject*, SUIT_DataObject* ) ) ); + SUIT_DataObject::connect( SIGNAL( modified( SUIT_DataObject* ) ), + this, SLOT( onModified( SUIT_DataObject* ) ) ); } myItems.clear(); // ????? is it really necessary @@ -1592,13 +1591,28 @@ void SUIT_TreeModel::updateItem( SUIT_TreeModel::TreeItem* item, bool emitLayout return; // update all columns corresponding to the given data object - //emit layoutAboutToBeChanged(); // VSR 25/04/2011: fix crash on delete objects - QModelIndex firstIdx = index( obj, 0 ); - QModelIndex lastIdx = index( obj, columnCount() - 1 ); - emit dataChanged( firstIdx, lastIdx ); - obj->setModified(false); - if( emitLayoutChanged ) - emit layoutChanged(); + /*To avoid crashes we should update any persistent model indexes before emitting layoutChanged(). In other words, when the structure changes: + - emit layoutAboutToBeChanged + - Remember the QModelIndex that will change + - call changePersistentIndex() + - emit layoutChanged + */ + + emit layoutAboutToBeChanged(); + + // Remember the QModelIndex that will change + QModelIndexList fromIndexes; + QModelIndexList toIndexes; + for (int i = 0; i < columnCount() - 1; ++i) { + fromIndexes.append( index( obj, i )); + toIndexes.append(QModelIndex()); + } + //changePersistentIndexList(fromIndexes, toIndexes); // Limitation: can lead to loss of selection + + emit dataChanged( toIndexes.first(), toIndexes.last() ); + obj->setModified(false); + if ( emitLayoutChanged ) + emit layoutChanged(); } /*! @@ -1664,6 +1678,22 @@ void SUIT_TreeModel::onRemoved( SUIT_DataObject* /*object*/, SUIT_DataObject* pa updateTree( parent ); } +/*! + \brief Called when the data object is modified. TreeSync is not used here for maximum efficiency. + It is assumed that it is up to the application to decide when its data objects are modified. + \param obj data object that has been modified +*/ +void SUIT_TreeModel::onModified( SUIT_DataObject* obj ) +{ + if ( autoUpdate() ) + { + QModelIndex firstIdx = index( obj, 0 ); + QModelIndex lastIdx = index( obj, columnCount() - 1 ); + emit dataChanged( firstIdx, lastIdx ); + obj->setModified(false); + } +} + /*! \brief Drag and Drop support. */ @@ -1763,6 +1793,7 @@ SUIT_ProxyModel::SUIT_ProxyModel( QObject* parent ) connect( model, SIGNAL( clicked( SUIT_DataObject*, int ) ), this, SIGNAL(clicked( SUIT_DataObject*, int ) ) ); connect( model, SIGNAL( dropped( const QList&, SUIT_DataObject*, int, Qt::DropAction ) ), this, SIGNAL( dropped( const QList&, SUIT_DataObject*, int, Qt::DropAction ) ) ); + connect( model, SIGNAL( renamed( SUIT_DataObject* ) ), this, SIGNAL( renamed( SUIT_DataObject* ) ) ); setSourceModel( model ); setDynamicSortFilter( true ); } @@ -1781,6 +1812,7 @@ SUIT_ProxyModel::SUIT_ProxyModel( SUIT_DataObject* root, QObject* parent ) connect( model, SIGNAL( clicked( SUIT_DataObject*, int ) ), this, SIGNAL( clicked( SUIT_DataObject*, int ) ) ); connect( model, SIGNAL( dropped( const QList&, SUIT_DataObject*, int, Qt::DropAction ) ), this, SIGNAL( dropped( const QList&, SUIT_DataObject*, int, Qt::DropAction ) ) ); + connect( model, SIGNAL( renamed( SUIT_DataObject* ) ), this, SIGNAL( renamed( SUIT_DataObject* ) ) ); setSourceModel( model ); setDynamicSortFilter( true ); } @@ -1798,6 +1830,7 @@ SUIT_ProxyModel::SUIT_ProxyModel( SUIT_AbstractModel* model, QObject* parent ) connect( *model, SIGNAL( clicked( SUIT_DataObject*, int ) ), this, SIGNAL( clicked( SUIT_DataObject*, int ) ) ); connect( *model, SIGNAL( dropped( const QList&, SUIT_DataObject*, int, Qt::DropAction ) ), this, SIGNAL( dropped( const QList&, SUIT_DataObject*, int, Qt::DropAction ) ) ); + connect( *model, SIGNAL( renamed( SUIT_DataObject* ) ), this, SIGNAL( renamed( SUIT_DataObject* ) ) ); setSourceModel( *model ); setDynamicSortFilter( true ); } @@ -2171,11 +2204,12 @@ Qtx::HeaderViewFlags SUIT_ProxyModel::headerFlags( const QString& name ) const \param id - column name \param state - visible state + \param emitChanged - if set to false, blocks dataChanged() signal, this can be used to + prevent emitting dataChanged() several times for the same data object */ -void SUIT_ProxyModel::setVisibilityState(const QString& id, Qtx::VisibilityState state) -{ +void SUIT_ProxyModel::setVisibilityState(const QString& id, Qtx::VisibilityState state, bool emitChanged ) { if(treeModel()) - treeModel()->setVisibilityState(id,state); + treeModel()->setVisibilityState(id,state,emitChanged); } /*! @@ -2265,8 +2299,6 @@ void SUIT_ItemDelegate::paint( QPainter* painter, QSize SUIT_ItemDelegate::sizeHint ( const QStyleOptionViewItem & option, const QModelIndex & index ) const { QSize size = QItemDelegate::sizeHint ( option, index ); -#if QT_VERSION >= 0x040500 size.setHeight( size.height() + 1 ); -#endif return size; }