X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FXGUI%2FXGUI_DataModel.cpp;h=344b4bfc3db37a3ae58d7686fc1c2129a6c68472;hb=d9359acfaf1fa39e052d117c30af8a28e117b78d;hp=2a30656d42ea2c9766a5239445442787d9971975;hpb=703b67eb8a86fd14603e03b3755ed65d6c22de87;p=modules%2Fshaper.git diff --git a/src/XGUI/XGUI_DataModel.cpp b/src/XGUI/XGUI_DataModel.cpp index 2a30656d4..344b4bfc3 100644 --- a/src/XGUI/XGUI_DataModel.cpp +++ b/src/XGUI/XGUI_DataModel.cpp @@ -13,6 +13,10 @@ #include #include #include +#include +#include +#include +#include #include @@ -33,7 +37,10 @@ ResultPartPtr getPartResult(ModelAPI_Object* theObj) if (aFeature) { ResultPtr aRes = aFeature->firstResult(); if (aRes.get() && (aRes->groupName() == ModelAPI_ResultPart::group())) { - return std::dynamic_pointer_cast(aRes); + ResultPartPtr aPartRes = std::dynamic_pointer_cast(aRes); + // Use only original parts, not a placement results + if (aPartRes == aPartRes->original()) + return aPartRes; } } return ResultPartPtr(); @@ -50,13 +57,14 @@ ModelAPI_Document* getSubDocument(void* theObj) // Constructor ************************************************* -XGUI_DataModel::XGUI_DataModel(QObject* theParent) : QAbstractItemModel(theParent) +XGUI_DataModel::XGUI_DataModel(QObject* theParent) : ModuleBase_IDocumentDataModel(theParent) { myXMLReader.readAll(); 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_DOCUMENT_CHANGED)); } //****************************************************** @@ -77,6 +85,10 @@ void XGUI_DataModel::processEvent(const std::shared_ptr& theMess std::string aObjType; for (aIt = aObjects.begin(); aIt != aObjects.end(); ++aIt) { ObjectPtr aObject = (*aIt); + // We do not show objects which not has to be shown in object browser + if (!aObject->isInHistory()) + continue; + aObjType = aObject->groupName(); DocumentPtr aDoc = aObject->document(); if (aDoc == aRootDoc) { @@ -115,16 +127,17 @@ void XGUI_DataModel::processEvent(const std::shared_ptr& theMess insertRow(aRow + aNbSubFolders, aDocRoot); } else { // List of objects under a folder - int aFolderId = myXMLReader.subFolderId(aObjType); - if (aFolderId != -1) { - insertRow(aRow, createIndex(aFolderId, 0, aDoc.get())); + if (aRow != -1) { + int aFolderId = myXMLReader.subFolderId(aObjType); + if (aFolderId != -1) { + insertRow(aRow, createIndex(aFolderId, 0, aDoc.get())); + } } } } #ifdef _DEBUG - else { + else Events_Error::send("Problem with Data Model definition of sub-document"); - } #endif } } @@ -180,12 +193,22 @@ void XGUI_DataModel::processEvent(const std::shared_ptr& theMess } } #ifdef _DEBUG - else { + else Events_Error::send("Problem with Data Model definition of sub-document"); - } #endif } } + } else if (theMessage->eventID() == Events_Loop::loop()->eventByName(EVENT_DOCUMENT_CHANGED)) { + DocumentPtr aDoc = ModelAPI_Session::get()->activeDocument(); + if (aDoc != aRootDoc) { + QModelIndex aDocRoot = findDocumentRootIndex(aDoc.get()); + if (aDocRoot.isValid()) + emit dataChanged(aDocRoot, aDocRoot); +#ifdef _DEBUG + else + Events_Error::send("Problem with Data Model definition of sub-document"); +#endif + } } } @@ -210,18 +233,7 @@ ObjectPtr XGUI_DataModel::object(const QModelIndex& theIndex) const if (getSubDocument(aObj)) // the selected index is a folder of sub-document return ObjectPtr(); - // We can not create the ObjectPtr directly because the pointer will be deleted - // with deletion of the ObjectPtr because its counter become to 0. - DocumentPtr aDoc = aObj->document(); - std::string aType = aObj->groupName(); - - ObjectPtr aObjPtr; - for (int i = 0; i < aDoc->size(aType); i++) { - aObjPtr = aDoc->object(aType, i); - if (aObjPtr.get() == aObj) - return aObjPtr; - } - return ObjectPtr(); + return aObj->data()->owner(); } //****************************************************** @@ -230,9 +242,38 @@ QModelIndex XGUI_DataModel::objectIndex(const ObjectPtr theObject) const std::string aType = theObject->groupName(); DocumentPtr aDoc = theObject->document(); int aRow = aDoc->index(theObject); - if (aRow == -1) - return QModelIndex(); - + if (aRow == -1) { + // it could be a part of complex object + FeaturePtr aFeature = std::dynamic_pointer_cast(theObject); + if (aFeature.get()) { + CompositeFeaturePtr aCompFea = ModelAPI_Tools::compositeOwner(aFeature); + if (aCompFea.get()) { + for (int i = 0; i < aCompFea->numberOfSubs(true); i++) { + if (aCompFea->subFeature(i, true) == theObject) { + aRow = i; + break; + } + } + } + } else { + ResultPtr aResult = std::dynamic_pointer_cast(theObject); + if (aResult.get()) { + ResultCompSolidPtr aCompRes = ModelAPI_Tools::compSolidOwner(aResult); + if (aCompRes.get()) { + for (int i = 0; i < aCompRes->numberOfSubs(true); i++) { + if (aCompRes->subResult(i, true) == theObject) { + aRow = i; + break; + } + } + } + } + } + if (aRow == -1) + return QModelIndex(); + else + return createIndex(aRow, 0, theObject.get()); + } SessionPtr aSession = ModelAPI_Session::get(); DocumentPtr aRootDoc = aSession->moduleDocument(); if (aDoc == aRootDoc && myXMLReader.rootType() == aType) { @@ -253,14 +294,11 @@ QVariant XGUI_DataModel::data(const QModelIndex& theIndex, int theRole) const int aNbFolders = foldersCount(); int theIndexRow = theIndex.row(); - if ((theIndex.column() == 1) ) { - //if (theIndexRow >= aNbFolders) { - // if (theRole == Qt::DecorationRole) { - // return QIcon(":pictures/arrow.png"); - // } - //} + if ((theRole == Qt::DecorationRole) && (theIndex == lastHistoryIndex())) + return QIcon(":pictures/arrow.png"); + + if (theIndex.column() == 1) return QVariant(); - } int aParentId = theIndex.internalId(); if (aParentId == -1) { // root folders @@ -271,21 +309,23 @@ QVariant XGUI_DataModel::data(const QModelIndex& theIndex, int theRole) const case Qt::DecorationRole: return QIcon(myXMLReader.rootFolderIcon(theIndexRow).c_str()); case Qt::ForegroundRole: - if (aRootDoc->isActive()) + if (aSession->activeDocument() == aRootDoc) return QBrush(ACTIVE_COLOR); else return QBrush(PASSIVE_COLOR); } - } else { + } else { // an object or sub-document ModelAPI_Document* aSubDoc = getSubDocument(theIndex.internalPointer()); if (theRole == Qt::ForegroundRole) { bool aIsActive = false; if (aSubDoc) - aIsActive = aSubDoc->isActive(); + aIsActive = (aSession->activeDocument().get() == aSubDoc); else { ModelAPI_Object* aObj = (ModelAPI_Object*)theIndex.internalPointer(); - aIsActive = aObj->document()->isActive(); + if (aObj->isDisabled()) + return QBrush(Qt::lightGray); + aIsActive = (aSession->activeDocument() == aObj->document()); } if (aIsActive) return QBrush(ACTIVE_COLOR); @@ -360,8 +400,8 @@ int XGUI_DataModel::rowCount(const QModelIndex& theParent) const std::string aType = myXMLReader.subFolderType(theParent.row()); return aDoc->size(aType); } else { - // Check for Part feature ModelAPI_Object* aObj = (ModelAPI_Object*)theParent.internalPointer(); + // Check for Part feature ResultPartPtr aPartRes = getPartResult(aObj); if (aPartRes.get()) { DocumentPtr aSubDoc = aPartRes->partDoc(); @@ -371,6 +411,14 @@ int XGUI_DataModel::rowCount(const QModelIndex& theParent) const if (!aSubType.empty()) aNbSubItems = aSubDoc->size(aSubType); return aNbSubItems + aNbSubFolders; + } else { + // Check for composite object + ModelAPI_CompositeFeature* aCompFeature = dynamic_cast(aObj); + if (aCompFeature) + return aCompFeature->numberOfSubs(true); + ModelAPI_ResultCompSolid* aCompRes = dynamic_cast(aObj); + if (aCompRes) + return aCompRes->numberOfSubs(true); } } } @@ -390,6 +438,8 @@ QModelIndex XGUI_DataModel::index(int theRow, int theColumn, const QModelIndex & DocumentPtr aRootDoc = aSession->moduleDocument(); int aNbFolders = foldersCount(); + QModelIndex aIndex; + if (!theParent.isValid()) { if (theRow < aNbFolders) // Return first level folder index return createIndex(theRow, theColumn, -1); @@ -398,66 +448,71 @@ QModelIndex XGUI_DataModel::index(int theRow, int theColumn, const QModelIndex & int aObjId = theRow - aNbFolders; if (aObjId < aRootDoc->size(aType)) { ObjectPtr aObj = aRootDoc->object(aType, aObjId); - QModelIndex aIndex = objectIndex(aObj); - if (theColumn != 0) - return createIndex(aIndex.row(), theColumn, aIndex.internalPointer()); - return aIndex; + aIndex = objectIndex(aObj); } - return QModelIndex(); - } - } - int aId = theParent.internalId(); - int aParentPos = theParent.row(); - if (aId == -1) { // 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); - QModelIndex aIndex = objectIndex(aObj); - if (theColumn != 0) - return createIndex(aIndex.row(), theColumn, aIndex.internalPointer()); - return aIndex; } } else { - // It is an object which could have children - ModelAPI_Document* aDoc = getSubDocument(theParent.internalPointer()); - if (aDoc) { - // It is a folder of sub-document - std::string aType = myXMLReader.subFolderType(aParentPos); - if (theRow < aDoc->size(aType)) { - ObjectPtr aObj = aDoc->object(aType, theRow); - QModelIndex aIndex = objectIndex(aObj); - if (theColumn != 0) - return createIndex(aIndex.row(), theColumn, aIndex.internalPointer()); - return aIndex; + int aId = theParent.internalId(); + int aParentPos = theParent.row(); + if (aId == -1) { // return object index inside of first level of folders + std::string aType = myXMLReader.rootFolderType(aParentPos); + if (theRow < aRootDoc->size(aType)) { + ObjectPtr aObj = aRootDoc->object(aType, theRow); + aIndex = objectIndex(aObj); } } else { - ModelAPI_Object* aParentObj = (ModelAPI_Object*)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 - return createIndex(theRow, theColumn, aSubDoc.get()); + // It is an object which could have children + ModelAPI_Document* aDoc = getSubDocument(theParent.internalPointer()); + if (aDoc) { + // It is a folder of sub-document + std::string aType = myXMLReader.subFolderType(aParentPos); + if (theRow < aDoc->size(aType)) { + ObjectPtr aObj = aDoc->object(aType, theRow); + aIndex = objectIndex(aObj); + } + } else { + ModelAPI_Object* aParentObj = (ModelAPI_Object*)theParent.internalPointer(); + + // Check for Part feature + ResultPartPtr aPartRes = getPartResult(aParentObj); + if (aPartRes.get()) { + DocumentPtr aSubDoc = aPartRes->partDoc(); + int aNbSubFolders = foldersCount(aSubDoc.get()); + if (theRow < aNbSubFolders) { // Create a Folder of sub-document + aIndex = createIndex(theRow, theColumn, aSubDoc.get()); + } else { + // this is an object under sub document root + std::string aType = myXMLReader.subType(); + ObjectPtr aObj = aSubDoc->object(aType, theRow - aNbSubFolders); + aIndex = objectIndex(aObj); + } } else { - // this is an object under sub document root - std::string aType = myXMLReader.subType(); - ObjectPtr aObj = aSubDoc->object(aType, theRow - aNbSubFolders); - QModelIndex aIndex = objectIndex(aObj); - if (theColumn != 0) - return createIndex(aIndex.row(), theColumn, aIndex.internalPointer()); - return aIndex; + // Check for composite object + ModelAPI_CompositeFeature* aCompFeature = dynamic_cast(aParentObj); + if (aCompFeature) { + aIndex = objectIndex(aCompFeature->subFeature(theRow)); + } else { + ModelAPI_ResultCompSolid* aCompRes = dynamic_cast(aParentObj); + if (aCompRes) + aIndex = objectIndex(aCompRes->subResult(theRow)); + } } } } } - return QModelIndex(); + if (theColumn != 0) + return createIndex(aIndex.row(), theColumn, aIndex.internalPointer()); + return aIndex; } //****************************************************** +static QModelIndex MYLastDeleted; QModelIndex XGUI_DataModel::parent(const QModelIndex& theIndex) const { + // To avoid additional request about index which was already deleted + if (theIndex == MYLastDeleted) + return QModelIndex(); + int aId = theIndex.internalId(); if (aId != -1) { // The object is not a root folder ModelAPI_Document* aDoc = getSubDocument(theIndex.internalPointer()); @@ -465,7 +520,29 @@ QModelIndex XGUI_DataModel::parent(const QModelIndex& theIndex) const // It is a folder of sub-document return findDocumentRootIndex(aDoc); } - ModelAPI_Object* aObj = (ModelAPI_Object*) theIndex.internalPointer(); + ObjectPtr aObj = object(theIndex); + if (!aObj.get()) { + // To avoid additional request about index which was already deleted + // If deleted it causes a crash on delete object from Part + MYLastDeleted = theIndex; + return QModelIndex(); + } + // Check is it object a sub-object of a complex object + FeaturePtr aFeature = std::dynamic_pointer_cast(aObj); + if (aFeature.get()) { + CompositeFeaturePtr aCompFea = ModelAPI_Tools::compositeOwner(aFeature); + if (aCompFea.get()) { + return objectIndex(aCompFea); + } + } + ResultPtr aResult = std::dynamic_pointer_cast(aObj); + if (aResult.get()) { + ResultCompSolidPtr aCompRes = ModelAPI_Tools::compSolidOwner(aResult); + if (aCompRes.get()) { + return objectIndex(aCompRes); + } + } + // Use as ordinary object std::string aType = aObj->groupName(); SessionPtr aSession = ModelAPI_Session::get(); DocumentPtr aRootDoc = aSession->moduleDocument(); @@ -524,7 +601,16 @@ bool XGUI_DataModel::hasChildren(const QModelIndex& theParent) const // Check for Part feature ResultPartPtr aPartRes = getPartResult(aObj); if (aPartRes.get()) - return true; + return aPartRes->partDoc().get() != NULL; + else { + // Check for composite object + ModelAPI_CompositeFeature* aCompFeature = dynamic_cast(aObj); + if (aCompFeature) + return aCompFeature->numberOfSubs(true) > 0; + ModelAPI_ResultCompSolid* aCompRes = dynamic_cast(aObj); + if (aCompRes) + return aCompRes->numberOfSubs(true) > 0; + } } } return false; @@ -550,10 +636,40 @@ bool XGUI_DataModel::removeRows(int theRow, int theCount, const QModelIndex& the //****************************************************** Qt::ItemFlags XGUI_DataModel::flags(const QModelIndex& theIndex) const { - Qt::ItemFlags aFlags = Qt::ItemIsSelectable | Qt::ItemIsEnabled; - if (theIndex.internalId() > -1) { - aFlags |= Qt::ItemIsEditable; + Qt::ItemFlags aFlags = Qt::ItemIsSelectable; + + ModelAPI_Object* aObj = 0; + if (theIndex.internalId() != -1) { + if (!getSubDocument(theIndex.internalPointer())) + aObj = (ModelAPI_Object*) theIndex.internalPointer(); } + if (aObj) { + if (aObj->isDisabled()) + return Qt::ItemFlags(); + + bool isCompositeSub = false; + if (theIndex.column() == 1) { + ObjectPtr aObjPtr = aObj->data()->owner(); + FeaturePtr aFeature = std::dynamic_pointer_cast(aObjPtr); + if (aFeature.get()) { + CompositeFeaturePtr aCompFea = ModelAPI_Tools::compositeOwner(aFeature); + if (aCompFea.get()) + isCompositeSub = true; + } else { + ResultPtr aResult = std::dynamic_pointer_cast(aObjPtr); + if (aResult.get()) { + ResultCompSolidPtr aCompRes = ModelAPI_Tools::compSolidOwner(aResult); + if (aCompRes.get()) + isCompositeSub = true; + } + } + } + // An object which is sub-object of a composite object can not be accessible in column 1 + if (isCompositeSub) + return Qt::ItemFlags(); + } + + aFlags |= Qt::ItemIsEnabled; return aFlags; } @@ -649,4 +765,21 @@ QStringList XGUI_DataModel::listOfShowNotEmptyFolders(bool fromRoot) const } } 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(), 1, aInd.internalPointer()); + } else { + if (aCurDoc == aSession->moduleDocument()) + return createIndex(foldersCount() - 1, 1, -1); + else + return createIndex(foldersCount(aCurDoc.get()) - 1, 1, aCurDoc.get()); + } } \ No newline at end of file