Caf:PdmUiTree: Rewrote rebuildUiSubTree to become updateUiSubTree

Now the UI state is preserved when refreshing the tree, making it suitable
to use this method more extensively. This paves the way to make changes to the Pdm data structure without considering the ui at all, until a  call to updateUiSubTree gets the ui gracefully into sync.
p4#: 21599
This commit is contained in:
Jacob Støren 2013-05-13 12:00:52 +02:00
parent 06d32ae97e
commit cad25bcd59
9 changed files with 125 additions and 77 deletions

View File

@ -1098,7 +1098,7 @@ void RiaApplication::applyPreferences()
{
this->project()->setScriptDirectories(m_preferences->scriptDirectories());
RimUiTreeModelPdm* treeModel = RiuMainWindow::instance()->uiPdmModel();
if (treeModel) treeModel->rebuildUiSubTree(this->project()->scriptCollection());
if (treeModel) treeModel->updateUiSubTree(this->project()->scriptCollection());
}
}

View File

@ -102,7 +102,7 @@ void RimResultSlot::changeLegendConfig(QString resultVarNameOfNewLegend)
m_legendConfigData.v().erase(it);
m_legendConfigData.v().push_back(this->legendConfig());
this->legendConfig = newLegend;
RiuMainWindow::instance()->uiPdmModel()->rebuildUiSubTree(this);
RiuMainWindow::instance()->uiPdmModel()->updateUiSubTree(this);
found = true;
break;
}
@ -116,7 +116,7 @@ void RimResultSlot::changeLegendConfig(QString resultVarNameOfNewLegend)
newLegend->resultVariableName = resultVarNameOfNewLegend;
m_legendConfigData.v().push_back(this->legendConfig());
this->legendConfig = newLegend;
RiuMainWindow::instance()->uiPdmModel()->rebuildUiSubTree(this);
RiuMainWindow::instance()->uiPdmModel()->updateUiSubTree(this);
}
}

View File

@ -174,7 +174,7 @@ void RimScriptCollection::fieldChangedByUi(const caf::PdmFieldHandle *changedFie
this->setUiName(fi.baseName());
this->readContentFromDisc();
RimUiTreeModelPdm* treeModel = RiuMainWindow::instance()->uiPdmModel();
if (treeModel) treeModel->rebuildUiSubTree(this);
if (treeModel) treeModel->updateUiSubTree(this);
}
}

View File

@ -510,7 +510,7 @@ void RimStatisticsCase::setWellResultsAndUpdateViews(const cvf::Collection<RigSi
reservoirView->wellCollection()->wells.deleteAllChildObjects();
reservoirView->updateDisplayModelForWellResults();
treeModel->rebuildUiSubTree(reservoirView->wellCollection());
treeModel->updateUiSubTree(reservoirView->wellCollection());
progInfo.incrementProgress();
}

View File

@ -459,7 +459,7 @@ void RimUiTreeModelPdm::slotRefreshScriptTree(QString path)
if (changedSColl)
{
changedSColl->readContentFromDisc();
this->rebuildUiSubTree(changedSColl);
this->updateUiSubTree(changedSColl);
}
}
@ -484,7 +484,7 @@ void RimUiTreeModelPdm::addInputProperty(const QModelIndex& itemIndex, const QSt
inputReservoir->openDataFileSet(fileNames);
}
this->rebuildUiSubTree(inputPropertyCollection);
this->updateUiSubTree(inputPropertyCollection);
}
//--------------------------------------------------------------------------------------------------

View File

@ -548,7 +548,7 @@ void RiaSocketServer::readPropertyDataFromOctave()
inputProperty->fileName = "";
inputRes->m_inputPropertyCollection->inputProperties.push_back(inputProperty);
RimUiTreeModelPdm* treeModel = RiuMainWindow::instance()->uiPdmModel();
treeModel->rebuildUiSubTree(inputRes->m_inputPropertyCollection());
treeModel->updateUiSubTree(inputRes->m_inputPropertyCollection());
}
inputProperty->resolvedState = RimInputProperty::RESOLVED_NOT_SAVED;
}

View File

