X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FXGUI%2FXGUI_DataModel.cpp;h=16b4997ff20e4d244250620147419016f4d0ee97;hb=77ce6d35ac8d2f0fdaecb4f23e0870bf74e36103;hp=30cf4e574342ab50ac1d7090115d3cf5c5f71b15;hpb=7074394f8f08413d885f63be01df6bd5007b868c;p=modules%2Fshaper.git diff --git a/src/XGUI/XGUI_DataModel.cpp b/src/XGUI/XGUI_DataModel.cpp index 30cf4e574..16b4997ff 100644 --- a/src/XGUI/XGUI_DataModel.cpp +++ b/src/XGUI/XGUI_DataModel.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2017 CEA/DEN, EDF R&D +// Copyright (C) 2014-2024 CEA, EDF // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -12,81 +12,64 @@ // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // -// See http://www.salome-platform.org/ or -// email : webmaster.salome@opencascade.com +// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // #include "XGUI_DataModel.h" +#include "XGUI_ObjectsBrowser.h" +#include "XGUI_Workshop.h" #include +#include #include -#include -#include -#include -#include -#include -#include -#include #include #include +#include #include -#include #include -#include -#include - -#define ACTIVE_COLOR QColor(Qt::black) -//#define ACTIVE_COLOR QColor(0,72,140) -//#define PASSIVE_COLOR Qt::black - -/// Returns ResultPart object if the given object is a Part feature -/// Otherwise returns NULL +#include +#include -#define SELECTABLE_COLOR QColor(80, 80, 80) -#define DISABLED_COLOR QColor(200, 200, 200) +#include +#ifdef _MSC_VER +#pragma warning(disable: 4100) +#endif -ResultPartPtr getPartResult(ModelAPI_Object* theObj) +static bool isValidNode(const ModuleBase_ITreeNode* theNode) { - ModelAPI_Feature* aFeature = dynamic_cast(theObj); - if (aFeature) { - ResultPtr aRes = aFeature->firstResult(); - if (aRes.get() && (aRes->groupName() == ModelAPI_ResultPart::group())) { - ResultPartPtr aPartRes = std::dynamic_pointer_cast(aRes); - // Use only original parts, not a placement results - if (aPartRes == aPartRes->original()) - return aPartRes; - } + ModuleBase_ITreeNode* aParent = 0; + try { + aParent = theNode->parent(); } - return ResultPartPtr(); -} - -/// Returns pointer on document if the given object is document object -ModelAPI_Document* getSubDocument(void* theObj) -{ - ModelAPI_Document* aDoc = dynamic_cast((ModelAPI_Entity*)theObj); - return aDoc; + catch (...) { + return false; + } + if (aParent) + return isValidNode(aParent); + return true; } - - - // Constructor ************************************************* XGUI_DataModel::XGUI_DataModel(QObject* theParent) : QAbstractItemModel(theParent)//, //myIsEventsProcessingBlocked(false) { + XGUI_ObjectsBrowser* aOB = qobject_cast(theParent); + myWorkshop = aOB->workshop(); + Events_Loop* aLoop = Events_Loop::loop(); aLoop->registerListener(this, Events_Loop::eventByName(EVENT_OBJECT_CREATED)); aLoop->registerListener(this, Events_Loop::eventByName(EVENT_OBJECT_DELETED)); aLoop->registerListener(this, Events_Loop::eventByName(EVENT_OBJECT_UPDATED)); aLoop->registerListener(this, Events_Loop::eventByName(EVENT_ORDER_UPDATED)); aLoop->registerListener(this, Events_Loop::eventByName(EVENT_DOCUMENT_CHANGED)); + aLoop->registerListener(this, Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY)); } XGUI_DataModel::~XGUI_DataModel() @@ -97,238 +80,192 @@ XGUI_DataModel::~XGUI_DataModel() //****************************************************** void XGUI_DataModel::processEvent(const std::shared_ptr& theMessage) { - //if (myIsEventsProcessingBlocked) - // return; - DocumentPtr aRootDoc = ModelAPI_Session::get()->moduleDocument(); - std::string aRootType = myXMLReader->rootType(); - std::string aSubType = myXMLReader->subType(); - int aNbFolders = foldersCount(); - - // Created object event ******************* if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_CREATED)) { std::shared_ptr aUpdMsg = - std::dynamic_pointer_cast(theMessage); + std::dynamic_pointer_cast(theMessage); + std::set aObjects = aUpdMsg->objects(); + QObjectPtrList aCreated; + std::set::const_iterator aIt; + for (aIt = aObjects.cbegin(); aIt != aObjects.cend(); aIt++) { + if ((*aIt)->isInHistory()) + aCreated.append(*aIt); + if ((*aIt)->groupName() == ModelAPI_ResultPart::group()) { + emit beforeTreeRebuild(); + myRoot->update(); + rebuildDataTree(); + emit treeRebuilt(); + return; + } + } + if (aCreated.length() == 0) + return; + + emit beforeTreeRebuild(); + QTreeNodesList aNodes = myRoot->objectCreated(aCreated); + ModuleBase_ITreeNode* aParent; + int aRow = 0; + QModelIndex aParentIndex1, aParentIndex2; + ObjectPtr aObj; + bool aRebuildAll = false; + + foreach(ModuleBase_ITreeNode* aNode, aNodes) { + aObj = aNode->object(); + aParent = aNode->parent(); + if (aObj.get() && (aObj->groupName() == ModelAPI_Folder::group())) { + aParent->update(); + aRebuildAll = true; + } + else { + aRow = aParent->nodeRow(aNode); + aParentIndex1 = getParentIndex(aNode, 0); + aParentIndex2 = getParentIndex(aNode, 2); + insertRows(aRow, 1, aParentIndex1); + dataChanged(aParentIndex1, aParentIndex2); + } + } + if (aRebuildAll) + rebuildDataTree(); + + emit treeRebuilt(); + } + else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_DELETED)) { + std::shared_ptr aUpdMsg = + std::dynamic_pointer_cast(theMessage); + const std::list, std::string>>& aMsgGroups = + aUpdMsg->groups(); + QTreeNodesList aList; + std::list, std::string>>::const_iterator aIt; + emit beforeTreeRebuild(); + for (aIt = aMsgGroups.cbegin(); aIt != aMsgGroups.cend(); aIt++) { + aList.append(myRoot->objectsDeleted(aIt->first, aIt->second.c_str())); + } + // Remove obsolete nodes + QTreeNodesList aRemaining; + foreach(ModuleBase_ITreeNode* aNode, aList) { + if (myRoot->hasSubNode(aNode)) + aRemaining.append(aNode); + } + // Update remaining nodes + foreach(ModuleBase_ITreeNode* aNode, aRemaining) { + if (aNode->parent()) + aNode->parent()->update(); + } + rebuildDataTree(); + emit treeRebuilt(); + } + else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_UPDATED)) { + std::shared_ptr aUpdMsg = + std::dynamic_pointer_cast(theMessage); std::set aObjects = aUpdMsg->objects(); + QObjectPtrList aCreated; std::set::const_iterator aIt; - std::string aObjType; - for (aIt = aObjects.begin(); aIt != aObjects.end(); ++aIt) { - ObjectPtr aObject = (*aIt); - // We do not show objects which does not need to be shown in object browser - if (!aObject->isInHistory()) + bool aRebuildAll = false; + emit beforeTreeRebuild(); + for (aIt = aObjects.cbegin(); aIt != aObjects.cend(); aIt++) { + ObjectPtr aObj = (*aIt); + if (!aObj->isInHistory()) continue; - aObjType = aObject->groupName(); - DocumentPtr aDoc = aObject->document(); - if (aDoc == aRootDoc) { - // Check that new folders could appear - QStringList aNotEmptyFolders = listOfShowNotEmptyFolders(); - foreach (QString aNotEmptyFolder, aNotEmptyFolders) { - if ((aNotEmptyFolder.toStdString() == aObjType) && (aRootDoc->size(aObjType) == 1)) - // Appears first object in folder which can not be shown empty - insertRow(myXMLReader->rootFolderId(aObjType)); - } - // Insert new object - int aRow = aRootDoc->size(aObjType) - 1; - if (aRow != -1) { - if (aObjType == aRootType) { - insertRow(aRow + aNbFolders + 1); - } else { - int aFolderId = myXMLReader->rootFolderId(aObjType); - if (aFolderId != -1) { - insertRow(aRow, createIndex(aFolderId, 0, (void*)Q_NULLPTR)); - } - } - } - } else { - // Object created in sub-document - QModelIndex aDocRoot = findDocumentRootIndex(aDoc.get()); - if (aDocRoot.isValid()) { - // Check that new folders could appear - QStringList aNotEmptyFolders = listOfShowNotEmptyFolders(false); - foreach (QString aNotEmptyFolder, aNotEmptyFolders) { - if ((aNotEmptyFolder.toStdString() == aObjType) && (aDoc->size(aObjType) == 1)) - // Appears first object in folder which can not be shown empty - insertRow(myXMLReader->subFolderId(aObjType), aDocRoot); - } - int aRow = aDoc->index(aObject); - if (aRow != -1) { - int aNbSubFolders = foldersCount(aDoc.get()); - if (aObjType == aSubType) { - // List of objects under document root - insertRow(aRow + aNbSubFolders, aDocRoot); - } else { - // List of objects under a folder - if (aRow != -1) { - int aFolderId = folderId(aObjType, aDoc.get()); - if (aFolderId != -1) { - QModelIndex aParentFolder = createIndex(aFolderId, 0, aDoc.get()); - insertRow(aRow, aParentFolder); - emit dataChanged(aParentFolder, aParentFolder); - } - } - } - } else { - rebuildDataTree(); - break; - } - } else { - rebuildDataTree(); + if (aObj->data()->isValid()) { + if (aObj->groupName() == ModelAPI_Folder::group()) { + aRebuildAll = true; break; } + aCreated.append(*aIt); } } - // Deleted object event *********************** - } else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_DELETED)) { - std::shared_ptr aUpdMsg = - std::dynamic_pointer_cast(theMessage); - DocumentPtr aDoc = aUpdMsg->document(); - std::set aMsgGroups = aUpdMsg->groups(); - - /// Sort groups because RootType deletion has to be done after others - std::string aType = (aDoc == aRootDoc)? aRootType : aSubType; - std::list aGroups; - std::set::const_iterator aSetIt; - for (aSetIt = aMsgGroups.begin(); aSetIt != aMsgGroups.end(); ++aSetIt) { - std::string aGroup = (*aSetIt); - if (aGroup == aType) - aGroups.push_back(aGroup); - else - aGroups.push_front(aGroup); + if (aRebuildAll) { + myRoot->update(); } - - std::list::const_iterator aIt; - for (aIt = aGroups.begin(); aIt != aGroups.end(); ++aIt) { - std::string aGroup = (*aIt); - if (aDoc == aRootDoc) { // If root objects - int aRow = aRootDoc->size(aGroup); - if (aGroup == aRootType) { - // Process root folder - removeRow(aRow + aNbFolders); - rebuildBranch(aNbFolders, aRow); - } else { - // Process root sub-folder - int aFolderId = myXMLReader->rootFolderId(aGroup); - if (aFolderId != -1) { - QModelIndex aFolderIndex = createIndex(aFolderId, 0, (void*)Q_NULLPTR); - removeRow(aRow, aFolderIndex); - //rebuildBranch(0, aRow); - } - } - // Check that some folders could erased - QStringList aNotEmptyFolders = listOfShowNotEmptyFolders(); - foreach (QString aNotEmptyFolder, aNotEmptyFolders) { - if ((aNotEmptyFolder.toStdString() == aGroup) && (aRootDoc->size(aGroup) == 0)) { - // Appears first object in folder which can not be shown empty - removeRow(myXMLReader->rootFolderId(aGroup)); - //rebuildBranch(0, aNbFolders + aDoc->size(myXMLReader->rootType())); - break; - } - } - } else { - // Remove row for sub-document - QModelIndex aDocRoot = findDocumentRootIndex(aDoc.get()); - if (aDocRoot.isValid()) { - int aRow = aDoc->size(aGroup); - int aNbSubFolders = foldersCount(aDoc.get()); - if (aGroup == aSubType) { - // List of objects under document root - removeRow(aRow + aNbSubFolders, aDocRoot); - rebuildBranch(aNbSubFolders, aRow, aDocRoot); - } else { - // List of objects under a folder - int aFolderId = folderId(aGroup, aDoc.get()); - if (aFolderId != -1) { - QModelIndex aFolderRoot = createIndex(aFolderId, 0, aDoc.get()); - removeRow(aRow, aFolderRoot); - //rebuildBranch(0, aRow, aFolderRoot); - } - } - // Check that some folders could disappear - QStringList aNotEmptyFolders = listOfShowNotEmptyFolders(false); - int aSize = aDoc->size(aGroup); - foreach (QString aNotEmptyFolder, aNotEmptyFolders) { - if ((aNotEmptyFolder.toStdString() == aGroup) && (aSize == 0)) { - // Appears first object in folder which can not be shown empty - removeRow(myXMLReader->subFolderId(aGroup), aDocRoot); - //rebuildBranch(0, aNbSubFolders + aDoc->size(myXMLReader->subType()), aDocRoot); + else { + QSet aParents; + foreach(ObjectPtr aObj, aCreated) { + ModuleBase_ITreeNode* aNode = myRoot->subNode(aObj); + if (aNode) { + if (aNode->parent()) { + if (aNode->parent() == myRoot) { + aParents.clear(); + aParents.insert(myRoot); break; } + else { + aNode = aNode->parent(); + } } - } else { - rebuildDataTree(); - break; + aParents.insert(aNode); } } - } - } else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_UPDATED)) { - std::shared_ptr aUpdMsg = - std::dynamic_pointer_cast(theMessage); - std::set aObjects = aUpdMsg->objects(); - - std::set::const_iterator aIt; - std::string aObjType; - for (aIt = aObjects.begin(); aIt != aObjects.end(); ++aIt) { - ObjectPtr aObject = (*aIt); - if (aObject->data()->isValid()) { - FeaturePtr aFeature = std::dynamic_pointer_cast(aObject); - if (aFeature.get() && aFeature->firstResult().get() - && (aFeature->firstResult()->groupName() == ModelAPI_ResultField::group())) { - ResultFieldPtr aResult = - std::dynamic_pointer_cast(aFeature->firstResult()); - QModelIndex aIndex = objectIndex(aResult); - removeRows(0, aResult->stepsSize(), aIndex); - } else { - QModelIndex aIndex = objectIndex(aObject); - if (aIndex.isValid()) { - emit dataChanged(aIndex, aIndex); - } - } - } else { - rebuildDataTree(); - break; + foreach(ModuleBase_ITreeNode* aNode, aParents) { + aNode->update(); } } - } else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_ORDER_UPDATED)) { + rebuildDataTree(); + emit treeRebuilt(); + } + else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_ORDER_UPDATED)) { std::shared_ptr aUpdMsg = - std::dynamic_pointer_cast(theMessage); + std::dynamic_pointer_cast(theMessage); if (aUpdMsg->reordered().get()) { DocumentPtr aDoc = aUpdMsg->reordered()->document(); std::string aGroup = aUpdMsg->reordered()->group(); + ModuleBase_ITreeNode* aNode = myRoot->findParent(aDoc, aGroup.c_str()); + if (aNode) { + emit beforeTreeRebuild(); + aNode->update(); + rebuildDataTree(); + emit treeRebuilt(); + } + } + } + else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_DOCUMENT_CHANGED)) { + if (ModelAPI_Session::get()->hasModuleDocument()) { + DocumentPtr aDoc = ModelAPI_Session::get()->activeDocument(); + ModuleBase_ITreeNode* aRoot = myRoot->findRoot(aDoc); + if (aRoot) { + updateSubTree(aRoot); + } + } + } + else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY)) { + std::shared_ptr aUpdMsg = + std::dynamic_pointer_cast(theMessage); + std::set aObjects = aUpdMsg->objects(); - QModelIndex aParent; - int aStartId = 0; - if (aDoc == aRootDoc) { - // Update a group under root - if (aGroup == myXMLReader->rootType()) // Update objects under root - aStartId = foldersCount(); - else // Update objects in folder under root - aParent = createIndex(folderId(aGroup), 0, (void*)Q_NULLPTR); - } else { - // Update a sub-document - if (aGroup == myXMLReader->subType()) { - // Update sub-document root - aParent = findDocumentRootIndex(aDoc.get()); - aStartId = foldersCount(aDoc.get()); - } else - // update folder in sub-document - aParent = createIndex(folderId(aGroup, aDoc.get()), 0, aDoc.get()); + QObjectPtrList aCreated; + std::set::const_iterator aIt; + for (aIt = aObjects.cbegin(); aIt != aObjects.cend(); aIt++) { + ObjectPtr aObj = (*aIt); + if (aObj->groupName() == ModelAPI_ResultField::group()) { + aCreated.append(aObj); } - int aChildNb = rowCount(aParent); - rebuildBranch(aStartId, aChildNb - aStartId, aParent); - } else { - rebuildDataTree(); } - } else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_DOCUMENT_CHANGED)) { - DocumentPtr aDoc = ModelAPI_Session::get()->activeDocument(); - if (aDoc != aRootDoc) { - QModelIndex aDocRoot = findDocumentRootIndex(aDoc.get()); - if (aDocRoot.isValid()) - emit dataChanged(aDocRoot, aDocRoot); - else - // We have got a new document - rebuildDataTree(); + if (aCreated.length() == 0) + return; + emit beforeTreeRebuild(); + foreach(ObjectPtr aObj, aCreated) { + ModuleBase_ITreeNode* aNode = myRoot->subNode(aObj); + if (aNode) { + int aOldNb = aNode->childrenCount(); + aNode->update(); + int aNewNb = aNode->childrenCount(); + + QModelIndex aFirstIdx = getIndex(aNode, 0); + QModelIndex aLastIdx = getIndex(aNode, 2); + + if (aNewNb > aOldNb) { + insertRows(aOldNb - 1, aNewNb - aOldNb, aFirstIdx); + } + else if (aNewNb < aOldNb) { + if (aNewNb) + removeRows(aNewNb - 1, aOldNb - aNewNb, aFirstIdx); + else if (aOldNb) + removeRows(0, aOldNb, aFirstIdx); + } + dataChanged(aFirstIdx, aLastIdx); + } } + emit treeRebuilt(); } } @@ -344,175 +281,34 @@ void XGUI_DataModel::rebuildDataTree() { beginResetModel(); endResetModel(); - emit treeRebuilt(); } //****************************************************** ObjectPtr XGUI_DataModel::object(const QModelIndex& theIndex) const { - if (theIndex.internalId() == 0) // this is a folder - return ObjectPtr(); - ModelAPI_Object* aObj = - dynamic_cast((ModelAPI_Entity*)theIndex.internalPointer()); - if (!aObj) - return ObjectPtr(); - if (getSubDocument(aObj)) // the selected index is a folder of sub-document - return ObjectPtr(); - - return aObj->data()->owner(); + if (theIndex.isValid()) { + ModuleBase_ITreeNode* aNode = (ModuleBase_ITreeNode*)theIndex.internalPointer(); + return aNode->object(); + } + return ObjectPtr(); } //****************************************************** -QModelIndex XGUI_DataModel::objectIndex(const ObjectPtr theObject) const +QModelIndex XGUI_DataModel::objectIndex(const ObjectPtr theObject, int theColumn) const { - std::string aType = theObject->groupName(); - DocumentPtr aDoc = theObject->document(); - int aRow = aDoc->index(theObject); - if (aRow == -1) { - // it could be a part of complex object - FeaturePtr aFeature = std::dynamic_pointer_cast(theObject); - if (aFeature.get()) { - CompositeFeaturePtr aCompFea = ModelAPI_Tools::compositeOwner(aFeature); - if (aCompFea.get()) { - for (int i = 0; i < aCompFea->numberOfSubs(true); i++) { - if (aCompFea->subFeature(i, true) == theObject) { - aRow = i; - break; - } - } - } - } else { - ResultPtr aResult = std::dynamic_pointer_cast(theObject); - if (aResult.get()) { - ResultCompSolidPtr aCompRes = ModelAPI_Tools::compSolidOwner(aResult); - if (aCompRes.get()) { - for (int i = 0; i < aCompRes->numberOfSubs(true); i++) { - if (aCompRes->subResult(i, true) == theObject) { - aRow = i; - break; - } - } - } - } - } - if (aRow == -1) - return QModelIndex(); - else - return createIndex(aRow, 0, theObject.get()); + ModuleBase_ITreeNode* aNode = myRoot->subNode(theObject); + if (aNode) { + return getIndex(aNode, theColumn); } - SessionPtr aSession = ModelAPI_Session::get(); - DocumentPtr aRootDoc = aSession->moduleDocument(); - if (aDoc == aRootDoc && myXMLReader->rootType() == aType) { - // The object from root document - aRow += foldersCount(); - } else if (myXMLReader->subType() == aType) { - // The object from sub document - aRow += foldersCount(aDoc.get()); - } - return createIndex(aRow, 0, theObject.get()); + return QModelIndex(); } //****************************************************** QVariant XGUI_DataModel::data(const QModelIndex& theIndex, int theRole) const { - SessionPtr aSession = ModelAPI_Session::get(); - DocumentPtr aRootDoc = aSession->moduleDocument(); - int aNbFolders = foldersCount(); - int theIndexRow = theIndex.row(); - - if ((theRole == Qt::DecorationRole) && (theIndex == lastHistoryIndex())) - return QIcon(":pictures/arrow.png"); - - if (theIndex.column() == 1) - return QVariant(); - - quintptr aParentId = theIndex.internalId(); - if (aParentId == 0) { // root folders - switch (theRole) { - case Qt::DisplayRole: - return QString(myXMLReader->rootFolderName(theIndexRow).c_str()) + - QString(" (%1)").arg(rowCount(theIndex)); - case Qt::DecorationRole: - return QIcon(myXMLReader->rootFolderIcon(theIndexRow).c_str()); - case Qt::ForegroundRole: - { - Qt::ItemFlags aFlags = theIndex.flags(); - if (aFlags == Qt::ItemFlags()) - return QBrush(DISABLED_COLOR); - if (!aFlags.testFlag(Qt::ItemIsEditable)) - return QBrush(SELECTABLE_COLOR); - } - return ACTIVE_COLOR; - } - } else { // an object or sub-document - if (theRole == Qt::ForegroundRole) { - Qt::ItemFlags aFlags = theIndex.flags(); - if (aFlags == Qt::ItemFlags()) - return QBrush(DISABLED_COLOR); - if (!aFlags.testFlag(Qt::ItemIsEditable)) - return QBrush(SELECTABLE_COLOR); - return ACTIVE_COLOR; - } - - ModelAPI_Document* aSubDoc = getSubDocument(theIndex.internalPointer()); - if (aSubDoc) { // this is a folder of sub document - QIntList aMissedIdx = missedFolderIndexes(aSubDoc); - int aRow = theIndexRow; - while (aMissedIdx.contains(aRow)) - aRow++; - if (aRow < myXMLReader->subFoldersNumber()) { - switch (theRole) { - case Qt::DisplayRole: - return QString(myXMLReader->subFolderName(aRow).c_str()) + - QString(" (%1)").arg(rowCount(theIndex)); - case Qt::DecorationRole: - return QIcon(myXMLReader->subFolderIcon(aRow).c_str()); - } - } - } else { - ModelAPI_Object* aObj = - dynamic_cast((ModelAPI_Entity*)theIndex.internalPointer()); - if (aObj) { - switch (theRole) { - case Qt::DisplayRole: - { - if (aObj->groupName() == ModelAPI_ResultParameter::group()) { - ModelAPI_ResultParameter* aParam = dynamic_cast(aObj); - AttributeDoublePtr aValueAttribute = - aParam->data()->real(ModelAPI_ResultParameter::VALUE()); - QString aVal = QString::number(aValueAttribute->value()); - QString aTitle = QString(aObj->data()->name().c_str()); - return aTitle + " = " + aVal; - } - QString aSuffix; - if (aObj->groupName() == myXMLReader->subType()) { - ResultPartPtr aPartRes = getPartResult(aObj); - if (aPartRes.get()) { - if (aPartRes->partDoc().get() == NULL) - aSuffix = " (Not loaded)"; - } - } - return aObj->data()->name().c_str() + aSuffix; - } - case Qt::DecorationRole: - return ModuleBase_IconFactory::get()->getIcon(object(theIndex)); - } - } else { - switch (theRole) { - case Qt::DisplayRole: - { - ModelAPI_ResultField::ModelAPI_FieldStep* aStep = - dynamic_cast - ((ModelAPI_Entity*)theIndex.internalPointer()); - if (aStep) { - return "Step " + QString::number(aStep->id() + 1) + " " + - aStep->field()->textLine(aStep->id()).c_str(); - } - } - break; - } - } - } + if (theIndex.isValid()) { + ModuleBase_ITreeNode* aNode = (ModuleBase_ITreeNode*)theIndex.internalPointer(); + return aNode->data(theIndex.column(), theRole); } return QVariant(); } @@ -526,246 +322,33 @@ QVariant XGUI_DataModel::headerData(int theSection, Qt::Orientation theOrient, i //****************************************************** int XGUI_DataModel::rowCount(const QModelIndex& theParent) const { - SessionPtr aSession = ModelAPI_Session::get(); - if (!aSession->hasModuleDocument()) - return 0; - DocumentPtr aRootDoc = aSession->moduleDocument(); - - if (!theParent.isValid()) { - // Return number of items in root - int aNbFolders = foldersCount(); - int aNbItems = 0; - std::string aType = myXMLReader->rootType(); - if (!aType.empty()) - aNbItems = aRootDoc->size(aType); - return aNbFolders + aNbItems; - } - - quintptr aId = theParent.internalId(); - if (aId == 0) { - // this is a folder under root - int aParentPos = theParent.row(); - std::string aType = myXMLReader->rootFolderType(aParentPos); - return aRootDoc->size(aType); - } else { - // It is an object which could have children - ModelAPI_Document* aDoc = getSubDocument(theParent.internalPointer()); - if (aDoc) { - // a folder of sub-document - QIntList aMissedIdx = missedFolderIndexes(aDoc); - int aRow = theParent.row(); - while (aMissedIdx.contains(aRow)) - aRow++; - if (aRow < myXMLReader->subFoldersNumber()) { - std::string aType = myXMLReader->subFolderType(aRow); - return aDoc->size(aType); - } - } else { - ModelAPI_Object* aObj = - dynamic_cast((ModelAPI_Entity*)theParent.internalPointer()); - // Check for Part feature - ResultPartPtr aPartRes = getPartResult(aObj); - if (aPartRes.get()) { - DocumentPtr aSubDoc = aPartRes->partDoc(); - if (!aSubDoc.get()) - return 0; - - int aNbSubFolders = foldersCount(aSubDoc.get()); - int aNbSubItems = 0; - std::string aSubType = myXMLReader->subType(); - if (!aSubType.empty()) - aNbSubItems = aSubDoc->size(aSubType); - return aNbSubItems + aNbSubFolders; - } else { - // Check for composite object - ModelAPI_CompositeFeature* aCompFeature = dynamic_cast(aObj); - if (aCompFeature) - return aCompFeature->numberOfSubs(true); - ModelAPI_ResultCompSolid* aCompRes = dynamic_cast(aObj); - if (aCompRes) - return aCompRes->numberOfSubs(true); - ModelAPI_ResultField* aFieldRes = dynamic_cast(aObj); - if (aFieldRes) - return aFieldRes->stepsSize(); - } - } - } - return 0; + ModuleBase_ITreeNode* aParentNode = (theParent.isValid()) ? + (ModuleBase_ITreeNode*)theParent.internalPointer() : myRoot; + return aParentNode->childrenCount(); } //****************************************************** int XGUI_DataModel::columnCount(const QModelIndex& theParent) const { - return 2; + return 3; } //****************************************************** QModelIndex XGUI_DataModel::index(int theRow, int theColumn, const QModelIndex &theParent) const { - SessionPtr aSession = ModelAPI_Session::get(); - DocumentPtr aRootDoc = aSession->moduleDocument(); - int aNbFolders = foldersCount(); - - QModelIndex aIndex; - - if (!theParent.isValid()) { - if (theRow < aNbFolders) // Return first level folder index - return createIndex(theRow, theColumn, (void*)Q_NULLPTR); - else { // return object under root index - std::string aType = myXMLReader->rootType(); - int aObjId = theRow - aNbFolders; - if (aObjId < aRootDoc->size(aType)) { - ObjectPtr aObj = aRootDoc->object(aType, aObjId); - aIndex = objectIndex(aObj); - } - } - } else { - quintptr aId = theParent.internalId(); - int aParentPos = theParent.row(); - if (aId == 0) { // return object index inside of first level of folders - std::string aType = myXMLReader->rootFolderType(aParentPos); - if (theRow < aRootDoc->size(aType)) { - ObjectPtr aObj = aRootDoc->object(aType, theRow); - aIndex = objectIndex(aObj); - } - } else { - // It is an object which could have children - ModelAPI_Document* aDoc = getSubDocument(theParent.internalPointer()); - if (aDoc) { - // It is a folder of sub-document - int aParentRow = aParentPos; - QIntList aMissedIdx = missedFolderIndexes(aDoc); - while (aMissedIdx.contains(aParentRow)) - aParentRow++; - if (aParentRow < myXMLReader->subFoldersNumber()) { - std::string aType = myXMLReader->subFolderType(aParentRow); - if (theRow < aDoc->size(aType)) { - ObjectPtr aObj = aDoc->object(aType, theRow); - aIndex = objectIndex(aObj); - } - } - } else { - ModelAPI_Object* aParentObj = - dynamic_cast((ModelAPI_Entity*)theParent.internalPointer()); - - // Check for Part feature - ResultPartPtr aPartRes = getPartResult(aParentObj); - if (aPartRes.get()) { - DocumentPtr aSubDoc = aPartRes->partDoc(); - int aNbSubFolders = foldersCount(aSubDoc.get()); - if (theRow < aNbSubFolders) { // Create a Folder of sub-document - aIndex = createIndex(theRow, theColumn, aSubDoc.get()); - } else { - // this is an object under sub document root - std::string aType = myXMLReader->subType(); - ObjectPtr aObj = aSubDoc->object(aType, theRow - aNbSubFolders); - aIndex = objectIndex(aObj); - } - } else { - // Check for composite object - ModelAPI_CompositeFeature* aCompFeature = - dynamic_cast(aParentObj); - if (aCompFeature) { - aIndex = objectIndex(aCompFeature->subFeature(theRow)); - } else { - ModelAPI_ResultCompSolid* aCompRes = - dynamic_cast(aParentObj); - if (aCompRes) - aIndex = objectIndex(aCompRes->subResult(theRow)); - else { - ModelAPI_ResultField* aFieldRes = - dynamic_cast(aParentObj); - if (aFieldRes) { - aIndex = createIndex(theRow, 0, aFieldRes->step(theRow)); - } - } - } - } - } - } - } - if (theColumn != 0) - return createIndex(aIndex.row(), theColumn, aIndex.internalPointer()); - return aIndex; + ModuleBase_ITreeNode* aParentNode = (theParent.isValid()) ? + (ModuleBase_ITreeNode*)theParent.internalPointer() : myRoot; + ModuleBase_ITreeNode* aSubNode = aParentNode->subNode(theRow); + assert(aSubNode); + return createIndex(theRow, theColumn, aSubNode); } //****************************************************** -static QModelIndex MYLastDeleted; QModelIndex XGUI_DataModel::parent(const QModelIndex& theIndex) const { - if (!theIndex.isValid()) - return QModelIndex(); - // To avoid additional request about index which was already deleted - if (theIndex == MYLastDeleted) - return QModelIndex(); - - SessionPtr aSession = ModelAPI_Session::get(); - quintptr aId = theIndex.internalId(); - if (aId != 0) { // The object is not a root folder - ModelAPI_Document* aDoc = getSubDocument(theIndex.internalPointer()); - if (aDoc) { - // It is a folder of sub-document - return findDocumentRootIndex(aDoc); - } - ObjectPtr aObj = object(theIndex); - if (!aObj.get()) { - // It can b e a step of a field - ModelAPI_ResultField::ModelAPI_FieldStep* aStep = - dynamic_cast - ((ModelAPI_Entity*)theIndex.internalPointer()); - if (aStep) { - ModelAPI_ResultField* aField = aStep->field(); - DocumentPtr aDoc = aSession->activeDocument(); - ObjectPtr aFld; - for(int i = 0; i < aDoc->size(ModelAPI_ResultField::group()); i++) { - aFld = aDoc->object(ModelAPI_ResultField::group(), i); - if (aFld.get() == aField) - return objectIndex(aFld); - } - } - // To avoid additional request about index which was already deleted - // If deleted it causes a crash on delete object from Part - MYLastDeleted = theIndex; - return QModelIndex(); - } - // Check is it object a sub-object of a complex object - FeaturePtr aFeature = std::dynamic_pointer_cast(aObj); - if (aFeature.get()) { - CompositeFeaturePtr aCompFea = ModelAPI_Tools::compositeOwner(aFeature); - if (aCompFea.get()) { - return objectIndex(aCompFea); - } - } - ResultPtr aResult = std::dynamic_pointer_cast(aObj); - if (aResult.get()) { - ResultCompSolidPtr aCompRes = ModelAPI_Tools::compSolidOwner(aResult); - if (aCompRes.get()) { - return objectIndex(aCompRes); - } - } - // Use as ordinary object - std::string aType = aObj->groupName(); - DocumentPtr aRootDoc = aSession->moduleDocument(); - DocumentPtr aSubDoc = aObj->document(); - if (aSubDoc == aRootDoc) { - if (aType == myXMLReader->rootType()) - return QModelIndex(); - else { - // return first level of folder index - int aFolderId = myXMLReader->rootFolderId(aType); - // Items in a one row must have the same parent - return createIndex(aFolderId, 0, (void*)Q_NULLPTR); - } - } else { - if (aType == myXMLReader->subType()) - return findDocumentRootIndex(aSubDoc.get()); - else { - // return first level of folder index - int aFolderId = folderId(aType, aSubDoc.get()); - // Items in a one row must have the same parent - return createIndex(aFolderId, 0, aSubDoc.get()); - } - } + if (theIndex.isValid()) { + ModuleBase_ITreeNode* aNode = (ModuleBase_ITreeNode*)theIndex.internalPointer(); + return getParentIndex(aNode, 1); } return QModelIndex(); } @@ -773,7 +356,9 @@ QModelIndex XGUI_DataModel::parent(const QModelIndex& theIndex) const //****************************************************** bool XGUI_DataModel::hasChildren(const QModelIndex& theParent) const { - return rowCount(theParent) > 0; + ModuleBase_ITreeNode* aParentNode = (theParent.isValid()) ? + (ModuleBase_ITreeNode*)theParent.internalPointer() : myRoot; + return aParentNode->childrenCount() > 0; } //****************************************************** @@ -781,7 +366,6 @@ bool XGUI_DataModel::insertRows(int theRow, int theCount, const QModelIndex& the { beginInsertRows(theParent, theRow, theRow + theCount - 1); endInsertRows(); - return true; } @@ -796,259 +380,249 @@ bool XGUI_DataModel::removeRows(int theRow, int theCount, const QModelIndex& the //****************************************************** Qt::ItemFlags XGUI_DataModel::flags(const QModelIndex& theIndex) const { - quintptr aIt = theIndex.internalId(); - ModelAPI_Object* aObj = 0; - ModelAPI_Document* aDoc = 0; - SessionPtr aSession = ModelAPI_Session::get(); - DocumentPtr aActiveDoc = aSession->activeDocument(); - - Qt::ItemFlags aNullFlag; - Qt::ItemFlags aDefaultFlag = Qt::ItemIsSelectable | Qt::ItemIsEnabled; - Qt::ItemFlags aEditingFlag = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable; - - - if (aIt == 0) { - // Folders under root - DocumentPtr aRootDoc = aSession->moduleDocument(); - if (aRootDoc != aActiveDoc) - return aDefaultFlag; - } else { - aDoc = getSubDocument(theIndex.internalPointer()); - if (!aDoc) - aObj = dynamic_cast((ModelAPI_Entity*)theIndex.internalPointer()); + if (theIndex.isValid()) { + ModuleBase_ITreeNode* aNode = static_cast(theIndex.internalPointer()); + // Check that the pointer is Valid + if (!isValidNode(aNode)) + return Qt::NoItemFlags; + Qt::ItemFlags aResultFlags = aNode->flags(theIndex.column()); + // Drag and drop of Part features only if: + // - PartSet is active + // - active Part feature of PartSet is dragged + // - finally if it does not break dependencies between features (but here only drag possibility is checked) + SessionPtr aSession = ModelAPI_Session::get(); + if (aSession->hasModuleDocument() && aSession->moduleDocument() == aSession->activeDocument()) { + + ObjectPtr aNodeObj = aNode->object(); + if (aNodeObj.get() && aNodeObj->groupName() == ModelAPI_Feature::group()) + { + FeaturePtr aNodeFeature = std::dynamic_pointer_cast(aNodeObj); + if (aNodeFeature.get() && aNodeFeature->getKind() == "Part" && !aNodeFeature->isDisabled()) + aResultFlags |= Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled; + } + } + return aResultFlags; } + return Qt::ItemIsDropEnabled | Qt::ItemFlags(); +} - if (aObj) { - // An object - if (aObj->isDisabled()) - return theIndex.column() == 1? Qt::ItemIsSelectable : aNullFlag; - - if (aSession->moduleDocument() != aObj->document()) - if (aActiveDoc != aObj->document()) - return theIndex.column() == 1? Qt::ItemIsSelectable : aNullFlag; +bool XGUI_DataModel::canDropMimeData(const QMimeData *theData, Qt::DropAction theAction, + int theRow, int theColumn, const QModelIndex &theParent) const +{ + if (theParent.isValid()) + return false; + ModuleBase_ITreeNode* aSubNode = myRoot->subNode(theRow); + if ((aSubNode && aSubNode->object() && aSubNode->object()->groupName() == ModelAPI_Feature::group()) + || theRow == myRoot->childrenCount()) // into the end of a list of features + { + return true; + } - bool isCompositeSub = false; - // An object which is sub-object of a composite object can not be accessible in column 1 - if (theIndex.column() == 1) { - ObjectPtr aObjPtr = aObj->data()->owner(); - FeaturePtr aFeature = std::dynamic_pointer_cast(aObjPtr); - if (aFeature.get()) { - CompositeFeaturePtr aCompFea = ModelAPI_Tools::compositeOwner(aFeature); - if (aCompFea.get()) - isCompositeSub = true; - } else { - ResultPtr aResult = std::dynamic_pointer_cast(aObjPtr); - if (aResult.get()) { - ResultCompSolidPtr aCompRes = ModelAPI_Tools::compSolidOwner(aResult); - if (aCompRes.get()) - isCompositeSub = true; - } - } - } - if (isCompositeSub) - return Qt::ItemIsSelectable; + return false; // in other cases drop is forbidden +} - if (aObj->document() != aActiveDoc) { - // The object could be a root of sub-tree - ResultPartPtr aPartRes = getPartResult(aObj); - if (aPartRes.get()) { - if (aPartRes->partDoc() == aActiveDoc) - return aEditingFlag; - } - return aDefaultFlag; - } - } else if (aDoc) { - // A folder under sub-document - if (aActiveDoc.get() != aDoc) - return aNullFlag; +QMimeData* XGUI_DataModel::mimeData(const QModelIndexList& theIndexes) const +{ + std::set aRows; // to avoid duplication of rows and for sorting the indices + foreach (QModelIndex anIndex, theIndexes) { + if (anIndex.isValid() && anIndex.internalPointer()) + aRows.insert(anIndex.row()); } - return aEditingFlag; + QByteArray anEncodedData; + QDataStream aStream(&anEncodedData, QIODevice::WriteOnly); + for(std::set::iterator aRIter = aRows.begin(); aRIter != aRows.end(); aRIter++) + aStream << *aRIter; + + QMimeData* aMimeData = new QMimeData(); + aMimeData->setData("xgui/moved.rows", anEncodedData); + return aMimeData; } -//****************************************************** -QModelIndex XGUI_DataModel::findDocumentRootIndex(const ModelAPI_Document* theDoc) const +bool XGUI_DataModel::dropMimeData(const QMimeData *theData, Qt::DropAction theAction, + int theRow, int theColumn, const QModelIndex &theParent) { + FeaturePtr aDropAfter; // after this feature it is dropped, NULL if drop the the first place + if (theRow > 0) + { + ModuleBase_ITreeNode* aNode = myRoot->subNode(theRow - 1); + if (aNode && aNode->object() && aNode->object()->groupName() == ModelAPI_Feature::group()) + aDropAfter = std::dynamic_pointer_cast(aNode->object()); + } SessionPtr aSession = ModelAPI_Session::get(); - DocumentPtr aRootDoc = aSession->moduleDocument(); - if (myXMLReader->isAttachToResult()) { // If document is attached to result - int aNb = aRootDoc->size(ModelAPI_ResultPart::group()); - ObjectPtr aObj; - ResultPartPtr aPartRes; - for (int i = 0; i < aNb; i++) { - aObj = aRootDoc->object(ModelAPI_ResultPart::group(), i); - aPartRes = std::dynamic_pointer_cast(aObj); - if (aPartRes.get() && (aPartRes->partDoc().get() == theDoc)) { - int aRow = i; - if (myXMLReader->rootType() == ModelAPI_Feature::group()) { - aRow += foldersCount(); - } - return createIndex(aRow, 0, aObj.get()); - } + if (aDropAfter.get()) // move to the upper enabled feature + { + while (aDropAfter.get() && (aDropAfter->isDisabled() || !aDropAfter->isInHistory())) + aDropAfter = aDropAfter->document()->nextFeature(aDropAfter, true); + } + else { // move after invisible items, not the first (which is coordinate system by default) + std::list allFeatures = aSession->get()->moduleDocument()->allFeatures(); + std::list::iterator aFeature = allFeatures.begin(); + for(; aFeature != allFeatures.end(); aFeature++) + { + if ((*aFeature)->isInHistory()) + break; + aDropAfter = *aFeature; } - } else { // If document is attached to feature - int aNb = aRootDoc->size(ModelAPI_Feature::group()); - ObjectPtr aObj; - ResultPartPtr aPartRes; - for (int i = 0; i < aNb; i++) { - aObj = aRootDoc->object(ModelAPI_Feature::group(), i); - aPartRes = getPartResult(aObj.get()); - if (aPartRes.get() && (aPartRes->partDoc().get() == theDoc)) { - int aRow = i; - if (myXMLReader->rootType() == ModelAPI_Feature::group()) - aRow += foldersCount(); - return createIndex(aRow, 0, aObj.get()); - } + } + // move after the composite feature memebers, if they are invisible (sub elements of sketch) + CompositeFeaturePtr aComposite = std::dynamic_pointer_cast(aDropAfter); + if (aComposite.get()) + { + FeaturePtr aNext = aDropAfter->document()->nextFeature(aDropAfter); + while (aNext.get() && !aNext->isInHistory() && aComposite->isSub(aNext)) { + aDropAfter = aNext; + aNext = aDropAfter->document()->nextFeature(aNext); } } - return QModelIndex(); + + QByteArray anEncodedData = theData->data("xgui/moved.rows"); + if (anEncodedData.isEmpty()) + return false; // dropped something alien, decline + + QDataStream stream(&anEncodedData, QIODevice::ReadOnly); + std::list aDropped; + while (!stream.atEnd()) { + int aRow; + stream >> aRow; + ModuleBase_ITreeNode* aNode = myRoot->subNode(aRow); + if (aNode) + { + FeaturePtr aFeature = std::dynamic_pointer_cast(aNode->object()); + // feature moved after itself is not moved, add only Part feature, other skip + if (aFeature.get() && aFeature != aDropAfter && aFeature->getKind() == "Part") + aDropped.push_back(aFeature); + } + } + if (aDropped.empty()) // nothing to move + return false; + + // check for the movement is valid due to existing dependencies + std::wstring anErrorStr = ModelAPI_Tools::validateMovement(aDropAfter, aDropped); + if (!anErrorStr.empty()) + { + QMessageBox aMessageBox; + aMessageBox.setWindowTitle(QObject::tr("Move part")); + aMessageBox.setIcon(QMessageBox::Warning); + aMessageBox.setStandardButtons(QMessageBox::Ok); + aMessageBox.setDefaultButton(QMessageBox::Ok); + QString aMessageText(QObject::tr("Part(s) cannot be moved because of breaking dependencies.")); + aMessageBox.setText(aMessageText); + aMessageBox.setDetailedText(QString::fromStdWString(anErrorStr)); + aMessageBox.exec(); + return false; + } + + if (aSession->isOperation()) + { + QMessageBox aMessageBox; + aMessageBox.setWindowTitle(QObject::tr("Move part")); + aMessageBox.setIcon(QMessageBox::Warning); + aMessageBox.setStandardButtons(QMessageBox::Ok); + aMessageBox.setDefaultButton(QMessageBox::Ok); + QString aMessageText(QObject::tr("Cannot move part(s) during another operation.")); + aMessageBox.setText(aMessageText); + aMessageBox.exec(); + return false; + } + + aSession->startOperation("Move Part"); + DocumentPtr aPartSet = aSession->moduleDocument(); + for (std::list::iterator aDrop = aDropped.begin(); aDrop != aDropped.end(); aDrop++) + { + aPartSet->moveFeature(*aDrop, aDropAfter); + aDropAfter = *aDrop; + } + aSession->finishOperation(); + + updateSubTree(myRoot); + myWorkshop->updateHistory(); + + // returns false in any case to avoid calling removeRows after it, + return false; // because number of rows stays the same } //****************************************************** -QModelIndex XGUI_DataModel::documentRootIndex(DocumentPtr theDoc) const +QModelIndex XGUI_DataModel::documentRootIndex(DocumentPtr theDoc, int theColumn) const { SessionPtr aSession = ModelAPI_Session::get(); DocumentPtr aRootDoc = aSession->moduleDocument(); if (theDoc == aRootDoc) return QModelIndex(); - else - return findDocumentRootIndex(theDoc.get()); -} - -//****************************************************** -int XGUI_DataModel::foldersCount(ModelAPI_Document* theDoc) const -{ - int aNb = 0; - SessionPtr aSession = ModelAPI_Session::get(); - DocumentPtr aRootDoc = aSession->moduleDocument(); - if ((theDoc == 0) || (theDoc == aRootDoc.get())) { - for (int i = 0; i < myXMLReader->rootFoldersNumber(); i++) { - if (myXMLReader->rootShowEmpty(i)) - aNb++; - else { - if (aRootDoc->size(myXMLReader->rootFolderType(i)) > 0) - aNb++; - } - } - } else { - for (int i = 0; i < myXMLReader->subFoldersNumber(); i++) { - if (myXMLReader->subShowEmpty(i)) - aNb++; - else { - if (theDoc->size(myXMLReader->subFolderType(i)) > 0) - aNb++; + else { + ModuleBase_ITreeNode* aDocNode = 0; + foreach(ModuleBase_ITreeNode* aNode, myRoot->children()) { + if (aNode->document() == theDoc) { + aDocNode = aNode; + break; } } + if (aDocNode) + return getIndex(aDocNode, theColumn); } - return aNb; + return QModelIndex(); } - //****************************************************** -QIntList XGUI_DataModel::missedFolderIndexes(ModelAPI_Document* theDoc) const +bool XGUI_DataModel::hasHiddenState(const QModelIndex& theIndex) { - QIntList aList; - SessionPtr aSession = ModelAPI_Session::get(); - DocumentPtr aRootDoc = aSession->moduleDocument(); - if ((theDoc == 0) || (theDoc == aRootDoc.get())) { - for (int i = 0; i < myXMLReader->rootFoldersNumber(); i++) { - if (!myXMLReader->rootShowEmpty(i)) { - if (aRootDoc->size(myXMLReader->rootFolderType(i)) == 0) - aList.append(i); - } - } - } else { - for (int i = 0; i < myXMLReader->subFoldersNumber(); i++) { - if (!myXMLReader->subShowEmpty(i)) { - if (theDoc->size(myXMLReader->subFolderType(i)) == 0) - aList.append(i); - } - } + if (theIndex.isValid()) { + ModuleBase_ITreeNode* aNode = (ModuleBase_ITreeNode*)theIndex.internalPointer(); + return aNode->visibilityState() == ModuleBase_ITreeNode::Hidden; } - return aList; + return false; } - //****************************************************** -QStringList XGUI_DataModel::listOfShowNotEmptyFolders(bool fromRoot) const +bool XGUI_DataModel::hasIndex(const QModelIndex& theIndex) const { - QStringList aResult; - if (fromRoot) { - for (int i = 0; i < myXMLReader->rootFoldersNumber(); i++) { - if (!myXMLReader->rootShowEmpty(i)) - aResult << myXMLReader->rootFolderType(i).c_str(); - } - } else { - for (int i = 0; i < myXMLReader->subFoldersNumber(); i++) { - if (!myXMLReader->subShowEmpty(i)) - aResult << myXMLReader->subFolderType(i).c_str(); - } - } - return aResult; + ModuleBase_ITreeNode* aNode = (ModuleBase_ITreeNode*)theIndex.internalPointer(); + return myRoot->hasSubNode(aNode); } //****************************************************** -QModelIndex XGUI_DataModel::lastHistoryIndex() const +QModelIndex XGUI_DataModel::getParentIndex(ModuleBase_ITreeNode* theNode, int thCol) const { - SessionPtr aSession = ModelAPI_Session::get(); - DocumentPtr aCurDoc = aSession->activeDocument(); - FeaturePtr aFeature = aCurDoc->currentFeature(true); - if (aFeature.get()) { - QModelIndex aInd = objectIndex(aFeature); - return createIndex(aInd.row(), 1, aInd.internalPointer()); + ModuleBase_ITreeNode* aParent = theNode->parent(); + if (aParent == myRoot) { + return QModelIndex(); } else { - if (aCurDoc == aSession->moduleDocument()) - return createIndex(foldersCount() - 1, 1, -1); - else - return createIndex(foldersCount(aCurDoc.get()) - 1, 1, aCurDoc.get()); + return getIndex(aParent, thCol); } } //****************************************************** -int XGUI_DataModel::folderId(std::string theType, ModelAPI_Document* theDoc) const +QModelIndex XGUI_DataModel::getIndex(ModuleBase_ITreeNode* theNode, int thCol) const { - SessionPtr aSession = ModelAPI_Session::get(); - ModelAPI_Document* aDoc = theDoc; - if (aDoc == 0) - aDoc = aSession->moduleDocument().get(); + if (theNode == myRoot) + return QModelIndex(); + int aRow = theNode->parent()->nodeRow(theNode); + return createIndex(aRow, thCol, theNode); +} - bool aUseSubDoc = (aDoc != aSession->moduleDocument().get()); - int aRes = -1; - if (aUseSubDoc) { - int aId = myXMLReader->subFolderId(theType); - aRes = aId; - for (int i = 0; i < aId; i++) { - if (!myXMLReader->subShowEmpty(i)) { - if (aDoc->size(myXMLReader->subFolderType(i)) == 0) - aRes--; - } - } - } else { - int aId = myXMLReader->rootFolderId(theType); - aRes = aId; - for (int i = 0; i < aId; i++) { - if (!myXMLReader->rootShowEmpty(i)) { - if (aDoc->size(myXMLReader->rootFolderType(i)) == 0) - aRes--; - } - } +//****************************************************** +void XGUI_DataModel::updateSubTree(ModuleBase_ITreeNode* theParent) +{ + int aRows = theParent->childrenCount(); + if (aRows) { + QModelIndex aParent = getIndex(theParent, 0); + QModelIndex aFirstIdx = aParent.child(0, 0); + QModelIndex aLastIdx = aParent.child(aRows - 1, 2); + dataChanged(aFirstIdx, aLastIdx); } - return aRes; } + //****************************************************** -void XGUI_DataModel::rebuildBranch(int theRow, int theCount, const QModelIndex& theParent) +DocumentPtr XGUI_DataModel::document(const QModelIndex& theIndex) const { - if (theCount > 0) { - removeRows(theRow, theCount, theParent); - insertRows(theRow, theCount, theParent); - } + ModuleBase_ITreeNode* aNode = (ModuleBase_ITreeNode*)theIndex.internalPointer(); + return aNode->document(); } + //****************************************************** -//bool XGUI_DataModel::blockEventsProcessing(const bool theState) -//{ -// bool aPreviousState = myIsEventsProcessingBlocked; -// myIsEventsProcessingBlocked = theState; -// return aPreviousState; -//} +bool XGUI_DataModel::hasNode(ModuleBase_ITreeNode* theNode) const +{ + return myRoot->hasSubNode(theNode); +}