-// Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
+// Copyright (C) 2007-2013 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
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;
}
\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_TreeModel::setVisibilityState( const QString& id, Qtx::VisibilityState state )
+void SUIT_TreeModel::setVisibilityState( const QString& id, Qtx::VisibilityState state, bool emitChanged )
{
VisibilityMap::const_iterator it = myVisibilityMap.find( id );
if ( it != myVisibilityMap.end() && it.value() == state )
else {
needSignal = myVisibilityMap.remove( id ) > 0;
}
- if ( needSignal ) {
+ if ( emitChanged && needSignal ) {
QModelIndexList lst;
if ( searcher() ) {
SUIT_DataObject* o = searcher()->findObject( id );
/*!
\brief Set visibility state for all objects.
- \param id - column name
\param state - visible state
*/
void SUIT_TreeModel::setVisibilityStateForAll( Qtx::VisibilityState state )
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<TreeItem*> items = myRootItem->children();
+ for ( QList<TreeItem*>::iterator anIt = items.begin(); anIt != items.end(); anIt++ )
+ delete *anIt;
+ }
}
myRoot = r;
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 ) {
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();
}
if(sitem==0)
{
//end of item list
- if(kitem==0)
- sitem=createItemAtPos(sobj,item,0);
- else
- sitem=createItemAtPos(sobj,item,kitem);
+ sitem=createItemAtPos(sobj,item,kitem);
updateTreeModel(sobj,sitem);
kobj++;
kitem++;
else
{
// obj : new object
- createItemAtPos(sobj,item,kitem);
+ sitem=createItemAtPos(sobj,item,kitem);
+ updateTreeModel(sobj,sitem);
kobj++;
kitem++;
sobj=obj->childObject(kobj);
//obj and item are synchronised : go to next ones
updateTreeModel(sobj,sitem);
if(sobj->modified()) updateItem(sitem, true);
- if( sobj ) sobj->update();
+ sobj->update();
kobj++;
kitem++;
sobj=obj->childObject(kobj);
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
SUIT_TreeModel::TreeItem* item = new TreeItem( obj, parent, after );
myItems[ obj ] = item;
- for(int pos=row;pos < parent->childCount();pos++)
- parent->child(pos)->setPosition(pos);
+ for(int ppos=row;ppos < parent->childCount();ppos++)
+ parent->child(ppos)->setPosition(ppos);
endInsertRows();
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();
}
/*!
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.
*/
\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);
}
/*!