@ -28,7 +28,6 @@ namespace caf
//==================================================================================================
/// Class used to build a tree item holding a data object
/// Todo: Needs destructor !!!
//==================================================================================================
template <typename T>
class UiTreeItem
@ -98,23 +97,10 @@ public:
child->m_parentItem = this;
}
bool insertChildren(int position, int count)
void insertChild( int position, UiTreeItem* child)
{
if (position < 0 || position > m_childItems.size())
return false;
for (int row = 0; row < count; ++row)
{
createChild(this, position + row);
}
return true;
}
// Create a new Ui tree item at given position pointing to a NULL data object
virtual UiTreeItem* createChild(UiTreeItem* parent, int position)
{
return new UiTreeItem(this, position, NULL);
m_childItems.insert(position, child);
child->m_parentItem = this;
}
bool removeChildren(int position, int count)
@ -132,27 +118,40 @@ public:
return true;
}
bool removeChildrenNoDelete(int position, int count)
{
if (position < 0 || position + count > m_childItems.size())
return false;
for (int row = 0; row < count; ++row)
{
m_childItems.removeAt(position);
}
return true;
}
void removeAllChildrenNoDelete()
{
m_childItems.clear();
}
UiTreeItem* findUiItem(const T& dataObject)
// Returns the index of the first child with dataObject() == dataObject. -1 if not found
int findChildItemIndex(const T& dataObject)
{
if (m_dataObject == dataObject) return this;
int i;
for (i = 0; i < m_childItems.size(); ++i)
for (int i = 0; i < m_childItems.size(); ++i)
{
UiTreeItem* itemFound = m_childItems[i]->findUiItem(dataObject);
if (itemFound != NULL) return itemFound;
if (m_childItems[i]->dataObject() == dataObject)
{
return i;
}
}
return NULL;
return -1;
}
private:
QList<UiTreeItem*> m_childItems;
UiTreeItem* m_parentItem;
T m_dataObject;
T m_dataObject;
};

View File

