From: vsv Date: Thu, 19 Jul 2018 12:56:52 +0000 (+0300) Subject: Redevelopment of object browser data model X-Git-Tag: SHAPER_V9_1_0RC1~73^2~59 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=0698959843945efd4d1007b85e918e8b6db31c32;p=modules%2Fshaper.git Redevelopment of object browser data model --- diff --git a/src/ModuleBase/ModuleBase_ITreeNode.h b/src/ModuleBase/ModuleBase_ITreeNode.h index 954e72f03..9e33eeae5 100644 --- a/src/ModuleBase/ModuleBase_ITreeNode.h +++ b/src/ModuleBase/ModuleBase_ITreeNode.h @@ -22,14 +22,18 @@ #define ModuleBase_ITreeNode_H #include "ModuleBase.h" +#include "ModuleBase_Definitions.h" #include +#include #include #include #include +#include class ModuleBase_ITreeNode; +class ModuleBase_IWorkshop; typedef QList QTreeNodesList; @@ -37,19 +41,13 @@ class ModuleBase_ITreeNode { public: /// Default constructor - ModuleBase_ITreeNode() : myParent(0) {} + ModuleBase_ITreeNode(ModuleBase_ITreeNode* theParent = 0) : myParent(theParent) {} - /// Returns name of the node - virtual QString name() const { return "Item"; } - - /// Returns icon of the node - virtual QIcon icon() const { return QIcon(); } - - /// Returns foreground color of the node - virtual QColor color() const { return Qt::black; } + /// Returns the node representation according to theRole. + virtual QVariant data(int theColumn, int theRole) const { return QVariant(); } /// Returns properties flag of the item - virtual Qt::ItemFlags falg() const { return Qt::ItemIsSelectable | Qt::ItemIsEnabled; } + virtual Qt::ItemFlags flags(int theColumn) const { return Qt::ItemIsSelectable | Qt::ItemIsEnabled; } /// Returns parent node of the current node ModuleBase_ITreeNode* parent() const { return myParent; } @@ -57,9 +55,83 @@ public: /// Returns list of the node children QTreeNodesList children() const { return myChildren; } + /// Returns a children node according to given row (index) + ModuleBase_ITreeNode* subNode(int theRow) const + { + if ((theRow > -1) && (theRow < myChildren.length())) + return myChildren.at(theRow); + return 0; + } + + /// Finds a node which contains the referenced object + /// \param theObj an object to find + /// \param allLevels if true then all sub-trees will be processed + ModuleBase_ITreeNode* subNode(const ObjectPtr& theObj, bool allLevels = true) const + { + foreach(ModuleBase_ITreeNode* aNode, myChildren) { + if (aNode->object() == theObj) + return aNode; + if (allLevels) { + ModuleBase_ITreeNode* aSubNode = aNode->subNode(theObj, allLevels); + if (aSubNode) + return aSubNode; + } + } + return 0; + } + + /// Returns true if the given node is found within children + /// \param theNode a node to find + /// \param allLevels if true then all sub-trees will be processed + bool hasSubNode(ModuleBase_ITreeNode* theNode, bool allLevels = true) const + { + foreach(ModuleBase_ITreeNode* aNode, myChildren) { + if (aNode == theNode) + return true; + if (allLevels) { + if (aNode->hasSubNode(theNode)) + return true; + } + } + return false; + } + + /// Returns number of children + int childrenCount() const { return myChildren.length(); } + + int nodeRow(ModuleBase_ITreeNode* theNode) const { return myChildren.indexOf(theNode); } + /// Returns object referenced by the node (can be null) virtual ObjectPtr object() const { return ObjectPtr(); } + /// Updates all sub-nodes of the node (checks whole sub-tree) + virtual void update() {} + + /// Process creation of objects. + /// \param theObjects a list of created objects + /// \return a list of nodes which corresponds to the created objects + virtual QTreeNodesList objectCreated(const QObjectPtrList& theObjects) { return QTreeNodesList(); } + + /// Process deletion of objects. + /// \param theDoc a document where objects were deleted + /// \param theGroup a name of group where objects were deleted + /// \return a list of parents where nodes were deleted + virtual QTreeNodesList objectsDeleted(const DocumentPtr& theDoc, const QString& theGroup) + { return QTreeNodesList(); } + + /// Returns workshop object. Has to be reimplemented in a root node + virtual ModuleBase_IWorkshop* workshop() const { return parent()->workshop(); } + + /// Returns document object of the sub-tree. Has to be reimplemented in sub-tree root object + virtual DocumentPtr document() const { return parent()->document(); } + + /// Returns a node which belongs to the given document and contains objects of the given group + /// \param theDoc a document + /// \param theGroup a name of objects group + /// \return a parent node if it is found + virtual ModuleBase_ITreeNode* findParent(const DocumentPtr& theDoc, QString theGroup) + { return 0; } + protected: ModuleBase_ITreeNode* myParent; //!< Parent of the node QTreeNodesList myChildren; //!< Children of the node diff --git a/src/ModuleBase/ModuleBase_IWorkshop.h b/src/ModuleBase/ModuleBase_IWorkshop.h index e9a4d2c35..e8cf8b622 100644 --- a/src/ModuleBase/ModuleBase_IWorkshop.h +++ b/src/ModuleBase/ModuleBase_IWorkshop.h @@ -112,6 +112,10 @@ Q_OBJECT //! \param theAIS a presentation virtual ObjectPtr findPresentedObject(const AISObjectPtr& theAIS) const = 0; + //! Returns true if the object is displayed + //! \param theObject a data object + virtual bool isVisible(const ObjectPtr& theObject) const = 0; + //! Select features clearing previous selection. //! If the list is empty then selection will be cleared //! \param theValues a list of presentations diff --git a/src/ModuleBase/ModuleBase_OperationFeature.cpp b/src/ModuleBase/ModuleBase_OperationFeature.cpp index c54669495..b7b72a47b 100755 --- a/src/ModuleBase/ModuleBase_OperationFeature.cpp +++ b/src/ModuleBase/ModuleBase_OperationFeature.cpp @@ -187,10 +187,10 @@ FeaturePtr ModuleBase_OperationFeature::createFeature(const bool theFlushMessage }*/ } - if (theFlushMessage) { - Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_CREATED)); - Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED)); - } + //if (theFlushMessage) { + // Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_CREATED)); + // Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED)); + //} return myFeature; } diff --git a/src/PartSet/CMakeLists.txt b/src/PartSet/CMakeLists.txt index 2ed698518..c029f0565 100644 --- a/src/PartSet/CMakeLists.txt +++ b/src/PartSet/CMakeLists.txt @@ -58,7 +58,6 @@ SET(PROJECT_HEADERS PartSet_WidgetSketchLabel.h PartSet_CenterPrs.h PartSet_ExternalPointsMgr.h - PartSet_DataModel.h PartSet_TreeNodes.h ) @@ -108,7 +107,6 @@ SET(PROJECT_SOURCES PartSet_WidgetSketchLabel.cpp PartSet_CenterPrs.cpp PartSet_ExternalPointsMgr.cpp - PartSet_DataModel.cpp PartSet_TreeNodes.cpp ) diff --git a/src/PartSet/PartSet_DataModel.cpp b/src/PartSet/PartSet_DataModel.cpp index 57f0735b5..a95e64d8b 100644 --- a/src/PartSet/PartSet_DataModel.cpp +++ b/src/PartSet/PartSet_DataModel.cpp @@ -19,6 +19,7 @@ // #include "PartSet_DataModel.h" +#include "PartSet_TreeNodes.h" #include @@ -26,12 +27,12 @@ PartSet_DataModel::PartSet_DataModel() { - 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)); +// 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)); } diff --git a/src/PartSet/PartSet_Module.cpp b/src/PartSet/PartSet_Module.cpp index 14d46deae..b5c1821be 100755 --- a/src/PartSet/PartSet_Module.cpp +++ b/src/PartSet/PartSet_Module.cpp @@ -38,7 +38,7 @@ #include "PartSet_CustomPrs.h" #include "PartSet_IconFactory.h" #include "PartSet_OverconstraintListener.h" -#include "PartSet_DataModel.h" +#include "PartSet_TreeNodes.h" #include "PartSet_Filters.h" #include "PartSet_FilterInfinite.h" @@ -151,6 +151,7 @@ extern "C" PARTSET_EXPORT ModuleBase_IModule* createModule(ModuleBase_IWorkshop* PartSet_Module::PartSet_Module(ModuleBase_IWorkshop* theWshop) : ModuleBase_IModule(theWshop), myVisualLayerId(0), + myRoot(0), myIsOperationIsLaunched(false) { new PartSet_IconFactory(); @@ -158,8 +159,6 @@ PartSet_Module::PartSet_Module(ModuleBase_IWorkshop* theWshop) mySketchMgr = new PartSet_SketcherMgr(this); mySketchReentrantMgr = new PartSet_SketcherReentrantMgr(theWshop); - myDataModel = new PartSet_DataModel(); - XGUI_ModuleConnector* aConnector = dynamic_cast(theWshop); XGUI_Workshop* aWorkshop = aConnector->workshop(); @@ -222,8 +221,18 @@ PartSet_Module::~PartSet_Module() } delete myCustomPrs; delete myOverconstraintListener; + delete myRoot; +} + +//****************************************************** +void PartSet_Module::createFeatures() +{ + ModuleBase_IModule::createFeatures(); + myRoot = new PartSet_RootNode(); + myRoot->setWorkshop(workshop()); } + //****************************************************** void PartSet_Module::storeSelection() { @@ -1644,5 +1653,5 @@ void PartSet_Module::setDefaultConstraintShown() //****************************************************** ModuleBase_ITreeNode* PartSet_Module::rootNode() const { - return myDataModel->root(); + return myRoot; } diff --git a/src/PartSet/PartSet_Module.h b/src/PartSet/PartSet_Module.h index d196b6bdd..3979a599b 100755 --- a/src/PartSet/PartSet_Module.h +++ b/src/PartSet/PartSet_Module.h @@ -58,7 +58,7 @@ class PartSet_MenuMgr; class PartSet_CustomPrs; class PartSet_SketcherMgr; class PartSet_SketcherReentrantMgr; -class PartSet_DataModel; +class PartSet_RootNode; class ModelAPI_Result; class QAction; @@ -400,6 +400,9 @@ public: /// Returns the workshop XGUI_Workshop* getWorkshop() const; + /// Reads description of features from XML file + virtual void createFeatures(); + public slots: /// Slolt called on object display /// \param theObject a data object @@ -495,7 +498,7 @@ private: PartSet_SketcherMgr::FeatureToSelectionMap myCurrentSelection; QModelIndex myActivePartIndex; - PartSet_DataModel* myDataModel; + PartSet_RootNode* myRoot; }; #endif diff --git a/src/PartSet/PartSet_TreeNodes.cpp b/src/PartSet/PartSet_TreeNodes.cpp index 3d029e57b..6c1c9dd89 100644 --- a/src/PartSet/PartSet_TreeNodes.cpp +++ b/src/PartSet/PartSet_TreeNodes.cpp @@ -20,8 +20,703 @@ #include "PartSet_TreeNodes.h" +#include +#include -PartSet_RootNode::PartSet_RootNode() +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include + + +#define ACTIVE_COLOR QColor(Qt::black) +#define SELECTABLE_COLOR QColor(100, 100, 100) +#define DISABLED_COLOR QColor(200, 200, 200) + +Qt::ItemFlags aNullFlag; +Qt::ItemFlags aDefaultFlag = Qt::ItemIsSelectable | Qt::ItemIsEnabled; +Qt::ItemFlags aEditingFlag = Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsEditable; + + +ResultPartPtr getPartResult(const ObjectPtr& theObj) +{ + FeaturePtr aFeature = std::dynamic_pointer_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; + } + } + return ResultPartPtr(); +} + +bool isCurrentFeature(const ObjectPtr& theObj) +{ + SessionPtr aSession = ModelAPI_Session::get(); + DocumentPtr aCurDoc = aSession->activeDocument(); + FeaturePtr aFeature = aCurDoc->currentFeature(true); + return aFeature == theObj; +} + +////////////////////////////////////////////////////////////////////////////////// +QVariant PartSet_TreeNode::data(int theColumn, int theRole) const +{ + if ((theColumn == 1) && (theRole == Qt::ForegroundRole)) { + Qt::ItemFlags aFlags = flags(theColumn); + if (aFlags == Qt::ItemFlags()) + return QBrush(DISABLED_COLOR); + if (!aFlags.testFlag(Qt::ItemIsEditable)) + return QBrush(SELECTABLE_COLOR); + return ACTIVE_COLOR; + } + return ModuleBase_ITreeNode::data(theColumn, theRole); +} + + +////////////////////////////////////////////////////////////////////////////////// +QVariant PartSet_ObjectNode::data(int theColumn, int theRole) const +{ + switch (theRole) { + case Qt::DisplayRole: + if (theColumn == 1) { + if (myObject->groupName() == ModelAPI_ResultParameter::group()) { + ResultParameterPtr aParam = std::dynamic_pointer_cast(myObject); + AttributeDoublePtr aValueAttribute = + aParam->data()->real(ModelAPI_ResultParameter::VALUE()); + QString aVal = QString::number(aValueAttribute->value()); + QString aTitle = QString(myObject->data()->name().c_str()); + return aTitle + " = " + aVal; + } + return myObject->data()->name().c_str(); + } + break; + case Qt::DecorationRole: + switch (theColumn) { + case 0: + switch (getVisibilityState()) { + case NoneState: + return QIcon(); + case Visible: + return QIcon(":pictures/eyeopen.png"); + case SemiVisible: + return QIcon(":pictures/eyemiclosed.png"); + case Hidden: + return QIcon(":pictures/eyeclosed.png"); + } + case 1: + return ModuleBase_IconFactory::get()->getIcon(myObject); + case 2: + if (isCurrentFeature(myObject)) + return QIcon(":pictures/arrow.png"); + } + } + return PartSet_TreeNode::data(theColumn, theRole); +} + +Qt::ItemFlags PartSet_ObjectNode::flags(int theColumn) const +{ + if (!myObject->isDisabled()) { + DocumentPtr aDoc = myObject->document(); + SessionPtr aSession = ModelAPI_Session::get(); + if (aSession->activeDocument() == aDoc) + return aEditingFlag; + } + return aDefaultFlag; +} + +PartSet_ObjectNode::VisibilityState PartSet_ObjectNode::getVisibilityState() const +{ + Qt::ItemFlags aFlags = flags(1); + if (aFlags == Qt::ItemFlags()) + return NoneState; + + if (myObject->groupName() == ModelAPI_ResultParameter::group()) + return NoneState; + ResultPtr aResObj = std::dynamic_pointer_cast(myObject); + if (aResObj.get()) { + ModuleBase_IWorkshop* aWork = workshop(); + ResultCompSolidPtr aCompRes = std::dynamic_pointer_cast(aResObj); + if (aCompRes.get()) { + VisibilityState aState = aCompRes->numberOfSubs(true) == 0 ? + (aWork->isVisible(aCompRes) ? Visible : Hidden) : NoneState; + for (int i = 0; i < aCompRes->numberOfSubs(true); i++) { + ResultPtr aSubRes = aCompRes->subResult(i, true); + VisibilityState aS = aWork->isVisible(aSubRes) ? Visible : Hidden; + if (aState == NoneState) + aState = aS; + else if (aState != aS) { + aState = SemiVisible; + break; + } + } + return aState; + } else { + if (aWork->isVisible(aResObj)) + return Visible; + else + return Hidden; + } + } + return NoneState; +} + + +////////////////////////////////////////////////////////////////////////////////// +PartSet_FolderNode::PartSet_FolderNode(ModuleBase_ITreeNode* theParent, + FolderType theType) + : PartSet_TreeNode(theParent), myType(theType) +{ +} + +PartSet_FolderNode::~PartSet_FolderNode() +{ + while (myChildren.length() > 0) { + ModuleBase_ITreeNode* aNode = myChildren.last(); + myChildren.removeAll(aNode); + delete aNode; + } +} + +QString PartSet_FolderNode::name() const +{ + switch (myType) { + case ParametersFolder: + return QObject::tr("Parameters"); + case ConstructionFolder: + return QObject::tr("Constructions"); + case PartsFolder: + return QObject::tr("Parts"); + case ResultsFolder: + return QObject::tr("Results"); + case FieldsFolder: + return QObject::tr("Fields"); + case GroupsFolder: + return QObject::tr("Groups"); + } + return "NoName"; +} + + +QVariant PartSet_FolderNode::data(int theColumn, int theRole) const +{ + static QIcon aParamsIco(":pictures/params_folder.png"); + static QIcon aConstrIco(":pictures/constr_folder.png"); + + if (theColumn == 1) { + switch (theRole) { + case Qt::DisplayRole: + return name() + QString(" (%1)").arg(childrenCount()); + case Qt::DecorationRole: + switch (myType) { + case ParametersFolder: + return aParamsIco; + case ConstructionFolder: + return aConstrIco; + case PartsFolder: + return aConstrIco; + case ResultsFolder: + return aConstrIco; + case FieldsFolder: + return aConstrIco; + case GroupsFolder: + return aConstrIco; + } + } + } + return PartSet_TreeNode::data(theColumn, theRole); +} + +Qt::ItemFlags PartSet_FolderNode::flags(int theColumn) const +{ + SessionPtr aSession = ModelAPI_Session::get(); + DocumentPtr aActiveDoc = aSession->activeDocument(); + if (theColumn == 1) { + if (document() == aActiveDoc) + return aEditingFlag; + } + return aDefaultFlag; +} + +void PartSet_FolderNode::update() +{ + DocumentPtr aDoc = document(); + if (!aDoc.get()) + return; + + // Remove extra sub-nodes + QTreeNodesList aDelList; + foreach(ModuleBase_ITreeNode* aNode, myChildren) { + if (aDoc->index(aNode->object()) == -1) + aDelList.append(aNode); + } + foreach(ModuleBase_ITreeNode* aNode, aDelList) { + myChildren.removeAll(aNode); + delete aNode; + } + + // Add new nodes + std::string aGroup = groupName(); + int aSize = aDoc->size(aGroup); + for (int i = 0; i < aSize; i++) { + ObjectPtr aObj = aDoc->object(aGroup, i); + if (i < myChildren.size()) { + if (myChildren.at(i)->object() != aObj) { + PartSet_ObjectNode* aNode = new PartSet_ObjectNode(aObj, this); + myChildren.insert(i, aNode); + } + } else { + PartSet_ObjectNode* aNode = new PartSet_ObjectNode(aObj, this); + myChildren.append(aNode); + } + } +} + +std::string PartSet_FolderNode::groupName() const +{ + switch (myType) { + case ParametersFolder: + return ModelAPI_ResultParameter::group(); + case ConstructionFolder: + return ModelAPI_ResultConstruction::group(); + case PartsFolder: + return ModelAPI_ResultPart::group(); + case ResultsFolder: + return ModelAPI_ResultBody::group(); + case FieldsFolder: + return ModelAPI_ResultField::group(); + case GroupsFolder: + return ModelAPI_ResultGroup::group(); + } + return ""; +} + +QTreeNodesList PartSet_FolderNode::objectCreated(const QObjectPtrList& theObjects) +{ + QTreeNodesList aResult; + std::string aName = groupName(); + DocumentPtr aDoc = document(); + int aIdx = -1; + foreach(ObjectPtr aObj, theObjects) { + if ((aObj->document() == aDoc) && (aObj->groupName() == aName)) { + aIdx = aDoc->index(aObj); + if (aIdx != -1) { + bool aHasObject = (aIdx < myChildren.size()) && (myChildren.at(aIdx)->object() == aObj); + if (!aHasObject) { + PartSet_ObjectNode* aNode = new PartSet_ObjectNode(aObj, this); + aResult.append(aNode); + if (aIdx < myChildren.size()) + myChildren.insert(aIdx, aNode); + else + myChildren.append(aNode); + } + } + } + } + return aResult; +} + +QTreeNodesList PartSet_FolderNode::objectsDeleted(const DocumentPtr& theDoc, + const QString& theGroup) +{ + DocumentPtr aDoc = document(); + QTreeNodesList aResult; + if ((theGroup.toStdString() == groupName()) && (theDoc == aDoc)) { + QTreeNodesList aDelList; + foreach(ModuleBase_ITreeNode* aNode, myChildren) { + if (aDoc->index(aNode->object()) == -1) + aDelList.append(aNode); + } + if (aDelList.size() > 0) { + foreach(ModuleBase_ITreeNode* aNode, aDelList) { + myChildren.removeAll(aNode); + delete aNode; + } + aResult.append(this); + } + } + return aResult; +} + +////////////////////////////////////////////////////////////////////////////////// +QTreeNodesList PartSet_FeatureFolderNode::objectCreated(const QObjectPtrList& theObjects) +{ + QTreeNodesList aResult; + // Process all folders + ModuleBase_ITreeNode* aFoder = 0; + foreach(ModuleBase_ITreeNode* aNode, myChildren) { + aFoder = dynamic_cast(aNode); + if (!aFoder) + aFoder = dynamic_cast(aNode); + + if (aFoder) { // aFolder node + QTreeNodesList aList = aNode->objectCreated(theObjects); + if (aList.size() > 0) + aResult.append(aList); + } + } + // Process the root sub-objects + DocumentPtr aDoc = document(); + int aIdx = -1; + int aNb = numberOfFolders(); + foreach(ObjectPtr aObj, theObjects) { + if (aDoc == aObj->document()) { + if (aObj->groupName() == ModelAPI_Feature::group()) { + ModuleBase_ITreeNode* aNode = createNode(aObj); + aIdx = aDoc->index(aObj) + aNb; + bool aHasObject = (aIdx < myChildren.size()) && (myChildren.at(aIdx)->object() == aObj); + if (!aHasObject) { + if (aIdx < myChildren.size()) + myChildren.insert(aIdx, aNode); + else + myChildren.append(aNode); + aResult.append(aNode); + } + } + } + } + return aResult; +} + +QTreeNodesList PartSet_FeatureFolderNode::objectsDeleted(const DocumentPtr& theDoc, + const QString& theGroup) { + QTreeNodesList aResult; + foreach(ModuleBase_ITreeNode* aNode, myChildren) { + if (aNode->childrenCount() > 0) { // aFolder node + QTreeNodesList aList = aNode->objectsDeleted(theDoc, theGroup); + if (aList.size() > 0) + aResult.append(aList); + } + } + DocumentPtr aDoc = document(); + if ((theDoc == aDoc) && (theGroup.toStdString() == ModelAPI_Feature::group())) { + QTreeNodesList aDelList; + foreach(ModuleBase_ITreeNode* aNode, myChildren) { + if (aNode->object().get()) { + if (aDoc->index(aNode->object()) == -1) + aDelList.append(aNode); + } + } + if (aDelList.size() > 0) { + foreach(ModuleBase_ITreeNode* aNode, aDelList) { + myChildren.removeAll(aNode); + delete aNode; + } + aResult.append(this); + } + } + return aResult; +} -} \ No newline at end of file +ModuleBase_ITreeNode* PartSet_FeatureFolderNode::findParent(const DocumentPtr& theDoc, + QString theGroup) +{ + ModuleBase_ITreeNode* aResult = 0; + foreach(ModuleBase_ITreeNode* aNode, myChildren) { + aResult = aNode->findParent(theDoc, theGroup); + if (aResult) { + return aResult; + } + } + if ((theDoc == document()) && (theGroup.toStdString() == ModelAPI_Feature::group())) + return this; + return 0; +} + + +////////////////////////////////////////////////////////////////////////////////// +PartSet_RootNode::PartSet_RootNode() : PartSet_FeatureFolderNode(0), myWorkshop(0) +{ + SessionPtr aSession = ModelAPI_Session::get(); + DocumentPtr aDoc = aSession->moduleDocument(); + + myParamsFolder = new PartSet_FolderNode(this, PartSet_FolderNode::ParametersFolder); + myConstrFolder = new PartSet_FolderNode(this, PartSet_FolderNode::ConstructionFolder); + myPartsFolder = new PartSet_FolderNode(this, PartSet_FolderNode::PartsFolder); + + myChildren.append(myParamsFolder); + myChildren.append(myConstrFolder); + myChildren.append(myPartsFolder); + + update(); +} + +PartSet_RootNode::~PartSet_RootNode() +{ + delete myParamsFolder; + delete myConstrFolder; + delete myPartsFolder; +} + + +void PartSet_RootNode::update() +{ + myParamsFolder->update(); + myConstrFolder->update(); + myPartsFolder->update(); + + // Update features content + DocumentPtr aDoc = document(); + + // Remove extra sub-nodes + QTreeNodesList aDelList; + foreach(ModuleBase_ITreeNode* aNode, myChildren) { + if (aNode->object().get()) { + if (aDoc->index(aNode->object()) == -1) + aDelList.append(aNode); + } + } + foreach(ModuleBase_ITreeNode* aNode, aDelList) { + myChildren.removeAll(aNode); + delete aNode; + } + + // Add new nodes + std::string aGroup = ModelAPI_Feature::group(); + int aSize = aDoc->size(aGroup); + int aId; + FeaturePtr aFeature; + int aNb = numberOfFolders(); + for (int i = 0; i < aSize; i++) { + ObjectPtr aObj = aDoc->object(aGroup, i); + aId = i + aNb; // Take into account existing folders + if (aId < myChildren.size()) { + if (myChildren.at(aId)->object() != aObj) { + aFeature = std::dynamic_pointer_cast(aObj); + ModuleBase_ITreeNode* aNode; + if (aFeature->getKind() == PartSetPlugin_Part::ID()) + aNode = new PartSet_PartRootNode(aObj, this); + else + aNode = new PartSet_ObjectNode(aObj, this); + myChildren.insert(aId, aNode); + } + } else { + aFeature = std::dynamic_pointer_cast(aObj); + ModuleBase_ITreeNode* aNode; + if (aFeature->getKind() == PartSetPlugin_Part::ID()) + aNode = new PartSet_PartRootNode(aObj, this); + else + aNode = new PartSet_ObjectNode(aObj, this); + myChildren.append(aNode); + } + } + // Update sub-folders + ModuleBase_ITreeNode* aSubFolder = 0; + foreach(ModuleBase_ITreeNode* aNode, myChildren) { + aSubFolder = dynamic_cast(aNode); + if (aSubFolder) + aSubFolder->update(); + } +} + +DocumentPtr PartSet_RootNode::document() const +{ + return ModelAPI_Session::get()->moduleDocument(); +} + +ModuleBase_ITreeNode* PartSet_RootNode::createNode(const ObjectPtr& theObj) +{ + FeaturePtr aFeature = std::dynamic_pointer_cast(theObj); + if (aFeature->getKind() == PartSetPlugin_Part::ID()) + return new PartSet_PartRootNode(theObj, this); + else + return new PartSet_ObjectNode(theObj, this); +} + +////////////////////////////////////////////////////////////////////////////////// +PartSet_PartRootNode::PartSet_PartRootNode(const ObjectPtr& theObj, ModuleBase_ITreeNode* theParent) + : PartSet_FeatureFolderNode(theParent), myObject(theObj) +{ + myParamsFolder = new PartSet_FolderNode(this, PartSet_FolderNode::ParametersFolder); + myConstrFolder = new PartSet_FolderNode(this, PartSet_FolderNode::ConstructionFolder); + myResultsFolder = new PartSet_FolderNode(this, PartSet_FolderNode::ResultsFolder); + myFieldsFolder = new PartSet_FolderNode(this, PartSet_FolderNode::FieldsFolder); + myGroupsFolder = new PartSet_FolderNode(this, PartSet_FolderNode::GroupsFolder); + + myChildren.append(myParamsFolder); + myChildren.append(myConstrFolder); + myChildren.append(myResultsFolder); + + update(); +} + +PartSet_PartRootNode::~PartSet_PartRootNode() +{ + delete myParamsFolder; + delete myConstrFolder; + delete myResultsFolder; + delete myFieldsFolder; + delete myGroupsFolder; +} + + +void PartSet_PartRootNode::update() +{ + DocumentPtr aDoc = document(); + if (!aDoc.get()) + return; + + myParamsFolder->update(); + myConstrFolder->update(); + myResultsFolder->update(); + myFieldsFolder->update(); + myGroupsFolder->update(); + + bool aHasFields = myFieldsFolder->childrenCount() > 0; + bool aHasGroups = myGroupsFolder->childrenCount() > 0; + if (aHasFields && (!myChildren.contains(myFieldsFolder))) { + myChildren.insert(3, myFieldsFolder); + } + if (aHasGroups && (!myChildren.contains(myGroupsFolder))) { + myChildren.insert(aHasFields ? 4 : 3, myGroupsFolder); + } + + // Update features content + int aRows = numberOfFolders(); + + // Remove extra sub-nodes + QTreeNodesList aDelList; + int aIndex = -1; + int aId = -1; + foreach(ModuleBase_ITreeNode* aNode, myChildren) { + aId++; + if (aNode->object().get()) { + aIndex = aDoc->index(aNode->object()); + if ((aIndex == -1) || (aId != (aIndex + aRows))) + aDelList.append(aNode); + } + } + foreach(ModuleBase_ITreeNode* aNode, aDelList) { + myChildren.removeAll(aNode); + delete aNode; + } + + std::string aGroup = ModelAPI_Feature::group(); + int aSize = aDoc->size(aGroup); + FeaturePtr aFeature; + for (int i = 0; i < aSize; i++) { + ObjectPtr aObj = aDoc->object(aGroup, i); + aId = i + aRows; // Take into account existing folders + if (aId < myChildren.size()) { + if (myChildren.at(aId)->object() != aObj) { + ModuleBase_ITreeNode* aNode = new PartSet_ObjectNode(aObj, this); + myChildren.insert(aId, aNode); + } + } else { + ModuleBase_ITreeNode* aNode = new PartSet_ObjectNode(aObj, this); + myChildren.append(aNode); + } + } +} + +DocumentPtr PartSet_PartRootNode::document() const +{ + ResultPartPtr aPartRes = getPartResult(myObject); + if (aPartRes.get()) + return aPartRes->partDoc(); + return DocumentPtr(); +} + +QVariant PartSet_PartRootNode::data(int theColumn, int theRole) const +{ + switch (theColumn) { + case 1: + switch (theRole) { + case Qt::DisplayRole: + return QString(myObject->data()->name().c_str()); + case Qt::DecorationRole: + return ModuleBase_IconFactory::get()->getIcon(myObject); + } + case 2: + if (theRole == Qt::DecorationRole) + if (isCurrentFeature(myObject)) + return QIcon(":pictures/arrow.png"); + } + return PartSet_TreeNode::data(theColumn, theRole); +} + +Qt::ItemFlags PartSet_PartRootNode::flags(int theColumn) const +{ + SessionPtr aSession = ModelAPI_Session::get(); + DocumentPtr aActiveDoc = aSession->activeDocument(); + if ((aActiveDoc == document()) || (myObject->document() == aActiveDoc)) + return aEditingFlag; + return aDefaultFlag; +} + +ModuleBase_ITreeNode* PartSet_PartRootNode::createNode(const ObjectPtr& theObj) +{ + return new PartSet_ObjectNode(theObj, this); +} + +int PartSet_PartRootNode::numberOfFolders() const +{ + int aNb = 3; + if (myFieldsFolder->childrenCount() > 0) + aNb++; + if (myGroupsFolder->childrenCount() > 0) + aNb++; + return aNb; +} + +QTreeNodesList PartSet_PartRootNode::objectCreated(const QObjectPtrList& theObjects) +{ + QTreeNodesList aResult = PartSet_FeatureFolderNode::objectCreated(theObjects); + if (!myFieldsFolder->childrenCount()) { + QTreeNodesList aList = myFieldsFolder->objectCreated(theObjects); + if (aList.size()) { + myChildren.insert(3, myFieldsFolder); + aResult.append(myFieldsFolder); + aResult.append(aList); + } + } + if (!myGroupsFolder->childrenCount()) { + QTreeNodesList aList = myGroupsFolder->objectCreated(theObjects); + if (aList.size()) { + myChildren.insert(myFieldsFolder->childrenCount()? 4 : 3, myGroupsFolder); + aResult.append(myGroupsFolder); + aResult.append(aList); + } + } + return aResult; +} + +QTreeNodesList PartSet_PartRootNode::objectsDeleted(const DocumentPtr& theDoc, + const QString& theGroup) +{ + QTreeNodesList aResult; + if (myFieldsFolder->childrenCount()) { + QTreeNodesList aList = myFieldsFolder->objectsDeleted(theDoc, theGroup); + if (aList.size()) { + aResult.append(aList); + if (!myFieldsFolder->childrenCount()) + myChildren.removeAll(myFieldsFolder); + } + } + if (myGroupsFolder->childrenCount()) { + QTreeNodesList aList = myGroupsFolder->objectsDeleted(theDoc, theGroup); + if (aList.size()) { + aResult.append(aList); + if (!myGroupsFolder->childrenCount()) + myChildren.removeAll(myGroupsFolder); + } + } + aResult.append(PartSet_FeatureFolderNode::objectsDeleted(theDoc, theGroup)); + return aResult; +} diff --git a/src/PartSet/PartSet_TreeNodes.h b/src/PartSet/PartSet_TreeNodes.h index 6c165b198..f3a596ecd 100644 --- a/src/PartSet/PartSet_TreeNodes.h +++ b/src/PartSet/PartSet_TreeNodes.h @@ -25,12 +25,230 @@ #include -class PartSet_RootNode : public ModuleBase_ITreeNode + +/** +* \ingroup Modules +* Implementation of base node for the module data tree +*/ +class PartSet_TreeNode : public ModuleBase_ITreeNode +{ +public: + PartSet_TreeNode(ModuleBase_ITreeNode* theParent = 0) : ModuleBase_ITreeNode(theParent) {} + + /// Returns the node representation according to theRole. + virtual QVariant data(int theColumn, int theRole) const; +}; + +/** +* \ingroup Modules +* Implementation of a node for object repesentation +*/ +class PartSet_ObjectNode : public PartSet_TreeNode +{ +public: + enum VisibilityState { + NoneState, + Visible, + SemiVisible, + Hidden + }; + + PartSet_ObjectNode(const ObjectPtr& theObj, ModuleBase_ITreeNode* theParent = 0) + : PartSet_TreeNode(theParent), myObject(theObj) {} + + /// Returns the node representation according to theRole. + virtual QVariant data(int theColumn, int theRole) const; + + /// Returns properties flag of the item + virtual Qt::ItemFlags flags(int theColumn) const; + + /// Returns object referenced by the node (can be null) + virtual ObjectPtr object() const { return myObject; } + + /// Updates sub-nodes of the node + virtual void update() {} + + VisibilityState getVisibilityState() const; + +private: + ObjectPtr myObject; +}; + +/** +* \ingroup Modules +* Implementation of aFolder node in data tree +*/ +class PartSet_FolderNode : public PartSet_TreeNode +{ +public: + enum FolderType { + ParametersFolder, + ConstructionFolder, + PartsFolder, + ResultsFolder, + FieldsFolder, + GroupsFolder + }; + + PartSet_FolderNode(ModuleBase_ITreeNode* theParent, FolderType theType); + + virtual ~PartSet_FolderNode(); + + /// Returns the node representation according to theRole. + virtual QVariant data(int theColumn, int theRole) const; + + /// Returns properties flag of the item + virtual Qt::ItemFlags flags(int theColumn) const; + + /// Updates sub-nodes of the node + virtual void update(); + + /// Process creation of objects. + /// \param theObjects a list of created objects + /// \return a list of nodes which corresponds to the created objects + virtual QTreeNodesList objectCreated(const QObjectPtrList& theObjects); + + /// Process deletion of objects. + /// \param theDoc a document where objects were deleted + /// \param theGroup a name of group where objects were deleted + virtual QTreeNodesList objectsDeleted(const DocumentPtr& theDoc, const QString& theGroup); + + QString name() const; + + /// Returns a node which belongs to the given document and contains objects of the given group + /// \param theDoc a document + /// \param theGroup a name of objects group + /// \return a parent node if it is found + virtual ModuleBase_ITreeNode* findParent(const DocumentPtr& theDoc, QString theGroup) + { + if ((theDoc == document()) && (theGroup.toStdString() == groupName())) + return this; + return 0; + } + +private: + std::string groupName() const; + + FolderType myType; +}; + +///////////////////////////////////////////////////////////////////// +/** +* \ingroup Modules +* A base class for root folders +*/ +class PartSet_FeatureFolderNode : public PartSet_TreeNode +{ +public: + PartSet_FeatureFolderNode(ModuleBase_ITreeNode* theParent = 0) : PartSet_TreeNode(theParent) {} + + /// Process creation of objects. + /// \param theObjects a list of created objects + /// \return a list of nodes which corresponds to the created objects + virtual QTreeNodesList objectCreated(const QObjectPtrList& theObjects); + + /// Process deletion of objects. + /// \param theDoc a document where objects were deleted + /// \param theGroup a name of group where objects were deleted + virtual QTreeNodesList objectsDeleted(const DocumentPtr& theDoc, const QString& theGroup); + + /// Returns a node which belongs to the given document and contains objects of the given group + /// \param theDoc a document + /// \param theGroup a name of objects group + /// \return a parent node if it is found + virtual ModuleBase_ITreeNode* findParent(const DocumentPtr& theDoc, QString theGroup); + +protected: + virtual ModuleBase_ITreeNode* createNode(const ObjectPtr& theObj) = 0; + + virtual int numberOfFolders() const { return 0; } +}; + + +///////////////////////////////////////////////////////////////////// +/** +* \ingroup Modules +* Implementation of Root node in data tree +*/ +class PartSet_RootNode : public PartSet_FeatureFolderNode { public: PartSet_RootNode(); + virtual ~PartSet_RootNode(); + + /// Updates sub-nodes of the node + virtual void update(); + + virtual ModuleBase_IWorkshop* workshop() const { return myWorkshop; } + + /// Returns document object of the sub-tree. + virtual DocumentPtr document() const; + + void setWorkshop(ModuleBase_IWorkshop* theWork) { myWorkshop = theWork; } + +protected: + virtual ModuleBase_ITreeNode* createNode(const ObjectPtr& theObj); + + virtual int numberOfFolders() const { return 3; } +private: + PartSet_FolderNode* myParamsFolder; + PartSet_FolderNode* myConstrFolder; + PartSet_FolderNode* myPartsFolder; + + ModuleBase_IWorkshop* myWorkshop; }; +///////////////////////////////////////////////////////////////////// +/** +* \ingroup Modules +* Implementation of Root node of a Part document in data tree +*/ +class PartSet_PartRootNode : public PartSet_FeatureFolderNode +{ +public: + PartSet_PartRootNode(const ObjectPtr& theObj, ModuleBase_ITreeNode* theParent); + + virtual ~PartSet_PartRootNode(); + + /// Returns object referenced by the node (can be null) + virtual ObjectPtr object() const { return myObject; } + + /// Returns document object of the sub-tree. + virtual DocumentPtr document() const; + + /// Updates sub-nodes of the node + virtual void update(); + + /// Returns the node representation according to theRole. + virtual QVariant data(int theColumn, int theRole) const; + + /// Returns properties flag of the item + virtual Qt::ItemFlags flags(int theColumn) const; + + /// Process creation of objects. + /// \param theObjects a list of created objects + /// \return a list of nodes which corresponds to the created objects + virtual QTreeNodesList objectCreated(const QObjectPtrList& theObjects); + + /// Process deletion of objects. + /// \param theDoc a document where objects were deleted + /// \param theGroup a name of group where objects were deleted + virtual QTreeNodesList objectsDeleted(const DocumentPtr& theDoc, const QString& theGroup); + +protected: + virtual ModuleBase_ITreeNode* createNode(const ObjectPtr& theObj); + + virtual int numberOfFolders() const; + +private: + PartSet_FolderNode* myParamsFolder; + PartSet_FolderNode* myConstrFolder; + PartSet_FolderNode* myResultsFolder; + PartSet_FolderNode* myFieldsFolder; + PartSet_FolderNode* myGroupsFolder; + + ObjectPtr myObject; +}; #endif \ No newline at end of file diff --git a/src/XGUI/XGUI_DataModel.cpp b/src/XGUI/XGUI_DataModel.cpp index 051402c90..d8fd37391 100644 --- a/src/XGUI/XGUI_DataModel.cpp +++ b/src/XGUI/XGUI_DataModel.cpp @@ -19,68 +19,71 @@ // #include "XGUI_DataModel.h" -#include "XGUI_Workshop.h" +//#include "XGUI_Workshop.h" #include "XGUI_ObjectsBrowser.h" -#include "XGUI_Displayer.h" +//#include "XGUI_Displayer.h" #include +#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include +//#include #include -#include +//#include #include -#include -#include +//#include +//#include -#define ACTIVE_COLOR QColor(Qt::black) +#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 -#define SELECTABLE_COLOR QColor(110, 110, 110) -#define DISABLED_COLOR QColor(200, 200, 200) +//#define SELECTABLE_COLOR QColor(110, 110, 110) +//#define DISABLED_COLOR QColor(200, 200, 200) -ResultPartPtr getPartResult(ModelAPI_Object* theObj) -{ - 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; - } - } - return ResultPartPtr(); -} - +//ResultPartPtr getPartResult(ModelAPI_Object* theObj) +//{ +// 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; +// } +// } +// return ResultPartPtr(); +//} +// /// Returns pointer on document if the given object is document object -ModelAPI_Document* getSubDocument(void* theObj) -{ - ModelAPI_Document* aDoc = 0; - try { - aDoc = dynamic_cast((ModelAPI_Entity*)theObj); - } catch(...) {} - return aDoc; -} +//ModelAPI_Document* getSubDocument(void* theObj) +//{ +// ModelAPI_Document* aDoc = 0; +// try { +// aDoc = dynamic_cast((ModelAPI_Entity*)theObj); +// } catch(...) {} +// return aDoc; +//} @@ -108,258 +111,309 @@ 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::set aObjects = aUpdMsg->objects(); - - 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()) - 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) > 0)) { - // Appears first object in folder which can not be shown empty - if (!hasShownFolder(aRootDoc, aNotEmptyFolder)) { - insertRow(myXMLReader->rootFolderId(aObjType)); - addShownFolder(aRootDoc, aNotEmptyFolder); - } - } - } - // Insert new object - int aRow = aRootDoc->size(aObjType) - 1; - if (aRow != -1) { - if ((aObjType == aRootType) || (aObjType == ModelAPI_Folder::group())) { - 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(), 0); - if (aDocRoot.isValid()) { - // Check that new folders could appear - QStringList aNotEmptyFolders = listOfShowNotEmptyFolders(false); - foreach (QString aNotEmptyFolder, aNotEmptyFolders) { - if ((aNotEmptyFolder.toStdString() == aObjType) && (aDoc->size(aObjType) > 0)) { - // Appears first object in folder which can not be shown empty - if (!hasShownFolder(aDoc, aNotEmptyFolder)) { - insertRow(myXMLReader->subFolderId(aObjType), aDocRoot); - addShownFolder(aDoc, aNotEmptyFolder); - } - } - } - int aRow = aDoc->index(aObject, true); - if (aRow != -1) { - int aNbSubFolders = foldersCount(aDoc.get()); - if ((aObjType == aSubType) || (aObjType == ModelAPI_Folder::group())) { - // 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(); - break; - } - } - } - // 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); - } - - 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, true); - if (aGroup == aRootType) { - // Process root folder - // remove optimization due to the issue #2456 - //removeRow(aRow + aNbFolders); - //rebuildBranch(aNbFolders, aRow); - rebuildDataTree(); - } else if (aGroup == ModelAPI_Folder::group()) { - rebuildDataTree(); - } 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, true) == 0)) { - // Appears first object in folder which can not be shown empty - removeRow(myXMLReader->rootFolderId(aGroup)); - removeShownFolder(aRootDoc, aNotEmptyFolder); - //rebuildBranch(0, aNbFolders + aDoc->size(myXMLReader->rootType())); - break; - } - } - } else { - // Remove row for sub-document - QModelIndex aDocRoot = findDocumentRootIndex(aDoc.get(), 0); - if (aDocRoot.isValid()) { - int aRow = aDoc->size(aGroup, true); - int aNbSubFolders = foldersCount(aDoc.get()); - if (aGroup == aSubType) { - // List of objects under document root - removeRow(aRow + aNbSubFolders, aDocRoot); - rebuildBranch(aNbSubFolders, aRow, aDocRoot); - } if (aGroup == ModelAPI_Folder::group()) { - rebuildDataTree(); - } 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, true); - 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); - removeShownFolder(aDoc, aNotEmptyFolder); - //rebuildBranch(0, aNbSubFolders + aDoc->size(myXMLReader->subType()), aDocRoot); - break; - } - } - } else { - rebuildDataTree(); - break; - } - } - } - } 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; - 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, 0); - removeRows(0, aResult->stepsSize(), aIndex); - } else { - if (aObject->groupName() == ModelAPI_Folder::group()) { - rebuildDataTree(); - } else { - QModelIndex aIndex = objectIndex(aObject, 0); - if (aIndex.isValid()) { - emit dataChanged(aIndex, aIndex); - } - } - } - } else { - rebuildDataTree(); - break; - } + for (aIt = aObjects.cbegin(); aIt != aObjects.cend(); aIt++) + aCreated.append(*aIt); + QTreeNodesList aNodes = myRoot->objectCreated(aCreated); + ModuleBase_ITreeNode* aParent; + int aRow = 0; + QModelIndex aParentIndex; + foreach(ModuleBase_ITreeNode* aNode, aNodes) { + aParent = aNode->parent(); + aRow = aParent->nodeRow(aNode); + aParentIndex = getParentIndex(aNode, 0); + insertRows(aRow, 1, aParentIndex); } - } else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_ORDER_UPDATED)) { + } + 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(); + std::set::const_iterator aIt; + for (aIt = aMsgGroups.cbegin(); aIt != aMsgGroups.cend(); aIt++) + QTreeNodesList aList = myRoot->objectsDeleted(aDoc, (*aIt).c_str()); + rebuildDataTree(); + } + 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(); - - 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(), 0); - aStartId = foldersCount(aDoc.get()); - } else - // update folder in sub-document - aParent = createIndex(folderId(aGroup, aDoc.get()), 0, aDoc.get()); + ModuleBase_ITreeNode* aNode = myRoot->findParent(aDoc, aGroup.c_str()); + if (aNode) { + aNode->update(); + int aRows = aNode->childrenCount(); + if (aRows) { + QModelIndex aParent = getIndex(aNode, 0); + QModelIndex aFirstIdx = aParent.child(0, 0); + QModelIndex aLastIdx = aParent.child(aRows - 1, 2); + dataChanged(aFirstIdx, aLastIdx); + } } - int aChildNb = rowCount(aParent); - rebuildBranch(aStartId, aChildNb - aStartId, aParent); - } else { - rebuildDataTree(); } - } else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_DOCUMENT_CHANGED)) { + } + 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(), 0); - if (aDocRoot.isValid()) - emit dataChanged(aDocRoot, aDocRoot); - else - // We have got a new document - rebuildDataTree(); - } } + //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::set aObjects = aUpdMsg->objects(); + + // 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()) + // 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) > 0)) { + // // Appears first object in folder which can not be shown empty + // if (!hasShownFolder(aRootDoc, aNotEmptyFolder)) { + // insertRow(myXMLReader->rootFolderId(aObjType)); + // addShownFolder(aRootDoc, aNotEmptyFolder); + // } + // } + // } + // // Insert new object + // int aRow = aRootDoc->size(aObjType) - 1; + // if (aRow != -1) { + // if ((aObjType == aRootType) || (aObjType == ModelAPI_Folder::group())) { + // 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(), 0); + // if (aDocRoot.isValid()) { + // // Check that new folders could appear + // QStringList aNotEmptyFolders = listOfShowNotEmptyFolders(false); + // foreach (QString aNotEmptyFolder, aNotEmptyFolders) { + // if ((aNotEmptyFolder.toStdString() == aObjType) && (aDoc->size(aObjType) > 0)) { + // // Appears first object in folder which can not be shown empty + // if (!hasShownFolder(aDoc, aNotEmptyFolder)) { + // insertRow(myXMLReader->subFolderId(aObjType), aDocRoot); + // addShownFolder(aDoc, aNotEmptyFolder); + // } + // } + // } + // int aRow = aDoc->index(aObject, true); + // if (aRow != -1) { + // int aNbSubFolders = foldersCount(aDoc.get()); + // if ((aObjType == aSubType) || (aObjType == ModelAPI_Folder::group())) { + // // 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(); + // break; + // } + // } + // } + // // 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); + // } + + // 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, true); + // if (aGroup == aRootType) { + // // Process root folder + // // remove optimization due to the issue #2456 + // //removeRow(aRow + aNbFolders); + // //rebuildBranch(aNbFolders, aRow); + // rebuildDataTree(); + // } else if (aGroup == ModelAPI_Folder::group()) { + // rebuildDataTree(); + // } 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, true) == 0)) { + // // Appears first object in folder which can not be shown empty + // removeRow(myXMLReader->rootFolderId(aGroup)); + // removeShownFolder(aRootDoc, aNotEmptyFolder); + // //rebuildBranch(0, aNbFolders + aDoc->size(myXMLReader->rootType())); + // break; + // } + // } + // } else { + // // Remove row for sub-document + // QModelIndex aDocRoot = findDocumentRootIndex(aDoc.get(), 0); + // if (aDocRoot.isValid()) { + // int aRow = aDoc->size(aGroup, true); + // int aNbSubFolders = foldersCount(aDoc.get()); + // if (aGroup == aSubType) { + // // List of objects under document root + // removeRow(aRow + aNbSubFolders, aDocRoot); + // rebuildBranch(aNbSubFolders, aRow, aDocRoot); + // } if (aGroup == ModelAPI_Folder::group()) { + // rebuildDataTree(); + // } 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, true); + // 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); + // removeShownFolder(aDoc, aNotEmptyFolder); + // //rebuildBranch(0, aNbSubFolders + aDoc->size(myXMLReader->subType()), aDocRoot); + // break; + // } + // } + // } else { + // rebuildDataTree(); + // break; + // } + // } + // } + //} 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; + // 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, 0); + // removeRows(0, aResult->stepsSize(), aIndex); + // } else { + // if (aObject->groupName() == ModelAPI_Folder::group()) { + // rebuildDataTree(); + // } else { + // QModelIndex aIndex = objectIndex(aObject, 0); + // if (aIndex.isValid()) { + // emit dataChanged(aIndex, aIndex); + // } + // } + // } + // } else { + // rebuildDataTree(); + // break; + // } + // } + //} else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_ORDER_UPDATED)) { + // std::shared_ptr aUpdMsg = + // std::dynamic_pointer_cast(theMessage); + // if (aUpdMsg->reordered().get()) { + // DocumentPtr aDoc = aUpdMsg->reordered()->document(); + // std::string aGroup = aUpdMsg->reordered()->group(); + + // 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(), 0); + // aStartId = foldersCount(aDoc.get()); + // } else + // // update folder in sub-document + // aParent = createIndex(folderId(aGroup, aDoc.get()), 0, aDoc.get()); + // } + // 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(), 0); + // if (aDocRoot.isValid()) + // emit dataChanged(aDocRoot, aDocRoot); + // else + // // We have got a new document + // rebuildDataTree(); + // } + //} } //****************************************************** @@ -380,194 +434,213 @@ void XGUI_DataModel::rebuildDataTree() //****************************************************** ObjectPtr XGUI_DataModel::object(const QModelIndex& theIndex) const { - if (theIndex.internalId() == 0) // this is a folder - return ObjectPtr(); - ModelAPI_Object* aObj = 0; - try { - aObj = dynamic_cast((ModelAPI_Entity*)theIndex.internalPointer()); - } catch(...) {} - - 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(); + + //if (theIndex.internalId() == 0) // this is a folder + // return ObjectPtr(); + //ModelAPI_Object* aObj = 0; + //try { + // aObj = dynamic_cast((ModelAPI_Entity*)theIndex.internalPointer()); + //} catch(...) {} + + //if (!aObj) + // return ObjectPtr(); + //if (getSubDocument(aObj)) // the selected index is a folder of sub-document + // return ObjectPtr(); + + //return aObj->data()->owner(); } //****************************************************** QModelIndex XGUI_DataModel::objectIndex(const ObjectPtr theObject, int theColumn) const { - std::string aType = theObject->groupName(); - DocumentPtr aDoc = theObject->document(); - int aRow = aDoc->index(theObject, true); - 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; - } - } - } - int aFRow = -1; - FolderPtr aFolder = aDoc->findContainingFolder(aFeature, aFRow); - if (aFolder.get()) - aRow = aFRow; - } else { - ResultPtr aResult = std::dynamic_pointer_cast(theObject); - if (aResult.get()) { - ResultCompSolidPtr aCompRes = ModelAPI_Tools::compSolidOwner(aResult); - if (aCompRes.get()) { - aRow = ModelAPI_Tools::compSolidIndex(aResult); - } - } - } - if (aRow == -1) - return QModelIndex(); - else - return createIndex(aRow, theColumn, theObject.get()); + ModuleBase_ITreeNode* aNode = myRoot->subNode(theObject); + if (aNode) { + ModuleBase_ITreeNode* aParent = aNode->parent(); + assert(aParent); + return getIndex(aNode, theColumn); } - SessionPtr aSession = ModelAPI_Session::get(); - DocumentPtr aRootDoc = aSession->moduleDocument(); - if (aDoc == aRootDoc && - ((myXMLReader->rootType() == aType) || (aType == ModelAPI_Folder::group()))) { - // The object from root document - aRow += foldersCount(); - } else if ((myXMLReader->subType() == aType) || (aType == ModelAPI_Folder::group())) { - // The object from sub document - aRow += foldersCount(aDoc.get()); - } - return createIndex(aRow, theColumn, theObject.get()); + return QModelIndex(); + //std::string aType = theObject->groupName(); + //DocumentPtr aDoc = theObject->document(); + //int aRow = aDoc->index(theObject, true); + //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; + // } + // } + // } + // int aFRow = -1; + // FolderPtr aFolder = aDoc->findContainingFolder(aFeature, aFRow); + // if (aFolder.get()) + // aRow = aFRow; + // } else { + // ResultPtr aResult = std::dynamic_pointer_cast(theObject); + // if (aResult.get()) { + // ResultCompSolidPtr aCompRes = ModelAPI_Tools::compSolidOwner(aResult); + // if (aCompRes.get()) { + // aRow = ModelAPI_Tools::compSolidIndex(aResult); + // } + // } + // } + // if (aRow == -1) + // return QModelIndex(); + // else + // return createIndex(aRow, theColumn, theObject.get()); + //} + //SessionPtr aSession = ModelAPI_Session::get(); + //DocumentPtr aRootDoc = aSession->moduleDocument(); + //if (aDoc == aRootDoc && + // ((myXMLReader->rootType() == aType) || (aType == ModelAPI_Folder::group()))) { + // // The object from root document + // aRow += foldersCount(); + //} else if ((myXMLReader->subType() == aType) || (aType == ModelAPI_Folder::group())) { + // // The object from sub document + // aRow += foldersCount(aDoc.get()); + //} + //return createIndex(aRow, theColumn, theObject.get()); } //****************************************************** 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) { - if (theIndex == lastHistoryIndex()) - return QIcon(":pictures/arrow.png"); - else if (theIndex.column() == 0) { - VisibilityState aState = getVisibilityState(theIndex); - switch (aState) { - case NoneState: - return QIcon(); - case Visible: - return QIcon(":pictures/eyeopen.png"); - case SemiVisible: - return QIcon(":pictures/eyemiclosed.png"); - case Hidden: - return QIcon(":pictures/eyeclosed.png"); - } - } - } - - //if (theIndex.column() == 1) - 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 { - ObjectPtr aObj = object(theIndex); - if (aObj) { - switch (theRole) { - case Qt::DisplayRole: - { - if (aObj->groupName() == ModelAPI_ResultParameter::group()) { - ResultParameterPtr aParam = std::dynamic_pointer_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.get()); - if (aPartRes.get()) { - if (aPartRes->partDoc().get() == NULL) - aSuffix = " (Not loaded)"; - } - } - return aObj->data()->name().c_str() + aSuffix; - } - case Qt::DecorationRole: - { - if (aObj->groupName() == ModelAPI_Folder::group()) - return QIcon(":pictures/features_folder.png"); - else - return ModuleBase_IconFactory::get()->getIcon(aObj); - } - } - } 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(); + + //SessionPtr aSession = ModelAPI_Session::get(); + //DocumentPtr aRootDoc = aSession->moduleDocument(); + //int aNbFolders = foldersCount(); + //int theIndexRow = theIndex.row(); + + //if (theRole == Qt::DecorationRole) { + // if (theIndex == lastHistoryIndex()) + // return QIcon(":pictures/arrow.png"); + // else if (theIndex.column() == 0) { + // VisibilityState aState = getVisibilityState(theIndex); + // switch (aState) { + // case NoneState: + // return QIcon(); + // case Visible: + // return QIcon(":pictures/eyeopen.png"); + // case SemiVisible: + // return QIcon(":pictures/eyemiclosed.png"); + // case Hidden: + // return QIcon(":pictures/eyeclosed.png"); + // } + // } + //} + + ////if (theIndex.column() == 1) + //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 { + // ObjectPtr aObj = object(theIndex); + // if (aObj) { + // switch (theRole) { + // case Qt::DisplayRole: + // { + // if (aObj->groupName() == ModelAPI_ResultParameter::group()) { + // ResultParameterPtr aParam = std::dynamic_pointer_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.get()); + // if (aPartRes.get()) { + // if (aPartRes->partDoc().get() == NULL) + // aSuffix = " (Not loaded)"; + // } + // } + // return aObj->data()->name().c_str() + aSuffix; + // } + // case Qt::DecorationRole: + // { + // if (aObj->groupName() == ModelAPI_Folder::group()) + // return QIcon(":pictures/features_folder.png"); + // else + // return ModuleBase_IconFactory::get()->getIcon(aObj); + // } + // } + // } 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; + // } + // } + // } + //} + //return QVariant(); } //****************************************************** @@ -579,74 +652,78 @@ 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, true); - 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, true); - 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(); - ModelAPI_Folder* aFolder = dynamic_cast(aObj); - if (aFolder) - return getNumberOfFolderItems(aFolder); - } - } - } - return 0; + ModuleBase_ITreeNode* aParentNode = (theParent.isValid()) ? + (ModuleBase_ITreeNode*)theParent.internalPointer() : myRoot; + return aParentNode->childrenCount(); + + //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, true); + // 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, true); + // 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(); + // ModelAPI_Folder* aFolder = dynamic_cast(aObj); + // if (aFolder) + // return getNumberOfFolderItems(aFolder); + // } + // } + //} + //return 0; } //****************************************************** @@ -658,189 +735,203 @@ int XGUI_DataModel::columnCount(const QModelIndex& theParent) const //****************************************************** 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, true)) { - ObjectPtr aObj = aRootDoc->object(aType, aObjId, true); - aIndex = objectIndex(aObj, theColumn); - } - } - } 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, true); - aIndex = objectIndex(aObj, theColumn); - } - } 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, theColumn); - } - } - } 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, true); - aIndex = objectIndex(aObj, theColumn); - } - } else { - // Check for composite object - ModelAPI_CompositeFeature* aCompFeature = - dynamic_cast(aParentObj); - if (aCompFeature) { - aIndex = objectIndex(aCompFeature->subFeature(theRow), theColumn); - } else { - ModelAPI_ResultCompSolid* aCompRes = - dynamic_cast(aParentObj); - if (aCompRes) - aIndex = objectIndex(aCompRes->subResult(theRow), theColumn); - else { - ModelAPI_ResultField* aFieldRes = - dynamic_cast(aParentObj); - if (aFieldRes) { - aIndex = createIndex(theRow, theColumn, aFieldRes->step(theRow)); - } else { - ModelAPI_Folder* aFolder = dynamic_cast(aParentObj); - ObjectPtr aObj = getObjectInFolder(aFolder, theRow); - if (aObj.get()) - aIndex = objectIndex(aObj, theColumn); - } - } - } - } - } - } - } - return aIndex; + int aa = theParent.row(); + ModuleBase_ITreeNode* aParentNode = (theParent.isValid()) ? + (ModuleBase_ITreeNode*)theParent.internalPointer() : myRoot; + ModuleBase_ITreeNode* aSubNode = aParentNode->subNode(theRow); + assert(aSubNode); + return createIndex(theRow, theColumn, aSubNode); + + //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, true)) { + // ObjectPtr aObj = aRootDoc->object(aType, aObjId, true); + // aIndex = objectIndex(aObj, theColumn); + // } + // } + //} 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, true); + // aIndex = objectIndex(aObj, theColumn); + // } + // } 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, theColumn); + // } + // } + // } 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, true); + // aIndex = objectIndex(aObj, theColumn); + // } + // } else { + // // Check for composite object + // ModelAPI_CompositeFeature* aCompFeature = + // dynamic_cast(aParentObj); + // if (aCompFeature) { + // aIndex = objectIndex(aCompFeature->subFeature(theRow), theColumn); + // } else { + // ModelAPI_ResultCompSolid* aCompRes = + // dynamic_cast(aParentObj); + // if (aCompRes) + // aIndex = objectIndex(aCompRes->subResult(theRow), theColumn); + // else { + // ModelAPI_ResultField* aFieldRes = + // dynamic_cast(aParentObj); + // if (aFieldRes) { + // aIndex = createIndex(theRow, theColumn, aFieldRes->step(theRow)); + // } else { + // ModelAPI_Folder* aFolder = dynamic_cast(aParentObj); + // ObjectPtr aObj = getObjectInFolder(aFolder, theRow); + // if (aObj.get()) + // aIndex = objectIndex(aObj, theColumn); + // } + // } + // } + // } + // } + // } + //} + //return aIndex; } //****************************************************** -static QModelIndex MYLastDeleted; +//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 be a step of a field - ModelAPI_ResultField::ModelAPI_FieldStep* aStep = 0; - try { - aStep = dynamic_cast - ((ModelAPI_Entity*)theIndex.internalPointer()); - } catch(...) {} - - 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); - } - DocumentPtr aDoc = aFeature->document(); - int aRow; - FolderPtr aFolder = aDoc->findContainingFolder(aFeature, aRow); - if (aFolder.get()) - return objectIndex(aFolder); - } - 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()) || (aType == ModelAPI_Folder::group())) - 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, 1, (void*)Q_NULLPTR); - } - } else { - if ((aType == myXMLReader->subType()) || (aType == ModelAPI_Folder::group())) - 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, 1, aSubDoc.get()); - } - } + if (theIndex.isValid()) { + ModuleBase_ITreeNode* aNode = (ModuleBase_ITreeNode*)theIndex.internalPointer(); + return getParentIndex(aNode, 1); } return QModelIndex(); + + //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 be a step of a field + // ModelAPI_ResultField::ModelAPI_FieldStep* aStep = 0; + // try { + // aStep = dynamic_cast + // ((ModelAPI_Entity*)theIndex.internalPointer()); + // } catch(...) {} + + // 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); + // } + // DocumentPtr aDoc = aFeature->document(); + // int aRow; + // FolderPtr aFolder = aDoc->findContainingFolder(aFeature, aRow); + // if (aFolder.get()) + // return objectIndex(aFolder); + // } + // 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()) || (aType == ModelAPI_Folder::group())) + // 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, 1, (void*)Q_NULLPTR); + // } + // } else { + // if ((aType == myXMLReader->subType()) || (aType == ModelAPI_Folder::group())) + // 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, 1, aSubDoc.get()); + // } + // } + //} } //****************************************************** 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; } //****************************************************** @@ -848,7 +939,6 @@ bool XGUI_DataModel::insertRows(int theRow, int theCount, const QModelIndex& the { beginInsertRows(theParent, theRow, theRow + theCount - 1); endInsertRows(); - return true; } @@ -863,113 +953,119 @@ 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 (aObj) { - // An object - if (aObj->isDisabled()) - return theIndex.column() == 2? Qt::ItemIsSelectable : aNullFlag; - - if (aSession->moduleDocument() != aObj->document()) - if (aActiveDoc != aObj->document()) - return theIndex.column() == 2? Qt::ItemIsSelectable : aNullFlag; - - bool isCompositeSub = false; - // An object which is sub-object of a composite object can not be accessible in column 2 - if (theIndex.column() == 2) { - 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; - - 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; + if (theIndex.isValid()) { + ModuleBase_ITreeNode* aNode = (ModuleBase_ITreeNode*)theIndex.internalPointer(); + return aNode->flags(theIndex.column()); } - return aEditingFlag; + return Qt::ItemFlags(); + + //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 (aObj) { + // // An object + // if (aObj->isDisabled()) + // return theIndex.column() == 2? Qt::ItemIsSelectable : aNullFlag; + + // if (aSession->moduleDocument() != aObj->document()) + // if (aActiveDoc != aObj->document()) + // return theIndex.column() == 2? Qt::ItemIsSelectable : aNullFlag; + + // bool isCompositeSub = false; + // // An object which is sub-object of a composite object can not be accessible in column 2 + // if (theIndex.column() == 2) { + // 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; + + // 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; + //} + //return aEditingFlag; } //****************************************************** -QModelIndex - XGUI_DataModel::findDocumentRootIndex(const ModelAPI_Document* theDoc, int aColumn) const -{ - 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, aColumn, aObj.get()); - } - } - } else { // If document is attached to feature - int aNb = aRootDoc->size(ModelAPI_Feature::group(), true); - ObjectPtr aObj; - ResultPartPtr aPartRes; - for (int i = 0; i < aNb; i++) { - aObj = aRootDoc->object(ModelAPI_Feature::group(), i, true); - 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, aColumn, aObj.get()); - } - } - } - return QModelIndex(); -} +//QModelIndex +// XGUI_DataModel::findDocumentRootIndex(const ModelAPI_Document* theDoc, int aColumn) const +//{ +// 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, aColumn, aObj.get()); +// } +// } +// } else { // If document is attached to feature +// int aNb = aRootDoc->size(ModelAPI_Feature::group(), true); +// ObjectPtr aObj; +// ResultPartPtr aPartRes; +// for (int i = 0; i < aNb; i++) { +// aObj = aRootDoc->object(ModelAPI_Feature::group(), i, true); +// 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, aColumn, aObj.get()); +// } +// } +// } +// return QModelIndex(); +//} //****************************************************** QModelIndex XGUI_DataModel::documentRootIndex(DocumentPtr theDoc, int theColumn) const @@ -978,146 +1074,158 @@ QModelIndex XGUI_DataModel::documentRootIndex(DocumentPtr theDoc, int theColumn) DocumentPtr aRootDoc = aSession->moduleDocument(); if (theDoc == aRootDoc) return QModelIndex(); - else - return findDocumentRootIndex(theDoc.get(), theColumn); -} - -//****************************************************** -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(); + // return findDocumentRootIndex(theDoc.get(), theColumn); } +//****************************************************** +//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++; +// } +// } +// } +// return aNb; +//} + //****************************************************** -QIntList XGUI_DataModel::missedFolderIndexes(ModelAPI_Document* theDoc) const -{ - 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); - } - } - } - return aList; -} +//QIntList XGUI_DataModel::missedFolderIndexes(ModelAPI_Document* theDoc) const +//{ +// 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); +// } +// } +// } +// return aList; +//} //****************************************************** -QStringList XGUI_DataModel::listOfShowNotEmptyFolders(bool fromRoot) 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; -} +//QStringList XGUI_DataModel::listOfShowNotEmptyFolders(bool fromRoot) 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; +//} //****************************************************** -QModelIndex XGUI_DataModel::lastHistoryIndex() 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(), 2, aInd.internalPointer()); - } else { - if (aCurDoc == aSession->moduleDocument()) - return createIndex(foldersCount() - 1, 2, -1); - else - return createIndex(foldersCount(aCurDoc.get()) - 1, 2, aCurDoc.get()); - } -} +//QModelIndex XGUI_DataModel::lastHistoryIndex() 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(), 2, aInd.internalPointer()); + //} else { + // if (aCurDoc == aSession->moduleDocument()) + // return createIndex(foldersCount() - 1, 2, -1); + // else + // return createIndex(foldersCount(aCurDoc.get()) - 1, 2, aCurDoc.get()); + //} +//} //****************************************************** bool XGUI_DataModel::hasHiddenState(const QModelIndex& theIndex) { - return getVisibilityState(theIndex) == Hidden; + return false; + //return getVisibilityState(theIndex) == Hidden; } //****************************************************** -int XGUI_DataModel::folderId(std::string theType, ModelAPI_Document* theDoc) const -{ - SessionPtr aSession = ModelAPI_Session::get(); - ModelAPI_Document* aDoc = theDoc; - if (aDoc == 0) - aDoc = aSession->moduleDocument().get(); - - 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--; - } - } - } - return aRes; -} +//int XGUI_DataModel::folderId(std::string theType, ModelAPI_Document* theDoc) const +//{ +// SessionPtr aSession = ModelAPI_Session::get(); +// ModelAPI_Document* aDoc = theDoc; +// if (aDoc == 0) +// aDoc = aSession->moduleDocument().get(); +// +// 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--; +// } +// } +// } +// return aRes; +//} //****************************************************** -void XGUI_DataModel::rebuildBranch(int theRow, int theCount, const QModelIndex& theParent) -{ - if (theCount > 0) { - removeRows(theRow, theCount, theParent); - insertRows(theRow, theCount, theParent); - } -} +//void XGUI_DataModel::rebuildBranch(int theRow, int theCount, const QModelIndex& theParent) +//{ +// if (theCount > 0) { +// removeRows(theRow, theCount, theParent); +// insertRows(theRow, theCount, theParent); +// } +//} //****************************************************** //bool XGUI_DataModel::blockEventsProcessing(const bool theState) @@ -1128,84 +1236,106 @@ void XGUI_DataModel::rebuildBranch(int theRow, int theCount, const QModelIndex& //} //****************************************************** -XGUI_DataModel::VisibilityState - XGUI_DataModel::getVisibilityState(const QModelIndex& theIndex) const +//XGUI_DataModel::VisibilityState +// XGUI_DataModel::getVisibilityState(const QModelIndex& theIndex) const +//{ +// Qt::ItemFlags aFlags = theIndex.flags(); +// if (aFlags == Qt::ItemFlags()) +// return NoneState; +// +// ObjectPtr aObj = object(theIndex); +// if (aObj.get()) { +// if (aObj->groupName() == ModelAPI_ResultParameter::group()) +// return NoneState; +// ResultPtr aResObj = std::dynamic_pointer_cast(aObj); +// if (aResObj.get()) { +// XGUI_Displayer* aDisplayer = myWorkshop->displayer(); +// ResultCompSolidPtr aCompRes = std::dynamic_pointer_cast(aResObj); +// if (aCompRes.get()) { +// VisibilityState aState = aCompRes->numberOfSubs(true) == 0 ? +// (aDisplayer->isVisible(aCompRes)? Visible : Hidden) : NoneState; +// for (int i = 0; i < aCompRes->numberOfSubs(true); i++) { +// ResultPtr aSubRes = aCompRes->subResult(i, true); +// VisibilityState aS = aDisplayer->isVisible(aSubRes)? Visible : Hidden; +// if (aState == NoneState) +// aState = aS; +// else if (aState != aS) { +// aState = SemiVisible; +// break; +// } +// } +// return aState; +// } else { +// if (aDisplayer->isVisible(aResObj)) +// return Visible; +// else +// return Hidden; +// } +// } +// } +// return NoneState; +//} + + +//int XGUI_DataModel::getNumberOfFolderItems(const ModelAPI_Folder* theFolder) const +//{ +// DocumentPtr aDoc = theFolder->document(); +// +// FeaturePtr aFirstFeatureInFolder; +// AttributeReferencePtr aFirstFeatAttr = +// theFolder->data()->reference(ModelAPI_Folder::FIRST_FEATURE_ID()); +// if (aFirstFeatAttr) +// aFirstFeatureInFolder = ModelAPI_Feature::feature(aFirstFeatAttr->value()); +// if (!aFirstFeatureInFolder.get()) +// return 0; +// +// FeaturePtr aLastFeatureInFolder; +// AttributeReferencePtr aLastFeatAttr = +// theFolder->data()->reference(ModelAPI_Folder::LAST_FEATURE_ID()); +// if (aLastFeatAttr) +// aLastFeatureInFolder = ModelAPI_Feature::feature(aLastFeatAttr->value()); +// if (!aLastFeatureInFolder.get()) +// return 0; +// +// int aFirst = aDoc->index(aFirstFeatureInFolder); +// int aLast = aDoc->index(aLastFeatureInFolder); +// return aLast - aFirst + 1; +//} + +//ObjectPtr XGUI_DataModel::getObjectInFolder(const ModelAPI_Folder* theFolder, int theId) const +//{ +// DocumentPtr aDoc = theFolder->document(); +// +// FeaturePtr aFirstFeatureInFolder; +// AttributeReferencePtr aFirstFeatAttr = +// theFolder->data()->reference(ModelAPI_Folder::FIRST_FEATURE_ID()); +// if (aFirstFeatAttr) +// aFirstFeatureInFolder = ModelAPI_Feature::feature(aFirstFeatAttr->value()); +// if (!aFirstFeatureInFolder.get()) +// return ObjectPtr(); +// +// int aFirst = aDoc->index(aFirstFeatureInFolder); +// return aDoc->object(ModelAPI_Feature::group(), aFirst + theId); +//} + +bool XGUI_DataModel::hasIndex(const QModelIndex& theIndex) const { - Qt::ItemFlags aFlags = theIndex.flags(); - if (aFlags == Qt::ItemFlags()) - return NoneState; - - ObjectPtr aObj = object(theIndex); - if (aObj.get()) { - if (aObj->groupName() == ModelAPI_ResultParameter::group()) - return NoneState; - ResultPtr aResObj = std::dynamic_pointer_cast(aObj); - if (aResObj.get()) { - XGUI_Displayer* aDisplayer = myWorkshop->displayer(); - ResultCompSolidPtr aCompRes = std::dynamic_pointer_cast(aResObj); - if (aCompRes.get()) { - VisibilityState aState = aCompRes->numberOfSubs(true) == 0 ? - (aDisplayer->isVisible(aCompRes)? Visible : Hidden) : NoneState; - for (int i = 0; i < aCompRes->numberOfSubs(true); i++) { - ResultPtr aSubRes = aCompRes->subResult(i, true); - VisibilityState aS = aDisplayer->isVisible(aSubRes)? Visible : Hidden; - if (aState == NoneState) - aState = aS; - else if (aState != aS) { - aState = SemiVisible; - break; - } - } - return aState; - } else { - if (aDisplayer->isVisible(aResObj)) - return Visible; - else - return Hidden; - } - } - } - return NoneState; + ModuleBase_ITreeNode* aNode = (ModuleBase_ITreeNode*)theIndex.internalPointer(); + return myRoot->hasSubNode(aNode); } - -int XGUI_DataModel::getNumberOfFolderItems(const ModelAPI_Folder* theFolder) const +QModelIndex XGUI_DataModel::getParentIndex(ModuleBase_ITreeNode* theNode, int thCol) const { - DocumentPtr aDoc = theFolder->document(); - - FeaturePtr aFirstFeatureInFolder; - AttributeReferencePtr aFirstFeatAttr = - theFolder->data()->reference(ModelAPI_Folder::FIRST_FEATURE_ID()); - if (aFirstFeatAttr) - aFirstFeatureInFolder = ModelAPI_Feature::feature(aFirstFeatAttr->value()); - if (!aFirstFeatureInFolder.get()) - return 0; - - FeaturePtr aLastFeatureInFolder; - AttributeReferencePtr aLastFeatAttr = - theFolder->data()->reference(ModelAPI_Folder::LAST_FEATURE_ID()); - if (aLastFeatAttr) - aLastFeatureInFolder = ModelAPI_Feature::feature(aLastFeatAttr->value()); - if (!aLastFeatureInFolder.get()) - return 0; - - int aFirst = aDoc->index(aFirstFeatureInFolder); - int aLast = aDoc->index(aLastFeatureInFolder); - return aLast - aFirst + 1; + ModuleBase_ITreeNode* aParent = theNode->parent(); + if (aParent == myRoot) { + return QModelIndex(); + } else { + return getIndex(aParent, thCol); + } } -ObjectPtr XGUI_DataModel::getObjectInFolder(const ModelAPI_Folder* theFolder, int theId) const +QModelIndex XGUI_DataModel::getIndex(ModuleBase_ITreeNode* theNode, int thCol) const { - DocumentPtr aDoc = theFolder->document(); - - FeaturePtr aFirstFeatureInFolder; - AttributeReferencePtr aFirstFeatAttr = - theFolder->data()->reference(ModelAPI_Folder::FIRST_FEATURE_ID()); - if (aFirstFeatAttr) - aFirstFeatureInFolder = ModelAPI_Feature::feature(aFirstFeatAttr->value()); - if (!aFirstFeatureInFolder.get()) - return ObjectPtr(); - - int aFirst = aDoc->index(aFirstFeatureInFolder); - return aDoc->object(ModelAPI_Feature::group(), aFirst + theId); + int aRow = theNode->parent()->nodeRow(theNode); + return createIndex(aRow, 0, theNode); } diff --git a/src/XGUI/XGUI_DataModel.h b/src/XGUI/XGUI_DataModel.h index e89546161..477370cc6 100644 --- a/src/XGUI/XGUI_DataModel.h +++ b/src/XGUI/XGUI_DataModel.h @@ -31,6 +31,7 @@ class Config_DataModelReader; class XGUI_Workshop; +class ModuleBase_ITreeNode; /**\class XGUI_DataModel * \ingroup GUI @@ -54,6 +55,11 @@ public: /// Destructor virtual ~XGUI_DataModel(); + + void setRoot(ModuleBase_ITreeNode* theRoot) { myRoot = theRoot; } + + ModuleBase_ITreeNode* root() const { return myRoot; } + /// Event Listener method /// \param theMessage an event message virtual void processEvent(const std::shared_ptr& theMessage); @@ -72,7 +78,6 @@ public: //! Rebuild data tree virtual void rebuildDataTree(); - /// Returns the data stored under the given role for the item referred to by the index. /// \param theIndex a model index /// \param theRole a data role (see Qt::ItemDataRole) @@ -134,10 +139,10 @@ public: QModelIndex documentRootIndex(DocumentPtr theDoc, int theColumn = 1) const; /// Returns last history object index - virtual QModelIndex lastHistoryIndex() const; + //virtual QModelIndex lastHistoryIndex() const; /// Initialises XML data model reader. It must be initialised before DataModel using. - void setXMLReader(Config_DataModelReader* theReader) { myXMLReader = theReader; } + //void setXMLReader(Config_DataModelReader* theReader) { myXMLReader = theReader; } /// Do not processing anymore events of model loop //bool blockEventsProcessing(const bool theState); @@ -147,6 +152,10 @@ public: /// \return boolean value bool hasHiddenState(const QModelIndex& theIndex); + /// Returns true if the given index exists in data tree + /// \param theIndex an index to check + bool hasIndex(const QModelIndex& theIndex) const; + signals: /// Signal about tree had been rebuilt void treeRebuilt(); @@ -158,69 +167,76 @@ private: SemiVisible, Hidden }; + + QModelIndex getParentIndex(ModuleBase_ITreeNode* theNode, int thCol) const; + + QModelIndex getIndex(ModuleBase_ITreeNode* theNode, int thCol) const; + /// Find a root index which contains objects of the given document /// \param theDoc the document object - QModelIndex findDocumentRootIndex(const ModelAPI_Document* theDoc, int aColumn = 1) const; + //QModelIndex findDocumentRootIndex(const ModelAPI_Document* theDoc, int aColumn = 1) const; /// Returns number of folders in document. /// Considered folders which has to be shown only if they are not empty. /// \param theDoc document which has to be checked. If 0 then Root document will be considered - int foldersCount(ModelAPI_Document* theDoc = 0) const; + //int foldersCount(ModelAPI_Document* theDoc = 0) const; /// Retrurns indexes of folders which can not be shown because they are empty /// \param theDoc document which has to be checked. If 0 then Root document will be considered - QIntList missedFolderIndexes(ModelAPI_Document* theDoc = 0) const; + //QIntList missedFolderIndexes(ModelAPI_Document* theDoc = 0) const; /// Returns Id (row) of a folder taking into consideration /// folders which can not be shown non empty /// \param theType Type of the folder /// \param theDoc a document which contains this folder - int folderId(std::string theType, ModelAPI_Document* theDoc = 0) const; + //int folderId(std::string theType, ModelAPI_Document* theDoc = 0) const; /// Removes a row from branch of tree /// \param theStart - start row to update indexes /// \param theSize - number of indexes in the folder /// \param theParent - index of parent folder - void rebuildBranch(int theRow, int theCount, const QModelIndex& theParent = QModelIndex()); + //void rebuildBranch(int theRow, int theCount, const QModelIndex& theParent = QModelIndex()); /// Returns list of folders types which can not be shown empty /// \param fromRoot - root document flag - QStringList listOfShowNotEmptyFolders(bool fromRoot = true) const; - - int getNumberOfFolderItems(const ModelAPI_Folder* theFolder) const; - ObjectPtr getObjectInFolder(const ModelAPI_Folder* theFolder, int theId) const; - - VisibilityState getVisibilityState(const QModelIndex& theIndex) const; - - void addShownFolder(DocumentPtr theDoc, QString theFolder) - { - if (!myShownFolders.contains(theDoc)) { - myShownFolders[theDoc] = QStringList(); - } - myShownFolders[theDoc].append(theFolder); - } - - void removeShownFolder(DocumentPtr theDoc, QString theFolder) - { - if (myShownFolders.contains(theDoc)) { - myShownFolders[theDoc].removeAll(theFolder); - if (myShownFolders[theDoc].isEmpty()) - myShownFolders.remove(theDoc); - } - } - - bool hasShownFolder(DocumentPtr theDoc, QString theFolder) const - { - if (myShownFolders.contains(theDoc)) - return myShownFolders[theDoc].contains(theFolder); - return false; - } - - Config_DataModelReader* myXMLReader; + //QStringList listOfShowNotEmptyFolders(bool fromRoot = true) const; + + //int getNumberOfFolderItems(const ModelAPI_Folder* theFolder) const; + //ObjectPtr getObjectInFolder(const ModelAPI_Folder* theFolder, int theId) const; + + //VisibilityState getVisibilityState(const QModelIndex& theIndex) const; + + //void addShownFolder(DocumentPtr theDoc, QString theFolder) + //{ + // if (!myShownFolders.contains(theDoc)) { + // myShownFolders[theDoc] = QStringList(); + // } + // myShownFolders[theDoc].append(theFolder); + //} + + //void removeShownFolder(DocumentPtr theDoc, QString theFolder) + //{ + // if (myShownFolders.contains(theDoc)) { + // myShownFolders[theDoc].removeAll(theFolder); + // if (myShownFolders[theDoc].isEmpty()) + // myShownFolders.remove(theDoc); + // } + //} + + //bool hasShownFolder(DocumentPtr theDoc, QString theFolder) const + //{ + // if (myShownFolders.contains(theDoc)) + // return myShownFolders[theDoc].contains(theFolder); + // return false; + //} + + //Config_DataModelReader* myXMLReader; XGUI_Workshop* myWorkshop; QMap myShownFolders; //bool myIsEventsProcessingBlocked; + + ModuleBase_ITreeNode* myRoot; }; #endif \ No newline at end of file diff --git a/src/XGUI/XGUI_ModuleConnector.cpp b/src/XGUI/XGUI_ModuleConnector.cpp index 4f2130509..5c67a3d50 100644 --- a/src/XGUI/XGUI_ModuleConnector.cpp +++ b/src/XGUI/XGUI_ModuleConnector.cpp @@ -109,6 +109,13 @@ AISObjectPtr XGUI_ModuleConnector::findPresentation(const ObjectPtr& theObject) return aDisp->getAISObject(theObject); } +bool XGUI_ModuleConnector::isVisible(const ObjectPtr& theObject) const +{ + XGUI_Displayer* aDisp = myWorkshop->displayer(); + return aDisp->isVisible(theObject); +} + + ObjectPtr XGUI_ModuleConnector::findPresentedObject(const AISObjectPtr& theAIS) const { XGUI_Displayer* aDisp = myWorkshop->displayer(); diff --git a/src/XGUI/XGUI_ModuleConnector.h b/src/XGUI/XGUI_ModuleConnector.h index 6bf3914c2..409c6edee 100644 --- a/src/XGUI/XGUI_ModuleConnector.h +++ b/src/XGUI/XGUI_ModuleConnector.h @@ -94,6 +94,10 @@ Q_OBJECT //! Returns data object by AIS virtual ObjectPtr findPresentedObject(const AISObjectPtr& theAIS) const; + //! Returns true if the object is displayed + //! \param theObject a data object + virtual bool isVisible(const ObjectPtr& theObject) const; + //! Select features clearing previous selection. //! If the list is empty then selection will be cleared virtual void setSelected(const QList>& theValues); diff --git a/src/XGUI/XGUI_ObjectsBrowser.cpp b/src/XGUI/XGUI_ObjectsBrowser.cpp index d256e56db..ab86347b5 100644 --- a/src/XGUI/XGUI_ObjectsBrowser.cpp +++ b/src/XGUI/XGUI_ObjectsBrowser.cpp @@ -220,7 +220,6 @@ void XGUI_DataTree::processHistoryChange(const QModelIndex& theIndex) aDoc->setCurrentFeature(FeaturePtr(), true); aMgr->finishOperation(); } - QModelIndex aNewIndex = aModel->lastHistoryIndex(); QModelIndex aParent = theIndex.parent(); int aSize = aModel->rowCount(aParent); for (int i = 0; i < aSize; i++) { @@ -426,9 +425,10 @@ XGUI_ObjectsBrowser::~XGUI_ObjectsBrowser() { } -void XGUI_ObjectsBrowser::setXMLReader(Config_DataModelReader* theReader) +void XGUI_ObjectsBrowser::initialize(ModuleBase_ITreeNode* theRoot) { - myDocModel->setXMLReader(theReader); + //myDocModel->setXMLReader(theReader); + myDocModel->setRoot(theRoot); myTreeView->setModel(myDocModel); // It has to be done after setting of model @@ -606,7 +606,8 @@ void XGUI_ObjectsBrowser::onBeforeReset() void XGUI_ObjectsBrowser::onAfterModelReset() { foreach(QModelIndex aIndex, myExpandedItems) { - myTreeView->setExpanded(aIndex, true); + if (myTreeView->dataModel()->hasIndex(aIndex)) + myTreeView->setExpanded(aIndex, true); } } @@ -646,9 +647,10 @@ void XGUI_ObjectsBrowser::updateAllIndexes(int theColumn, const QModelIndex& the int aNb = myDocModel->rowCount(theParent); for (int i = 0; i < aNb; i++) { QModelIndex aIdx = myDocModel->index(i, theColumn, theParent); - if (aIdx.isValid()) { + if (aIdx.isValid() && myDocModel->hasIndex(aIdx)) { myTreeView->update(aIdx); - updateAllIndexes(theColumn, aIdx); + if (myTreeView->isExpanded(aIdx)) + updateAllIndexes(theColumn, aIdx); } } } diff --git a/src/XGUI/XGUI_ObjectsBrowser.h b/src/XGUI/XGUI_ObjectsBrowser.h index f83ddfcad..c05073065 100644 --- a/src/XGUI/XGUI_ObjectsBrowser.h +++ b/src/XGUI/XGUI_ObjectsBrowser.h @@ -37,6 +37,7 @@ class ModuleBase_IDocumentDataModel; class XGUI_DataModel; class Config_DataModelReader; class XGUI_Workshop; +class ModuleBase_ITreeNode; //#define DEBUG_INDXES @@ -175,7 +176,10 @@ Q_OBJECT //! Returns currently selected indexes QModelIndexList selectedIndexes() const { - return myTreeView->selectionModel()->selectedIndexes(); + if (myTreeView->selectionModel()) + return myTreeView->selectionModel()->selectedIndexes(); + else + return QModelIndexList(); } //! Returns TreeView widget @@ -193,9 +197,8 @@ Q_OBJECT /// Resets the object browser into initial state void clearContent(); - /// Set XML reader object for data model - /// \param theReader the reader object - void setXMLReader(Config_DataModelReader* theReader); + /// Initialize the Object browser + void initialize(ModuleBase_ITreeNode* theRoot); /// Returns list of folders opened state for the given document /// \param theDoc the document diff --git a/src/XGUI/XGUI_Workshop.cpp b/src/XGUI/XGUI_Workshop.cpp index 0a1b1570c..9fe73219f 100755 --- a/src/XGUI/XGUI_Workshop.cpp +++ b/src/XGUI/XGUI_Workshop.cpp @@ -1310,7 +1310,7 @@ QDockWidget* XGUI_Workshop::createObjectBrowser(QWidget* theParent) aObjDock->setStyleSheet( "::title { position: relative; padding-left: 5px; text-align: left center }"); myObjectBrowser = new XGUI_ObjectsBrowser(aObjDock, this); - myObjectBrowser->setXMLReader(myDataModelXMLReader); + myObjectBrowser->initialize(myModule->rootNode()); myModule->customizeObjectBrowser(myObjectBrowser); aObjDock->setWidget(myObjectBrowser); @@ -1443,8 +1443,9 @@ void XGUI_Workshop::hidePanel(QDockWidget* theDockWidget) //****************************************************** void XGUI_Workshop::showObjectBrowser() { - if (!isSalomeMode()) + if (!isSalomeMode()) { myObjectBrowser->parentWidget()->show(); + } } //******************************************************