X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FXGUI%2FXGUI_DataModel.cpp;h=64088473747c5ebac9787fc798f75ffb0e4c0a2b;hb=3634c648d0695bb65658daf868f316b349cc0795;hp=0353bf0b394c2e1da1346eb628994e9a47a4dbd8;hpb=c795030a80f70473cfcd9bd1bbe2d65f3b25fb0b;p=modules%2Fshaper.git diff --git a/src/XGUI/XGUI_DataModel.cpp b/src/XGUI/XGUI_DataModel.cpp index 0353bf0b3..640884737 100644 --- a/src/XGUI/XGUI_DataModel.cpp +++ b/src/XGUI/XGUI_DataModel.cpp @@ -1,10 +1,27 @@ -// Copyright (C) 2014-20xx CEA/DEN, EDF R&D --> - -// File: ModuleBase_IDocumentDataModel.cpp -// Created: 28 Apr 2015 -// Author: Vitaly SMETANNIKOV +// Copyright (C) 2014-2017 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or +// email : webmaster.salome@opencascade.com +// #include "XGUI_DataModel.h" +#include "XGUI_Workshop.h" +#include "XGUI_ObjectsBrowser.h" +#include "XGUI_Displayer.h" #include @@ -16,7 +33,10 @@ #include #include #include +#include #include +#include +#include #include #include @@ -33,9 +53,10 @@ /// Returns ResultPart object if the given object is a Part feature /// Otherwise returns NULL -#define SELECTABLE_COLOR QColor(80, 80, 80) +#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); @@ -54,7 +75,10 @@ ResultPartPtr getPartResult(ModelAPI_Object* theObj) /// Returns pointer on document if the given object is document object ModelAPI_Document* getSubDocument(void* theObj) { - ModelAPI_Document* aDoc = dynamic_cast((ModelAPI_Entity*)theObj); + ModelAPI_Document* aDoc = 0; + try { + aDoc = dynamic_cast((ModelAPI_Entity*)theObj); + } catch(...) {} return aDoc; } @@ -65,6 +89,9 @@ ModelAPI_Document* getSubDocument(void* theObj) XGUI_DataModel::XGUI_DataModel(QObject* theParent) : QAbstractItemModel(theParent)//, //myIsEventsProcessingBlocked(false) { + XGUI_ObjectsBrowser* aOB = qobject_cast(theParent); + myWorkshop = aOB->workshop(); + Events_Loop* aLoop = Events_Loop::loop(); aLoop->registerListener(this, Events_Loop::eventByName(EVENT_OBJECT_CREATED)); aLoop->registerListener(this, Events_Loop::eventByName(EVENT_OBJECT_DELETED)); @@ -75,6 +102,7 @@ XGUI_DataModel::XGUI_DataModel(QObject* theParent) : QAbstractItemModel(theParen XGUI_DataModel::~XGUI_DataModel() { + clear(); } //****************************************************** @@ -107,37 +135,45 @@ void XGUI_DataModel::processEvent(const std::shared_ptr& theMess // Check that new folders could appear QStringList aNotEmptyFolders = listOfShowNotEmptyFolders(); foreach (QString aNotEmptyFolder, aNotEmptyFolders) { - if ((aNotEmptyFolder.toStdString() == aObjType) && (aRootDoc->size(aObjType) == 1)) + if ((aNotEmptyFolder.toStdString() == aObjType) && (aRootDoc->size(aObjType) > 0)) { // Appears first object in folder which can not be shown empty - insertRow(myXMLReader->rootFolderId(aObjType)); + 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) { + 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, Q_NULLPTR)); + insertRow(aRow, createIndex(aFolderId, 0, (void*)Q_NULLPTR)); } } } } else { // Object created in sub-document - QModelIndex aDocRoot = findDocumentRootIndex(aDoc.get()); + 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) == 1)) + if ((aNotEmptyFolder.toStdString() == aObjType) && (aDoc->size(aObjType) > 0)) { // Appears first object in folder which can not be shown empty - insertRow(myXMLReader->subFolderId(aObjType), aDocRoot); - } - int aRow = aDoc->index(aObject); + 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) { + if ((aObjType == aSubType) || (aObjType == ModelAPI_Folder::group())) { // List of objects under document root insertRow(aRow + aNbSubFolders, aDocRoot); } else { @@ -151,6 +187,9 @@ void XGUI_DataModel::processEvent(const std::shared_ptr& theMess } } } + } else { + rebuildDataTree(); + break; } } else { rebuildDataTree(); @@ -181,16 +220,18 @@ void XGUI_DataModel::processEvent(const std::shared_ptr& theMess for (aIt = aGroups.begin(); aIt != aGroups.end(); ++aIt) { std::string aGroup = (*aIt); if (aDoc == aRootDoc) { // If root objects - int aRow = aRootDoc->size(aGroup); + int aRow = aRootDoc->size(aGroup, true); if (aGroup == aRootType) { // Process root folder removeRow(aRow + aNbFolders); rebuildBranch(aNbFolders, aRow); + } 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, Q_NULLPTR); + QModelIndex aFolderIndex = createIndex(aFolderId, 0, (void*)Q_NULLPTR); removeRow(aRow, aFolderIndex); //rebuildBranch(0, aRow); } @@ -198,23 +239,26 @@ void XGUI_DataModel::processEvent(const std::shared_ptr& theMess // Check that some folders could erased QStringList aNotEmptyFolders = listOfShowNotEmptyFolders(); foreach (QString aNotEmptyFolder, aNotEmptyFolders) { - if ((aNotEmptyFolder.toStdString() == aGroup) && (aRootDoc->size(aGroup) == 0)) { + 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()); + QModelIndex aDocRoot = findDocumentRootIndex(aDoc.get(), 0); if (aDocRoot.isValid()) { - int aRow = aDoc->size(aGroup); + 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()); @@ -226,11 +270,12 @@ void XGUI_DataModel::processEvent(const std::shared_ptr& theMess } // Check that some folders could disappear QStringList aNotEmptyFolders = listOfShowNotEmptyFolders(false); - int aSize = aDoc->size(aGroup); + 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; } @@ -247,13 +292,25 @@ void XGUI_DataModel::processEvent(const std::shared_ptr& theMess std::set aObjects = aUpdMsg->objects(); std::set::const_iterator aIt; - std::string aObjType; for (aIt = aObjects.begin(); aIt != aObjects.end(); ++aIt) { ObjectPtr aObject = (*aIt); if (aObject->data()->isValid()) { - QModelIndex aIndex = objectIndex(aObject); - if (aIndex.isValid()) { - emit dataChanged(aIndex, aIndex); + 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(); @@ -274,12 +331,12 @@ void XGUI_DataModel::processEvent(const std::shared_ptr& theMess if (aGroup == myXMLReader->rootType()) // Update objects under root aStartId = foldersCount(); else // Update objects in folder under root - aParent = createIndex(folderId(aGroup), 0, Q_NULLPTR); + 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()); + aParent = findDocumentRootIndex(aDoc.get(), 0); aStartId = foldersCount(aDoc.get()); } else // update folder in sub-document @@ -293,7 +350,7 @@ void XGUI_DataModel::processEvent(const std::shared_ptr& theMess } 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()); + QModelIndex aDocRoot = findDocumentRootIndex(aDoc.get(), 0); if (aDocRoot.isValid()) emit dataChanged(aDocRoot, aDocRoot); else @@ -306,7 +363,8 @@ void XGUI_DataModel::processEvent(const std::shared_ptr& theMess //****************************************************** void XGUI_DataModel::clear() { - + beginResetModel(); + endResetModel(); } //****************************************************** @@ -322,7 +380,13 @@ ObjectPtr XGUI_DataModel::object(const QModelIndex& theIndex) const { if (theIndex.internalId() == 0) // this is a folder return ObjectPtr(); - ModelAPI_Object* aObj = (ModelAPI_Object*)theIndex.internalPointer(); + 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(); @@ -330,11 +394,11 @@ ObjectPtr XGUI_DataModel::object(const QModelIndex& theIndex) const } //****************************************************** -QModelIndex XGUI_DataModel::objectIndex(const ObjectPtr theObject) const +QModelIndex XGUI_DataModel::objectIndex(const ObjectPtr theObject, int theColumn) const { std::string aType = theObject->groupName(); DocumentPtr aDoc = theObject->document(); - int aRow = aDoc->index(theObject); + int aRow = aDoc->index(theObject, true); if (aRow == -1) { // it could be a part of complex object FeaturePtr aFeature = std::dynamic_pointer_cast(theObject); @@ -348,35 +412,35 @@ QModelIndex XGUI_DataModel::objectIndex(const ObjectPtr theObject) const } } } + 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()) { - for (int i = 0; i < aCompRes->numberOfSubs(true); i++) { - if (aCompRes->subResult(i, true) == theObject) { - aRow = i; - break; - } - } + aRow = ModelAPI_Tools::compSolidIndex(aResult); } } } if (aRow == -1) return QModelIndex(); else - return createIndex(aRow, 0, theObject.get()); + return createIndex(aRow, theColumn, theObject.get()); } SessionPtr aSession = ModelAPI_Session::get(); DocumentPtr aRootDoc = aSession->moduleDocument(); - if (aDoc == aRootDoc && myXMLReader->rootType() == aType) { + if (aDoc == aRootDoc && + ((myXMLReader->rootType() == aType) || (aType == ModelAPI_Folder::group()))) { // The object from root document aRow += foldersCount(); - } else if (myXMLReader->subType() == aType) { + } else if ((myXMLReader->subType() == aType) || (aType == ModelAPI_Folder::group())) { // The object from sub document aRow += foldersCount(aDoc.get()); } - return createIndex(aRow, 0, theObject.get()); + return createIndex(aRow, theColumn, theObject.get()); } //****************************************************** @@ -387,10 +451,26 @@ QVariant XGUI_DataModel::data(const QModelIndex& theIndex, int theRole) const int aNbFolders = foldersCount(); int theIndexRow = theIndex.row(); - if ((theRole == Qt::DecorationRole) && (theIndex == lastHistoryIndex())) - return QIcon(":pictures/arrow.png"); + 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) + if (theIndex.column() != 1) return QVariant(); quintptr aParentId = theIndex.internalId(); @@ -437,30 +517,51 @@ QVariant XGUI_DataModel::data(const QModelIndex& theIndex, int theRole) const } } } else { - ModelAPI_Object* aObj = (ModelAPI_Object*)theIndex.internalPointer(); - switch (theRole) { - case Qt::DisplayRole: - { - if (aObj->groupName() == ModelAPI_ResultParameter::group()) { - ModelAPI_ResultParameter* aParam = dynamic_cast(aObj); - AttributeDoublePtr aValueAttribute = - aParam->data()->real(ModelAPI_ResultParameter::VALUE()); - QString aVal = QString::number(aValueAttribute->value()); - QString aTitle = QString(aObj->data()->name().c_str()); - return aTitle + " = " + aVal; + 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); } - QString aSuffix; - if (aObj->groupName() == myXMLReader->subType()) { - ResultPartPtr aPartRes = getPartResult(aObj); - if (aPartRes.get()) { - if (aPartRes->partDoc().get() == NULL) - aSuffix = " (Not loaded)"; + } + } 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(); } } - return aObj->data()->name().c_str() + aSuffix; + break; } - case Qt::DecorationRole: - return ModuleBase_IconFactory::get()->getIcon(object(theIndex)); } } } @@ -487,7 +588,7 @@ int XGUI_DataModel::rowCount(const QModelIndex& theParent) const int aNbItems = 0; std::string aType = myXMLReader->rootType(); if (!aType.empty()) - aNbItems = aRootDoc->size(aType); + aNbItems = aRootDoc->size(aType, true); return aNbFolders + aNbItems; } @@ -511,7 +612,8 @@ int XGUI_DataModel::rowCount(const QModelIndex& theParent) const return aDoc->size(aType); } } else { - ModelAPI_Object* aObj = (ModelAPI_Object*)theParent.internalPointer(); + ModelAPI_Object* aObj = + dynamic_cast((ModelAPI_Entity*)theParent.internalPointer()); // Check for Part feature ResultPartPtr aPartRes = getPartResult(aObj); if (aPartRes.get()) { @@ -523,7 +625,7 @@ int XGUI_DataModel::rowCount(const QModelIndex& theParent) const int aNbSubItems = 0; std::string aSubType = myXMLReader->subType(); if (!aSubType.empty()) - aNbSubItems = aSubDoc->size(aSubType); + aNbSubItems = aSubDoc->size(aSubType, true); return aNbSubItems + aNbSubFolders; } else { // Check for composite object @@ -533,6 +635,12 @@ int XGUI_DataModel::rowCount(const QModelIndex& theParent) const 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); } } } @@ -542,7 +650,7 @@ int XGUI_DataModel::rowCount(const QModelIndex& theParent) const //****************************************************** int XGUI_DataModel::columnCount(const QModelIndex& theParent) const { - return 2; + return 3; } //****************************************************** @@ -556,13 +664,13 @@ QModelIndex XGUI_DataModel::index(int theRow, int theColumn, const QModelIndex & if (!theParent.isValid()) { if (theRow < aNbFolders) // Return first level folder index - return createIndex(theRow, theColumn, Q_NULLPTR); + return createIndex(theRow, theColumn, (void*)Q_NULLPTR); else { // return object under root index std::string aType = myXMLReader->rootType(); int aObjId = theRow - aNbFolders; - if (aObjId < aRootDoc->size(aType)) { - ObjectPtr aObj = aRootDoc->object(aType, aObjId); - aIndex = objectIndex(aObj); + if (aObjId < aRootDoc->size(aType, true)) { + ObjectPtr aObj = aRootDoc->object(aType, aObjId, true); + aIndex = objectIndex(aObj, theColumn); } } } else { @@ -571,8 +679,8 @@ QModelIndex XGUI_DataModel::index(int theRow, int theColumn, const QModelIndex & if (aId == 0) { // return object index inside of first level of folders std::string aType = myXMLReader->rootFolderType(aParentPos); if (theRow < aRootDoc->size(aType)) { - ObjectPtr aObj = aRootDoc->object(aType, theRow); - aIndex = objectIndex(aObj); + ObjectPtr aObj = aRootDoc->object(aType, theRow, true); + aIndex = objectIndex(aObj, theColumn); } } else { // It is an object which could have children @@ -587,11 +695,12 @@ QModelIndex XGUI_DataModel::index(int theRow, int theColumn, const QModelIndex & std::string aType = myXMLReader->subFolderType(aParentRow); if (theRow < aDoc->size(aType)) { ObjectPtr aObj = aDoc->object(aType, theRow); - aIndex = objectIndex(aObj); + aIndex = objectIndex(aObj, theColumn); } } } else { - ModelAPI_Object* aParentObj = (ModelAPI_Object*)theParent.internalPointer(); + ModelAPI_Object* aParentObj = + dynamic_cast((ModelAPI_Entity*)theParent.internalPointer()); // Check for Part feature ResultPartPtr aPartRes = getPartResult(aParentObj); @@ -603,27 +712,37 @@ QModelIndex XGUI_DataModel::index(int theRow, int theColumn, const QModelIndex & } else { // this is an object under sub document root std::string aType = myXMLReader->subType(); - ObjectPtr aObj = aSubDoc->object(aType, theRow - aNbSubFolders); - aIndex = objectIndex(aObj); + 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)); + aIndex = objectIndex(aCompFeature->subFeature(theRow), theColumn); } else { ModelAPI_ResultCompSolid* aCompRes = dynamic_cast(aParentObj); if (aCompRes) - aIndex = objectIndex(aCompRes->subResult(theRow)); + 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); + } + } } } } } } - if (theColumn != 0) - return createIndex(aIndex.row(), theColumn, aIndex.internalPointer()); return aIndex; } @@ -637,6 +756,7 @@ QModelIndex XGUI_DataModel::parent(const QModelIndex& theIndex) const 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()); @@ -646,6 +766,23 @@ QModelIndex XGUI_DataModel::parent(const QModelIndex& theIndex) const } 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; @@ -658,6 +795,11 @@ QModelIndex XGUI_DataModel::parent(const QModelIndex& theIndex) const 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()) { @@ -668,26 +810,25 @@ QModelIndex XGUI_DataModel::parent(const QModelIndex& theIndex) const } // Use as ordinary object std::string aType = aObj->groupName(); - SessionPtr aSession = ModelAPI_Session::get(); DocumentPtr aRootDoc = aSession->moduleDocument(); DocumentPtr aSubDoc = aObj->document(); if (aSubDoc == aRootDoc) { - if (aType == myXMLReader->rootType()) + 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, 0, Q_NULLPTR); + return createIndex(aFolderId, 1, (void*)Q_NULLPTR); } } else { - if (aType == myXMLReader->subType()) + 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, 0, aSubDoc.get()); + return createIndex(aFolderId, 1, aSubDoc.get()); } } } @@ -739,21 +880,21 @@ Qt::ItemFlags XGUI_DataModel::flags(const QModelIndex& theIndex) const } else { aDoc = getSubDocument(theIndex.internalPointer()); if (!aDoc) - aObj = (ModelAPI_Object*) theIndex.internalPointer(); + aObj = dynamic_cast((ModelAPI_Entity*)theIndex.internalPointer()); } if (aObj) { // An object if (aObj->isDisabled()) - return theIndex.column() == 1? Qt::ItemIsSelectable : aNullFlag; + return theIndex.column() == 2? Qt::ItemIsSelectable : aNullFlag; if (aSession->moduleDocument() != aObj->document()) if (aActiveDoc != aObj->document()) - return theIndex.column() == 1? Qt::ItemIsSelectable : aNullFlag; + 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 1 - if (theIndex.column() == 1) { + // 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()) { @@ -790,7 +931,8 @@ Qt::ItemFlags XGUI_DataModel::flags(const QModelIndex& theIndex) const } //****************************************************** -QModelIndex XGUI_DataModel::findDocumentRootIndex(const ModelAPI_Document* theDoc) const +QModelIndex + XGUI_DataModel::findDocumentRootIndex(const ModelAPI_Document* theDoc, int aColumn) const { SessionPtr aSession = ModelAPI_Session::get(); DocumentPtr aRootDoc = aSession->moduleDocument(); @@ -806,21 +948,21 @@ QModelIndex XGUI_DataModel::findDocumentRootIndex(const ModelAPI_Document* theDo if (myXMLReader->rootType() == ModelAPI_Feature::group()) { aRow += foldersCount(); } - return createIndex(aRow, 0, aObj.get()); + return createIndex(aRow, aColumn, aObj.get()); } } } else { // If document is attached to feature - int aNb = aRootDoc->size(ModelAPI_Feature::group()); + 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); + 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, 0, aObj.get()); + return createIndex(aRow, aColumn, aObj.get()); } } } @@ -828,14 +970,14 @@ QModelIndex XGUI_DataModel::findDocumentRootIndex(const ModelAPI_Document* theDo } //****************************************************** -QModelIndex XGUI_DataModel::documentRootIndex(DocumentPtr theDoc) const +QModelIndex XGUI_DataModel::documentRootIndex(DocumentPtr theDoc, int theColumn) const { SessionPtr aSession = ModelAPI_Session::get(); DocumentPtr aRootDoc = aSession->moduleDocument(); if (theDoc == aRootDoc) return QModelIndex(); else - return findDocumentRootIndex(theDoc.get()); + return findDocumentRootIndex(theDoc.get(), theColumn); } //****************************************************** @@ -918,15 +1060,21 @@ QModelIndex XGUI_DataModel::lastHistoryIndex() const FeaturePtr aFeature = aCurDoc->currentFeature(true); if (aFeature.get()) { QModelIndex aInd = objectIndex(aFeature); - return createIndex(aInd.row(), 1, aInd.internalPointer()); + return createIndex(aInd.row(), 2, aInd.internalPointer()); } else { if (aCurDoc == aSession->moduleDocument()) - return createIndex(foldersCount() - 1, 1, -1); + return createIndex(foldersCount() - 1, 2, -1); else - return createIndex(foldersCount(aCurDoc.get()) - 1, 1, aCurDoc.get()); + return createIndex(foldersCount(aCurDoc.get()) - 1, 2, aCurDoc.get()); } } +//****************************************************** +bool XGUI_DataModel::hasHiddenState(const QModelIndex& theIndex) +{ + return getVisibilityState(theIndex) == Hidden; +} + //****************************************************** int XGUI_DataModel::folderId(std::string theType, ModelAPI_Document* theDoc) const { @@ -976,3 +1124,86 @@ void XGUI_DataModel::rebuildBranch(int theRow, int theCount, const QModelIndex& // myIsEventsProcessingBlocked = theState; // return aPreviousState; //} + +//****************************************************** +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); +}