@ -332,28 +332,12 @@ Qt::ItemFlags UiTreeModelPdm::flags(const QModelIndex &index) const
return flagMask;
}
//--------------------------------------------------------------------------------------------------
/// TO BE DELETED
//--------------------------------------------------------------------------------------------------
bool UiTreeModelPdm::insertRows_special(int position, int rows, const QModelIndex &parent /*= QModelIndex()*/)
{
PdmUiTreeItem* parentItem = getTreeItemFromIndex(parent);
bool success;
beginInsertRows(parent, position, position + rows - 1);
success = parentItem->insertChildren(position, rows);
endInsertRows();
return success;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool UiTreeModelPdm::removeRows_special(int position, int rows, const QModelIndex &parent /*= QModelIndex()*/)
bool UiTreeModelPdm::removeRows_special(int position, int count, const QModelIndex &parent /*= QModelIndex()*/)
{
if (rows <= 0) return true;
if (count <= 0) return true;
PdmUiTreeItem* parentItem = NULL;
if (parent.isValid())
@ -369,38 +353,105 @@ bool UiTreeModelPdm::removeRows_special(int position, int rows, const QModelInde
bool success = true;
beginRemoveRows(parent, position, position + rows - 1);
success = parentItem->removeChildren(position, rows);
beginRemoveRows(parent, position, position + count - 1);
success = parentItem->removeChildren(position, count);
endRemoveRows();
return success;
}
//--------------------------------------------------------------------------------------------------
///
/// Refreshes the UI-tree below the supplied root PdmObject
//--------------------------------------------------------------------------------------------------
void UiTreeModelPdm::rebuildUiSubTree(PdmObject* root)
void UiTreeModelPdm::updateUiSubTree(PdmObject* pdmRoot)
{
QModelIndex item = getModelIndexFromPdmObject(root);
if (item.isValid())
// Build the new "Correct" Tree
PdmUiTreeItem* tempUpdatedPdmTree = UiTreeItemBuilderPdm::buildViewItems(NULL, -1, pdmRoot);
// Find the corresponding entry for "root" in the existing Ui tree
QModelIndex uiSubTreeRootModelIdx = getModelIndexFromPdmObject(pdmRoot);
PdmUiTreeItem* uiModelSubTreeRoot = NULL;
if (uiSubTreeRootModelIdx.isValid())
{
this->removeRows_special(0, rowCount(item), item);
PdmUiTreeItem* treeItem = getTreeItemFromIndex(item);
PdmUiTreeItem* fakeRoot = UiTreeItemBuilderPdm::buildViewItems(NULL, -1, root);
this->beginInsertRows(item, 0, fakeRoot->childCount());
for(int i = 0; i < fakeRoot->childCount(); ++i)
{
treeItem->appendChild(fakeRoot->child(i));
}
this->endInsertRows();
fakeRoot->removeAllChildrenNoDelete();
delete fakeRoot;
uiModelSubTreeRoot = getTreeItemFromIndex(uiSubTreeRootModelIdx);
}
else
{
uiModelSubTreeRoot = m_treeItemRoot;
}
updateModelSubTree(uiSubTreeRootModelIdx, uiModelSubTreeRoot, tempUpdatedPdmTree);
delete tempUpdatedPdmTree;
}
//--------------------------------------------------------------------------------------------------
/// Makes the olUiTreeRoot tree become identical to the tree in newUiTreeRoot,
/// calling begin..() end..() to make the UI update accordingly.
/// This assumes that all the items have a pointer an unique PdmObject
//--------------------------------------------------------------------------------------------------
void UiTreeModelPdm::updateModelSubTree(const QModelIndex& uiSubTreeRootModelIdx, PdmUiTreeItem* uiModelSubTreeRoot, PdmUiTreeItem* updatedPdmSubTreeRoot)
{
// First loop over children in the old ui tree, deleting the ones not present in
// the newUiTree
for (int i = 0; i < uiModelSubTreeRoot->childCount() ; ++i)
{
PdmUiTreeItem* oldChild = uiModelSubTreeRoot->child(i);
int childIndex = updatedPdmSubTreeRoot->findChildItemIndex(oldChild->dataObject());
if (childIndex == -1) // Not found
{
this->beginRemoveRows(uiSubTreeRootModelIdx, i, i);
uiModelSubTreeRoot->removeChildren(i, 1);
this->endRemoveRows();
i--;
}
}
// Then loop over the children in the new ui tree, finding the corresponding items in the old tree.
// If they are found, we move them to the correct position.
// If not found, we pulls the item out of the old ui tree, inserting it into the old tree.
for (int i = 0; i < updatedPdmSubTreeRoot->childCount() ; ++i)
{
PdmUiTreeItem* newChild = updatedPdmSubTreeRoot->child(i);
int childIndex = uiModelSubTreeRoot->findChildItemIndex(newChild->dataObject());
if (childIndex == -1) // Not found
{
this->beginInsertRows(uiSubTreeRootModelIdx, i, i);
uiModelSubTreeRoot->insertChild(i, newChild);
this->endInsertRows();
updatedPdmSubTreeRoot->removeChildrenNoDelete(i, 1);
i--;
}
else if (childIndex != i) // Found, but must be moved
{
assert(childIndex > i);
PdmUiTreeItem* oldChild = uiModelSubTreeRoot->child(childIndex);
this->beginMoveRows(uiSubTreeRootModelIdx, childIndex, childIndex, uiSubTreeRootModelIdx, i);
uiModelSubTreeRoot->removeChildrenNoDelete(childIndex, 1);
uiModelSubTreeRoot->insertChild(i, oldChild);
this->endMoveRows();
updateModelSubTree( index(i, 0, uiSubTreeRootModelIdx) ,oldChild, newChild);
}
else // Found the corresponding item in the right place.
{
PdmUiTreeItem* oldChild = uiModelSubTreeRoot->child(childIndex);
updateModelSubTree( index(i, 0, uiSubTreeRootModelIdx) ,oldChild, newChild);
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@ -50,7 +50,7 @@ public:
static PdmUiTreeItem* getTreeItemFromIndex(const QModelIndex& index);
QModelIndex getModelIndexFromPdmObject(const PdmObject* object) const;
void rebuildUiSubTree(PdmObject* root);
void updateUiSubTree(PdmObject* root);
public:
// Overrides from QAbstractItemModel
@ -63,16 +63,14 @@ public:
virtual Qt::ItemFlags flags(const QModelIndex &index) const;
virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
// TO BE DELETED, NOT USED
virtual bool insertRows_special(int position, int rows, const QModelIndex &parent = QModelIndex());
virtual bool removeRows_special(int position, int rows, const QModelIndex &parent = QModelIndex());
protected:
QModelIndex getModelIndexFromPdmObjectRecursive(const QModelIndex& currentIndex, const PdmObject * object) const;
private:
PdmUiTreeItem* m_treeItemRoot;
void updateModelSubTree(const QModelIndex& uiSubTreeRootModelIdx, PdmUiTreeItem* uiModelSubTreeRoot, PdmUiTreeItem* updatedPdmSubTreeRoot);
PdmUiTreeItem* m_treeItemRoot;
};