From c7c9598c735944d5ea695dc74c71eb7056d4ebac Mon Sep 17 00:00:00 2001 From: vsv Date: Tue, 27 Dec 2016 18:01:54 +0300 Subject: [PATCH] Provide displaying of steps in data browser --- .../CollectionPlugin_WidgetField.cpp | 6 +- src/Model/Model_ResultField.cpp | 63 +++++++++- src/Model/Model_ResultField.h | 34 +++++- src/ModelAPI/ModelAPI_Entity.h | 5 + src/ModelAPI/ModelAPI_ResultField.h | 20 ++++ src/XGUI/XGUI_DataModel.cpp | 113 +++++++++++++----- 6 files changed, 209 insertions(+), 32 deletions(-) diff --git a/src/CollectionPlugin/CollectionPlugin_WidgetField.cpp b/src/CollectionPlugin/CollectionPlugin_WidgetField.cpp index 5c0040a91..ebec37630 100644 --- a/src/CollectionPlugin/CollectionPlugin_WidgetField.cpp +++ b/src/CollectionPlugin/CollectionPlugin_WidgetField.cpp @@ -759,6 +759,7 @@ void CollectionPlugin_WidgetField::onAddStep() } } } + emit valuesChanged(); } //********************************************************************************** @@ -770,8 +771,9 @@ void CollectionPlugin_WidgetField::onRemoveStep() removeStepControls(); myStepSlider->setMaximum(aMax); - AttributeTablesPtr aTablesAttr = myFeature->data()->tables(CollectionPlugin_Field::VALUES_ID()); - aTablesAttr->setSize(aTablesAttr->rows(), aTablesAttr->columns(), myDataTblList.size()); + //AttributeTablesPtr aTablesAttr = myFeature->data()->tables(CollectionPlugin_Field::VALUES_ID()); + //aTablesAttr->setSize(aTablesAttr->rows(), aTablesAttr->columns(), myDataTblList.size()); + emit valuesChanged(); } //********************************************************************************** diff --git a/src/Model/Model_ResultField.cpp b/src/Model/Model_ResultField.cpp index 0c295fd43..da8f1773a 100644 --- a/src/Model/Model_ResultField.cpp +++ b/src/Model/Model_ResultField.cpp @@ -5,10 +5,12 @@ // Author: Mikhail PONIKAROV #include -#include #include + #include #include +#include +#include #include @@ -19,6 +21,14 @@ Model_ResultField::Model_ResultField(std::shared_ptr theOwnerData myOwnerData = theOwnerData; } +Model_ResultField::~Model_ResultField() +{ + while(mySteps.size() > 0) { + delete mySteps.back(); + mySteps.pop_back(); + } +} + void Model_ResultField::colorConfigInfo(std::string& theSection, std::string& theName, std::string& theDefault) { @@ -70,6 +80,57 @@ std::shared_ptr Model_ResultField::shape() aResult = GeomAlgoAPI_CompoundBuilder::compound(aSubs); } } + updateSteps(); } return aResult; } + +void Model_ResultField::updateSteps() +{ + // Update Array of steps + int aNbSteps = stepsSize(); + if (mySteps.size() != aNbSteps) { + while(mySteps.size() > aNbSteps) { + delete mySteps.back(); + mySteps.pop_back(); + } + while(mySteps.size() < aNbSteps) { + mySteps.push_back(new Model_ResultField::Model_FieldStep(this, mySteps.size())); + } + } +} + +int Model_ResultField::stepsSize() const +{ + if (myOwnerData) { + AttributeIntArrayPtr aArray = myOwnerData->intArray("stamps"); + if (aArray.get()) { + return aArray->size(); + } + } + return 0; +} + +std::string Model_ResultField::textLine(int theLine) const +{ + if (myOwnerData) { + AttributeIntArrayPtr aArray = myOwnerData->intArray("stamps"); + if (aArray.get()) { + if (theLine < aArray->size()) { + std::ostringstream aStream; + aStream << aArray->value(theLine); + return aStream.str(); + } + } + } + return ""; +} + + +ModelAPI_ResultField::ModelAPI_FieldStep* Model_ResultField::step(int theId) const +{ + if (theId < mySteps.size()) { + return mySteps[theId]; + } + return NULL; +} diff --git a/src/Model/Model_ResultField.h b/src/Model/Model_ResultField.h index b8954287e..315484297 100644 --- a/src/Model/Model_ResultField.h +++ b/src/Model/Model_ResultField.h @@ -9,6 +9,7 @@ #include "Model.h" #include +#include /**\class Model_ResultField * \ingroup DataModel @@ -21,6 +22,21 @@ class Model_ResultField : public ModelAPI_ResultField std::shared_ptr myOwnerData; ///< data of owner of this result public: + class Model_FieldStep : public ModelAPI_ResultField::ModelAPI_FieldStep + { + public: + Model_FieldStep(ModelAPI_ResultField* theParent, int theId) + : myParent(theParent), myId(theId) {}; + + virtual ModelAPI_ResultField* field() const { return myParent; } + + virtual int id() const { return myId; } + + private: + ModelAPI_ResultField* myParent; + int myId; + }; + /// Retuns the parameters of color definition in the resources config manager MODEL_EXPORT virtual void colorConfigInfo(std::string& theSection, std::string& theName, std::string& theDefault); @@ -28,14 +44,30 @@ public: /// Returns the compound of selected entities MODEL_EXPORT virtual std::shared_ptr shape(); + /// Returns number of steps + MODEL_EXPORT virtual int stepsSize() const; + + /// Returns a text line by its number + /// \param theLine a number of line + MODEL_EXPORT virtual std::string textLine(int theLine) const; + + /// Returns step object + /// \param theId an id of the object + MODEL_EXPORT virtual ModelAPI_ResultField::ModelAPI_FieldStep* step(int theId) const; + /// Removes the stored builders - MODEL_EXPORT virtual ~Model_ResultField() {} + MODEL_EXPORT virtual ~Model_ResultField(); protected: /// Makes a body on the given feature data Model_ResultField(std::shared_ptr theOwnerData); friend class Model_Objects; + +private: + void updateSteps(); + + std::vector mySteps; }; #endif diff --git a/src/ModelAPI/ModelAPI_Entity.h b/src/ModelAPI/ModelAPI_Entity.h index 5f97f6edd..e66c6f1c5 100644 --- a/src/ModelAPI/ModelAPI_Entity.h +++ b/src/ModelAPI/ModelAPI_Entity.h @@ -7,6 +7,8 @@ #ifndef ModelAPI_Entity_H_ #define ModelAPI_Entity_H_ +#include + /**\class ModelAPI_Entity * \ingroup DataModel * \brief Represents a common parent class for Objects and documents. @@ -20,4 +22,7 @@ public: virtual void emptyFunction() const {} }; +typedef std::shared_ptr EntityPtr; + + #endif \ No newline at end of file diff --git a/src/ModelAPI/ModelAPI_ResultField.h b/src/ModelAPI/ModelAPI_ResultField.h index 65888b555..1d4105b81 100644 --- a/src/ModelAPI/ModelAPI_ResultField.h +++ b/src/ModelAPI/ModelAPI_ResultField.h @@ -21,6 +21,15 @@ class ModelAPI_ResultField : public ModelAPI_Result { public: + + class ModelAPI_FieldStep : public ModelAPI_Entity + { + public: + virtual ModelAPI_ResultField* field() const = 0; + + virtual int id() const = 0; + }; + MODELAPI_EXPORT virtual ~ModelAPI_ResultField(); /// Returns the group identifier of this result MODELAPI_EXPORT virtual std::string groupName(); @@ -39,9 +48,20 @@ public: return RESULT_GROUP_COLOR; } + /// Returns number of steps + virtual int stepsSize() const = 0; + + /// Returns a text line by its number + /// \param theLine a number of line + virtual std::string textLine(int theLine) const = 0; + + /// Returns step object + /// \param theId an id of the object + virtual ModelAPI_FieldStep* step(int theId) const = 0; }; //! Pointer on feature object typedef std::shared_ptr ResultFieldPtr; +typedef std::shared_ptr FieldStepPtr; #endif diff --git a/src/XGUI/XGUI_DataModel.cpp b/src/XGUI/XGUI_DataModel.cpp index 35ffdc34d..ccc24dfb5 100644 --- a/src/XGUI/XGUI_DataModel.cpp +++ b/src/XGUI/XGUI_DataModel.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -36,6 +37,7 @@ #define SELECTABLE_COLOR QColor(80, 80, 80) #define DISABLED_COLOR QColor(200, 200, 200) + ResultPartPtr getPartResult(ModelAPI_Object* theObj) { ModelAPI_Feature* aFeature = dynamic_cast(theObj); @@ -251,9 +253,18 @@ void XGUI_DataModel::processEvent(const std::shared_ptr& theMess 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); + removeRows(0, aResult->stepsSize(), aIndex); + } else { + QModelIndex aIndex = objectIndex(aObject); + if (aIndex.isValid()) { + emit dataChanged(aIndex, aIndex); + } } } else { rebuildDataTree(); @@ -322,7 +333,10 @@ 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 = + dynamic_cast((ModelAPI_Entity*)theIndex.internalPointer()); + if (!aObj) + return ObjectPtr(); if (getSubDocument(aObj)) // the selected index is a folder of sub-document return ObjectPtr(); @@ -437,30 +451,47 @@ 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; + ModelAPI_Object* aObj = + dynamic_cast((ModelAPI_Entity*)theIndex.internalPointer()); + if (aObj) { + switch (theRole) { + case Qt::DisplayRole: + { + if (aObj->groupName() == ModelAPI_ResultParameter::group()) { + ModelAPI_ResultParameter* aParam = dynamic_cast(aObj); + AttributeDoublePtr aValueAttribute = + aParam->data()->real(ModelAPI_ResultParameter::VALUE()); + QString aVal = QString::number(aValueAttribute->value()); + QString aTitle = QString(aObj->data()->name().c_str()); + return aTitle + " = " + aVal; + } + QString aSuffix; + if (aObj->groupName() == myXMLReader->subType()) { + ResultPartPtr aPartRes = getPartResult(aObj); + if (aPartRes.get()) { + if (aPartRes->partDoc().get() == NULL) + aSuffix = " (Not loaded)"; + } + } + return aObj->data()->name().c_str() + aSuffix; } - QString aSuffix; - if (aObj->groupName() == myXMLReader->subType()) { - ResultPartPtr aPartRes = getPartResult(aObj); - if (aPartRes.get()) { - if (aPartRes->partDoc().get() == NULL) - aSuffix = " (Not loaded)"; + case Qt::DecorationRole: + return ModuleBase_IconFactory::get()->getIcon(object(theIndex)); + } + } else { + switch (theRole) { + case Qt::DisplayRole: + { + ModelAPI_ResultField::ModelAPI_FieldStep* aStep = + dynamic_cast + ((ModelAPI_Entity*)theIndex.internalPointer()); + if (aStep) { + return "Step " + QString::number(aStep->id()) + " " + + 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)); } } } @@ -511,7 +542,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()) { @@ -533,6 +565,9 @@ 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(); } } } @@ -591,7 +626,8 @@ QModelIndex XGUI_DataModel::index(int theRow, int theColumn, const QModelIndex & } } } 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); @@ -617,6 +653,13 @@ QModelIndex XGUI_DataModel::index(int theRow, int theColumn, const QModelIndex & dynamic_cast(aParentObj); if (aCompRes) aIndex = objectIndex(aCompRes->subResult(theRow)); + else { + ModelAPI_ResultField* aFieldRes = + dynamic_cast(aParentObj); + if (aFieldRes) { + aIndex = createIndex(theRow, 0, aFieldRes->step(theRow)); + } + } } } } @@ -637,6 +680,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 +690,20 @@ QModelIndex XGUI_DataModel::parent(const QModelIndex& theIndex) const } ObjectPtr aObj = object(theIndex); if (!aObj.get()) { + // It can b e a step of a field + ModelAPI_ResultField::ModelAPI_FieldStep* aStep = + dynamic_cast + ((ModelAPI_Entity*)theIndex.internalPointer()); + if (aStep) { + ModelAPI_ResultField* aField = aStep->field(); + DocumentPtr aDoc = aSession->activeDocument(); + ObjectPtr aFld; + for(int i = 0; i < aDoc->size(ModelAPI_ResultField::group()); i++) { + aFld = aDoc->object(ModelAPI_ResultField::group(), i); + if (aFld.get() == aField) + return objectIndex(aFld); + } + } // To avoid additional request about index which was already deleted // If deleted it causes a crash on delete object from Part MYLastDeleted = theIndex; @@ -668,7 +726,6 @@ 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) { @@ -739,7 +796,7 @@ 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) { -- 2.39.2