From e0a8234ef02c73de150a9685dc4780ddf55022e5 Mon Sep 17 00:00:00 2001 From: nds Date: Tue, 12 Jan 2016 16:13:22 +0300 Subject: [PATCH] Improve multi-selector control to provide width colored presentation of selected items. --- src/ModuleBase/ModuleBase_IModule.cpp | 4 +- src/ModuleBase/ModuleBase_IModule.h | 11 +- src/ModuleBase/ModuleBase_ModelWidget.h | 4 + .../ModuleBase_WidgetMultiSelector.cpp | 106 +++++++++++------- .../ModuleBase_WidgetMultiSelector.h | 19 +++- src/PartSet/PartSet_CustomPrs.cpp | 4 +- src/PartSet/PartSet_CustomPrs.h | 4 +- src/PartSet/PartSet_Module.cpp | 6 +- src/PartSet/PartSet_Module.h | 5 +- src/PartSet/PartSet_OperationPrs.cpp | 42 +++++++ src/XGUI/XGUI_WorkshopListener.cpp | 3 +- 11 files changed, 156 insertions(+), 52 deletions(-) diff --git a/src/ModuleBase/ModuleBase_IModule.cpp b/src/ModuleBase/ModuleBase_IModule.cpp index a4fb01757..76c899161 100644 --- a/src/ModuleBase/ModuleBase_IModule.cpp +++ b/src/ModuleBase/ModuleBase_IModule.cpp @@ -81,7 +81,9 @@ ModuleBase_Operation* ModuleBase_IModule::getNewOperation(const std::string& the return new ModuleBase_OperationFeature(theFeatureId.c_str(), this); } -bool ModuleBase_IModule::customizeObject(ObjectPtr theObject, const bool theUpdateViewer) +bool ModuleBase_IModule::customizeObject(ObjectPtr theObject, + const ModuleBase_IModule::ModuleBase_CustomizeFlag& theFlag, + const bool theUpdateViewer) { return false; } diff --git a/src/ModuleBase/ModuleBase_IModule.h b/src/ModuleBase/ModuleBase_IModule.h index ac7096437..45c895ded 100755 --- a/src/ModuleBase/ModuleBase_IModule.h +++ b/src/ModuleBase/ModuleBase_IModule.h @@ -32,6 +32,12 @@ class MODULEBASE_EXPORT ModuleBase_IModule : public QObject { Q_OBJECT public: + /// enumeration to know which objects should be customized + enum ModuleBase_CustomizeFlag { + CustomizeDependedAndResults = 0x00000000, + CustomizeHighlightedObjects = 0x00000001, + CustomizeAllObjects = CustomizeDependedAndResults | CustomizeHighlightedObjects + }; /// Constructor /// \param theParent instance of workshop interface @@ -158,10 +164,13 @@ class MODULEBASE_EXPORT ModuleBase_IModule : public QObject * If the object is result with the color attribute value set, it is used, * otherwise the customize is applyed to the object's feature if it is a custom prs * \param theObject an object instance + * \param theFlag a flag of level of customization, which means that only part of sub-elements + * should be updated(e.g. only highlighted elements) * \param theUpdateViewer the parameter whether the viewer should be update immediately * \returns true if the object is modified */ - virtual bool customizeObject(ObjectPtr theObject, const bool theUpdateViewer); + virtual bool customizeObject(ObjectPtr theObject, const ModuleBase_CustomizeFlag& theFlag, + const bool theUpdateViewer); /// This method is called on object browser creation for customization of module specific features /// \param theObjectBrowser a pinter on Object Browser widget diff --git a/src/ModuleBase/ModuleBase_ModelWidget.h b/src/ModuleBase/ModuleBase_ModelWidget.h index b08a0a551..9f7c99980 100644 --- a/src/ModuleBase/ModuleBase_ModelWidget.h +++ b/src/ModuleBase/ModuleBase_ModelWidget.h @@ -111,6 +111,10 @@ Q_OBJECT return false; } + /// Returns values which should be highlighted when the whidget is active + /// \param theValues a list of presentations + virtual void getHighlighted(QList& theValues) {}; + /// Restore value from attribute data to the widget's control. Emits signals before and after store /// \return True in success bool restoreValue(); diff --git a/src/ModuleBase/ModuleBase_WidgetMultiSelector.cpp b/src/ModuleBase/ModuleBase_WidgetMultiSelector.cpp index ffc380878..714e4ef7f 100755 --- a/src/ModuleBase/ModuleBase_WidgetMultiSelector.cpp +++ b/src/ModuleBase/ModuleBase_WidgetMultiSelector.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -292,6 +293,15 @@ bool ModuleBase_WidgetMultiSelector::setSelection(QList& t return isDone; } +//******************************************************************** +void ModuleBase_WidgetMultiSelector::getHighlighted(QList& theValues) +{ + std::set anAttributeIds; + getSelectedAttributeIndices(anAttributeIds); + if (!anAttributeIds.empty()) + convertIndicesToViewerSelection(anAttributeIds, theValues); +} + //******************************************************************** bool ModuleBase_WidgetMultiSelector::isValidSelectionCustom(const ModuleBase_ViewerPrs& thePrs) { @@ -395,35 +405,7 @@ void ModuleBase_WidgetMultiSelector::setCurrentShapeType(const TopAbs_ShapeEnum QList ModuleBase_WidgetMultiSelector::getAttributeSelection() const { QList aSelected; - // Restore selection in the viewer by the attribute selection list - if(myFeature) { - AttributeSelectionListPtr aSelectionListAttr = myFeature->data()->selectionList(attributeID()); - if (aSelectionListAttr.get()) { - for (int i = 0; i < aSelectionListAttr->size(); i++) { - AttributeSelectionPtr anAttr = aSelectionListAttr->value(i); - ResultPtr anObject = anAttr->context(); - if (anObject.get()) { - TopoDS_Shape aShape; - std::shared_ptr aShapePtr = anAttr->value(); - if (aShapePtr.get()) { - aShape = aShapePtr->impl(); - } - aSelected.append(ModuleBase_ViewerPrs(anObject, aShape, NULL)); - } - } - } - else { - AttributeRefListPtr aRefListAttr = myFeature->data()->reflist(attributeID()); - if (aRefListAttr.get()) { - for (int i = 0; i < aRefListAttr->size(); i++) { - ObjectPtr anObject = aRefListAttr->object(i); - if (anObject.get()) { - aSelected.append(ModuleBase_ViewerPrs(anObject, TopoDS_Shape(), NULL)); - } - } - } - } - } + convertIndicesToViewerSelection(std::set(), aSelected); return aSelected; } @@ -494,13 +476,9 @@ void ModuleBase_WidgetMultiSelector::onCopyItem() void ModuleBase_WidgetMultiSelector::onDeleteItem() { // find attribute indices to delete - QList aItems = myListControl->selectedItems(); std::set anAttributeIds; - foreach(QListWidgetItem* anItem, aItems) { - int anIndex = anItem->data(ATTRIBUTE_SELECTION_INDEX_ROLE).toInt(); - if (anAttributeIds.find(anIndex) == anAttributeIds.end()) - anAttributeIds.insert(anIndex); - } + getSelectedAttributeIndices(anAttributeIds); + // refill attribute by the items which indices are not in the list of ids bool aDone = false; AttributeSelectionListPtr aSelectionListAttr = myFeature->data()->selectionList(attributeID()); @@ -518,6 +496,8 @@ void ModuleBase_WidgetMultiSelector::onDeleteItem() if (aDone) { restoreValue(); myWorkshop->setSelected(getAttributeSelection()); + + myWorkshop->module()->customizeObject(myFeature, ModuleBase_IModule::CustomizeAllObjects, true); } } @@ -527,9 +507,57 @@ void ModuleBase_WidgetMultiSelector::onListSelection() QList aItems = myListControl->selectedItems(); myCopyAction->setEnabled(!aItems.isEmpty()); myDeleteAction->setEnabled(!aItems.isEmpty()); - - //myWorkshop->setSelected(>setSelected(getAttributeSelection()); - QList aSelectedItems; - emit itemsSelected(aSelectedItems); + myWorkshop->module()->customizeObject(myFeature, ModuleBase_IModule::CustomizeHighlightedObjects, + true); +} + +//******************************************************************** +void ModuleBase_WidgetMultiSelector::getSelectedAttributeIndices(std::set& theAttributeIds) +{ + QList aItems = myListControl->selectedItems(); + foreach(QListWidgetItem* anItem, aItems) { + int anIndex = anItem->data(ATTRIBUTE_SELECTION_INDEX_ROLE).toInt(); + if (theAttributeIds.find(anIndex) == theAttributeIds.end()) + theAttributeIds.insert(anIndex); + } +} + +void ModuleBase_WidgetMultiSelector::convertIndicesToViewerSelection(std::set theAttributeIds, + QList& theValues) const +{ + if(myFeature.get() == NULL) + return; + AttributeSelectionListPtr aSelectionListAttr = myFeature->data()->selectionList(attributeID()); + if (aSelectionListAttr.get()) { + for (int i = 0; i < aSelectionListAttr->size(); i++) { + // filter by attribute indices only if the container is not empty otherwise return all items + if (!theAttributeIds.empty() && theAttributeIds.find(i) == theAttributeIds.end()) + continue; + AttributeSelectionPtr anAttr = aSelectionListAttr->value(i); + ResultPtr anObject = anAttr->context(); + if (anObject.get()) { + TopoDS_Shape aShape; + std::shared_ptr aShapePtr = anAttr->value(); + if (aShapePtr.get()) { + aShape = aShapePtr->impl(); + } + theValues.append(ModuleBase_ViewerPrs(anObject, aShape, NULL)); + } + } + } + else { + AttributeRefListPtr aRefListAttr = myFeature->data()->reflist(attributeID()); + if (aRefListAttr.get()) { + for (int i = 0; i < aRefListAttr->size(); i++) { + // filter by attribute indices only if the container is not empty otherwise return all items + if (!theAttributeIds.empty() && theAttributeIds.find(i) == theAttributeIds.end()) + continue; + ObjectPtr anObject = aRefListAttr->object(i); + if (anObject.get()) { + theValues.append(ModuleBase_ViewerPrs(anObject, TopoDS_Shape(), NULL)); + } + } + } + } } diff --git a/src/ModuleBase/ModuleBase_WidgetMultiSelector.h b/src/ModuleBase/ModuleBase_WidgetMultiSelector.h index 49dbc1a7c..bebc59c91 100755 --- a/src/ModuleBase/ModuleBase_WidgetMultiSelector.h +++ b/src/ModuleBase/ModuleBase_WidgetMultiSelector.h @@ -72,6 +72,10 @@ class MODULEBASE_EXPORT ModuleBase_WidgetMultiSelector : public ModuleBase_Widge virtual bool setSelection(QList& theValues, const bool theToValidate); + /// Returns values which should be highlighted when the whidget is active + /// \param theValues a list of presentations + virtual void getHighlighted(QList& theValues); + /// Checks the widget validity. By default, it returns true. /// \param thePrs a selected presentation in the view /// \return a boolean value @@ -81,10 +85,6 @@ class MODULEBASE_EXPORT ModuleBase_WidgetMultiSelector : public ModuleBase_Widge /// Slot is called on selection type changed void onSelectionTypeChanged(); -signals: - /// Signals about items selected in the list view - void itemsSelected(const QList& theItems); - protected slots: /// Slot for copy command in a list pop-up menu void onCopyItem(); @@ -148,6 +148,17 @@ protected: /// For example, the "Edges" is converted to "edge" std::string validatorType(const QString& theType) const; +protected: + /// Returns attribute indices selected in the widget selection list + /// \param theIndices a list of indices + void getSelectedAttributeIndices(std::set& theIndices); + + /// Gets the feature attribute and fill a list of viewer presentation for the attribute + /// indices. If the the container of indices is empty, it returns all objects. + /// \param theAttributeIds indices in attribute list to be returned + /// \param theValues the result presentations, filled with object and shape of an attribute item + void convertIndicesToViewerSelection(std::set theAttributeIds, + QList& theValues) const; protected: /// List control QListWidget* myListControl; diff --git a/src/PartSet/PartSet_CustomPrs.cpp b/src/PartSet/PartSet_CustomPrs.cpp index b2315bffb..ed43e19bd 100755 --- a/src/PartSet/PartSet_CustomPrs.cpp +++ b/src/PartSet/PartSet_CustomPrs.cpp @@ -116,7 +116,9 @@ Handle(PartSet_OperationPrs) PartSet_CustomPrs::getPresentation() return Handle(PartSet_OperationPrs)::DownCast(anAISIO); } -bool PartSet_CustomPrs::redisplay(const ObjectPtr& theObject, const bool theUpdateViewer) +bool PartSet_CustomPrs::redisplay(const ObjectPtr& theObject, + const ModuleBase_IModule::ModuleBase_CustomizeFlag& theFlag, + const bool theUpdateViewer) { #ifdef DO_NOT_VISUALIZE_CUSTOM_PRESENTATION return false; diff --git a/src/PartSet/PartSet_CustomPrs.h b/src/PartSet/PartSet_CustomPrs.h index c12768e0e..1d12d6802 100755 --- a/src/PartSet/PartSet_CustomPrs.h +++ b/src/PartSet/PartSet_CustomPrs.h @@ -11,6 +11,7 @@ #include "PartSet_OperationPrs.h" +#include #include #include #include @@ -53,7 +54,8 @@ public: /// \param theObject an object to redisplay /// \param theUpdateViewer the parameter whether the viewer should be update immediatelly /// \returns true if the presentation is redisplayed - bool redisplay(const ObjectPtr& theObject, const bool theUpdateViewer); + bool redisplay(const ObjectPtr& theObject, + const ModuleBase_IModule::ModuleBase_CustomizeFlag& theFlag, const bool theUpdateViewer); /// Nullify the operation presentation. For example, it can be useful when the viewer/context /// is closed. If this is not performed and the presentation is assigned in another context, diff --git a/src/PartSet/PartSet_Module.cpp b/src/PartSet/PartSet_Module.cpp index 93a810750..5baf6b713 100755 --- a/src/PartSet/PartSet_Module.cpp +++ b/src/PartSet/PartSet_Module.cpp @@ -131,7 +131,6 @@ PartSet_Module::PartSet_Module(ModuleBase_IWorkshop* theWshop) SLOT(onViewTransformed(int))); connect(aViewer, SIGNAL(viewCreated(ModuleBase_IViewWindow*)), SLOT(onViewCreated(ModuleBase_IViewWindow*))); - myMenuMgr = new PartSet_MenuMgr(this); myCustomPrs = new PartSet_CustomPrs(theWshop); @@ -729,11 +728,12 @@ void PartSet_Module::onViewTransformed(int theTrsfType) aDisplayer->updateViewer(); } -bool PartSet_Module::customizeObject(ObjectPtr theObject, const bool theUpdateViewer) +bool PartSet_Module::customizeObject(ObjectPtr theObject, const ModuleBase_CustomizeFlag& theFlag, + const bool theUpdateViewer) { bool isRedisplayed = false; if (myCustomPrs->isActive()) - isRedisplayed = myCustomPrs->redisplay(theObject, theUpdateViewer); + isRedisplayed = myCustomPrs->redisplay(theObject, theFlag, theUpdateViewer); return isRedisplayed; } diff --git a/src/PartSet/PartSet_Module.h b/src/PartSet/PartSet_Module.h index f074786d3..956d09544 100755 --- a/src/PartSet/PartSet_Module.h +++ b/src/PartSet/PartSet_Module.h @@ -184,10 +184,13 @@ public: * If the object is result with the color attribute value set, it is used, * otherwise the customize is applyed to the object's feature if it is a custom prs * \param theObject an object instance + * \param theFlag a flag of level of customization, which means that only part of sub-elements + * should be updated(e.g. only highlighted elements) * \param theUpdateViewer the parameter whether the viewer should be update immediatelly * \returns true if the object is modified */ - virtual bool customizeObject(ObjectPtr theObject, const bool theUpdateViewer); + virtual bool customizeObject(ObjectPtr theObject, const ModuleBase_CustomizeFlag& theFlag, + const bool theUpdateViewer); /// This method is called on object browser creation for customisation of module specific features /// \param theObjectBrowser a pinter on Object Browser widget diff --git a/src/PartSet/PartSet_OperationPrs.cpp b/src/PartSet/PartSet_OperationPrs.cpp index 5252aac48..9b41b2eff 100755 --- a/src/PartSet/PartSet_OperationPrs.cpp +++ b/src/PartSet/PartSet_OperationPrs.cpp @@ -79,6 +79,8 @@ bool PartSet_OperationPrs::hasShapes() return !myFeatureShapes.empty() || !myFeatureResults.empty(); } +#include +#include void PartSet_OperationPrs::Compute(const Handle(PrsMgr_PresentationManager3d)& thePresentationManager, const Handle(Prs3d_Presentation)& thePresentation, const Standard_Integer theMode) @@ -98,6 +100,7 @@ void PartSet_OperationPrs::Compute(const Handle(PrsMgr_PresentationManager3d)& t // create presentations on the base of the shapes Handle(Prs3d_Drawer) aDrawer = Attributes(); + QMap >::const_iterator anIt = myFeatureShapes.begin(), aLast = myFeatureShapes.end(); for (; anIt != aLast; anIt++) { @@ -134,6 +137,45 @@ void PartSet_OperationPrs::Compute(const Handle(PrsMgr_PresentationManager3d)& t ModuleBase_Tools::setDefaultDeviationCoefficient(aShape, aDrawer); StdPrs_WFDeflectionShape::Add(thePresentation, aShape, aDrawer); } + QList aValues; + ModuleBase_IPropertyPanel* aPanel = myWorkshop->propertyPanel(); + if (aPanel) { + ModuleBase_ModelWidget* aWidget = aPanel->activeWidget(); + if (aWidget) { + aWidget->getHighlighted(aValues); + } + } + + Standard_Real aPreviousWidth = Width(); + setWidth(aDrawer, aPreviousWidth+3); + Handle(AIS_InteractiveContext) aContext = GetContext(); + Quantity_NameOfColor anHColor = aContext->HilightColor(); + + aColor = Quantity_Color(anHColor); + aColor = Quantity_Color((1. + aColor.Red())/2., (1. + aColor.Green())/2., + (1. + aColor.Blue())/2., Quantity_TOC_RGB); + SetColor(aColor); + + QList::const_iterator anIIt = aValues.begin(), + aILast = aValues.end(); + for (; anIIt != aILast; anIIt++) { + ModuleBase_ViewerPrs aPrs = *anIIt; + ObjectPtr anObject = aPrs.object(); + TopoDS_Shape aShape = aPrs.shape(); + if (aShape.IsNull()) { + ResultPtr aResult = std::dynamic_pointer_cast(anObject); + if (aResult.get()) { + GeomShapePtr aGeomShape = aResult->shape(); + if (aGeomShape.get()) + aShape = aGeomShape->impl(); + } + } + if (!aShape.IsNull()) { + ModuleBase_Tools::setDefaultDeviationCoefficient(aShape, aDrawer); + StdPrs_WFDeflectionShape::Add(thePresentation, aShape, aDrawer); + } + } + setWidth(aDrawer, aPreviousWidth); } void PartSet_OperationPrs::ComputeSelection(const Handle(SelectMgr_Selection)& aSelection, diff --git a/src/XGUI/XGUI_WorkshopListener.cpp b/src/XGUI/XGUI_WorkshopListener.cpp index d44633033..457d41216 100755 --- a/src/XGUI/XGUI_WorkshopListener.cpp +++ b/src/XGUI/XGUI_WorkshopListener.cpp @@ -571,7 +571,8 @@ bool XGUI_WorkshopListener::customizeCurrentObject() if (aFOperation) { FeaturePtr aCurrentFeature = aFOperation->feature(); if (aCurrentFeature.get()) - aCustomized = myWorkshop->module()->customizeObject(aCurrentFeature, false); + aCustomized = myWorkshop->module()->customizeObject(aCurrentFeature, + ModuleBase_IModule::CustomizeAllObjects, false); } } return aCustomized; -- 2.39.2