1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
3 // File: ModuleBase_WidgetShapeSelector.h
4 // Created: 2 June 2014
5 // Author: Vitaly Smetannikov
7 #include <ModuleBase_WidgetShapeSelector.h>
8 #include <ModuleBase_Definitions.h>
9 #include <ModuleBase_ISelection.h>
10 #include <ModuleBase_IWorkshop.h>
11 #include <ModuleBase_IViewer.h>
12 #include <ModuleBase_Tools.h>
13 #include <ModuleBase_FilterFactory.h>
14 #include <ModuleBase_Filter.h>
16 #include <Config_WidgetAPI.h>
17 #include <Events_Loop.h>
18 #include <Events_Message.h>
19 #include <GeomAPI_Interface.h>
20 #include <GeomAPI_Shape.h>
21 #include <GeomValidators_Tools.h>
23 #include <ModelAPI_AttributeReference.h>
24 #include <ModelAPI_Data.h>
25 #include <ModelAPI_Document.h>
26 #include <ModelAPI_Events.h>
27 #include <ModelAPI_Feature.h>
28 #include <ModelAPI_Result.h>
29 #include <ModelAPI_ResultConstruction.h>
30 #include <ModelAPI_AttributeReference.h>
31 #include <ModelAPI_AttributeSelection.h>
32 #include <ModelAPI_Session.h>
33 #include <ModelAPI_Tools.h>
34 #include <ModelAPI_ResultBody.h>
35 #include <ModelAPI_AttributeRefAttr.h>
36 #include <ModelAPI_Validator.h>
37 #include <ModelAPI_AttributeValidator.h>
38 #include <ModelAPI_ShapeValidator.h>
40 #include <Config_WidgetAPI.h>
41 #include <Events_Error.h>
43 #include <GeomAPI_Shape.h>
45 #include <SelectMgr_ListIteratorOfListOfFilter.hxx>
46 #include <TopoDS_Shape.hxx>
47 #include <TopExp_Explorer.hxx>
53 #include <QToolButton>
56 #include <QDockWidget>
57 #include <QApplication>
58 #include <QFormLayout>
60 #include <TopExp_Explorer.hxx>
61 #include <TopoDS_Shape.hxx>
69 ModuleBase_WidgetShapeSelector::ModuleBase_WidgetShapeSelector(QWidget* theParent,
70 ModuleBase_IWorkshop* theWorkshop,
71 const Config_WidgetAPI* theData,
72 const std::string& theParentId)
73 : ModuleBase_WidgetValidated(theParent, theData, theParentId),
74 myWorkshop(theWorkshop)
76 QFormLayout* aLayout = new QFormLayout(this);
77 ModuleBase_Tools::adjustMargins(aLayout);
79 QString aLabelText = QString::fromStdString(theData->widgetLabel());
80 QString aLabelIcon = QString::fromStdString(theData->widgetIcon());
81 myLabel = new QLabel(aLabelText, this);
82 if (!aLabelIcon.isEmpty())
83 myLabel->setPixmap(QPixmap(aLabelIcon));
86 QString aToolTip = QString::fromStdString(theData->widgetTooltip());
87 myTextLine = new QLineEdit(this);
88 myTextLine->setReadOnly(true);
89 myTextLine->setToolTip(aToolTip);
90 myTextLine->installEventFilter(this);
92 aLayout->addRow(myLabel, myTextLine);
94 std::string aTypes = theData->getProperty("shape_types");
95 myShapeTypes = QString(aTypes.c_str()).split(' ', QString::SkipEmptyParts);
98 //********************************************************************
99 ModuleBase_WidgetShapeSelector::~ModuleBase_WidgetShapeSelector()
101 activateSelection(false);
102 activateFilters(myWorkshop, false);
105 //********************************************************************
106 bool ModuleBase_WidgetShapeSelector::storeValueCustom() const
108 // the value is stored on the selection changed signal processing
112 //********************************************************************
113 bool ModuleBase_WidgetShapeSelector::setObject(ObjectPtr theSelectedObject,
114 GeomShapePtr theShape)
116 bool isChanged = false;
117 FeaturePtr aSelectedFeature = ModelAPI_Feature::feature(theSelectedObject);
118 if (aSelectedFeature == myFeature) // In order to avoid selection of the same object
121 DataPtr aData = myFeature->data();
122 AttributeReferencePtr aRef = aData->reference(attributeID());
124 ObjectPtr aObject = aRef->value();
125 if (!(aObject && aObject->isSame(theSelectedObject))) {
126 aRef->setValue(theSelectedObject);
130 AttributeRefAttrPtr aRefAttr = aData->refattr(attributeID());
132 ObjectPtr aObject = aRefAttr->object();
133 if (!(aObject && aObject->isSame(theSelectedObject))) {
134 aRefAttr->setObject(theSelectedObject);
138 AttributeSelectionPtr aSelectAttr = aData->selection(attributeID());
139 ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(theSelectedObject);
140 if (aSelectAttr.get() != NULL) {
141 aSelectAttr->setValue(aResult, theShape);
149 //********************************************************************
150 QList<ModuleBase_ViewerPrs> ModuleBase_WidgetShapeSelector::getAttributeSelection() const
152 QList<ModuleBase_ViewerPrs> aSelected;
154 DataPtr aData = myFeature->data();
155 AttributePtr anAttribute = myFeature->attribute(attributeID());
157 ObjectPtr anObject = GeomValidators_Tools::getObject(anAttribute);
159 std::shared_ptr<GeomAPI_Shape> aShapePtr = getShape();
160 if (aShapePtr.get()) {
161 aShape = aShapePtr->impl<TopoDS_Shape>();
163 ModuleBase_ViewerPrs aPrs(anObject, aShape, NULL);
164 aSelected.append(aPrs);
169 //********************************************************************
170 void ModuleBase_WidgetShapeSelector::clearAttribute()
172 DataPtr aData = myFeature->data();
173 AttributeSelectionPtr aSelect = aData->selection(attributeID());
175 aSelect->setValue(ResultPtr(), std::shared_ptr<GeomAPI_Shape>(new GeomAPI_Shape()));
178 AttributeRefAttrPtr aRefAttr = aData->refattr(attributeID());
180 aRefAttr->setObject(ObjectPtr());
183 AttributeReferencePtr aRef = aData->reference(attributeID());
185 aRef->setObject(ObjectPtr());
189 //********************************************************************
190 bool ModuleBase_WidgetShapeSelector::restoreValue()
192 bool isBlocked = this->blockSignals(true);
193 updateSelectionName();
194 this->blockSignals(isBlocked);
199 //********************************************************************
200 QList<QWidget*> ModuleBase_WidgetShapeSelector::getControls() const
202 QList<QWidget*> aControls;
203 aControls.append(myTextLine);
207 //********************************************************************
208 void ModuleBase_WidgetShapeSelector::onSelectionChanged()
210 // In order to make reselection possible, set empty object and shape should be done
211 setObject(ObjectPtr(), std::shared_ptr<GeomAPI_Shape>(new GeomAPI_Shape()));
213 bool aHasObject = false;
214 QList<ModuleBase_ViewerPrs> aSelectedPrs = getSelectedEntitiesOrObjects(myWorkshop->selection());
215 if (!aSelectedPrs.empty()) {
216 ModuleBase_ViewerPrs aPrs = aSelectedPrs.first();
217 if (!aPrs.isEmpty() && isValidSelection(aPrs)) {
218 setSelectionCustom(aPrs);
222 // the updateObject method should be called to flush the updated sigal. The workshop listens it,
223 // calls validators for the feature and, as a result, updates the Apply button state.
224 updateObject(myFeature);
225 // the widget loses the focus only if the selected object is set
227 emit focusOutWidget(this);
230 //********************************************************************
231 bool ModuleBase_WidgetShapeSelector::acceptSubShape(std::shared_ptr<GeomAPI_Shape> theShape) const
233 TopoDS_Shape aShape = theShape->impl<TopoDS_Shape>();
234 foreach (QString aType, myShapeTypes) {
235 if (aShape.ShapeType() == ModuleBase_Tools::shapeType(aType))
241 //********************************************************************
242 GeomShapePtr ModuleBase_WidgetShapeSelector::getShape() const
245 DataPtr aData = myFeature->data();
246 if (aData.get() == NULL)
249 AttributeSelectionPtr aSelect = aData->selection(attributeID());
251 aShape = aSelect->value();
256 //********************************************************************
257 void ModuleBase_WidgetShapeSelector::updateSelectionName()
259 DataPtr aData = myFeature->data();
260 if (aData.get() == NULL)
263 bool isNameUpdated = false;
264 AttributeSelectionPtr aSelect = aData->selection(attributeID());
266 myTextLine->setText(QString::fromStdString(aSelect->namingName()));
267 isNameUpdated = true;
269 if (!isNameUpdated) {
270 ObjectPtr anObject = GeomValidators_Tools::getObject(myFeature->attribute(attributeID()));
271 if (anObject.get() != NULL) {
272 std::string aName = anObject->data()->name();
273 myTextLine->setText(QString::fromStdString(aName));
275 AttributeRefAttrPtr aRefAttr = aData->refattr(attributeID());
276 if (aRefAttr && aRefAttr->attr().get() != NULL) {
277 //myIsObject = aRefAttr->isObject();
278 AttributePtr anAttr = aRefAttr->attr();
279 if (anAttr.get() != NULL) {
280 std::stringstream aName;
281 aName <<anAttr->owner()->data()->name()<<"/"<<anAttr->id();
282 myTextLine->setText(QString::fromStdString(aName.str()));
286 myTextLine->setText("");
293 //********************************************************************
294 void ModuleBase_WidgetShapeSelector::activateSelection(bool toActivate)
296 updateSelectionName();
300 foreach (QString aType, myShapeTypes) {
301 aList.append(ModuleBase_Tools::shapeType(aType));
303 myWorkshop->activateSubShapesSelection(aList);
305 myWorkshop->deactivateSubShapesSelection();
309 //********************************************************************
310 void ModuleBase_WidgetShapeSelector::raisePanel() const
312 QWidget* aParent = this->parentWidget();
313 QWidget* aLastPanel = 0;
314 while (!aParent->inherits("QDockWidget")) {
315 aLastPanel = aParent;
316 aParent = aParent->parentWidget();
320 if (aParent->inherits("QDockWidget")) {
321 QDockWidget* aTabWgt = (QDockWidget*) aParent;
326 //********************************************************************
327 void ModuleBase_WidgetShapeSelector::activateCustom()
329 connect(myWorkshop, SIGNAL(selectionChanged()), this, SLOT(onSelectionChanged()));
330 activateSelection(true);
332 // Restore selection in the viewer by the attribute selection list
333 myWorkshop->setSelected(getAttributeSelection());
335 activateFilters(myWorkshop, true);
338 //********************************************************************
339 void ModuleBase_WidgetShapeSelector::storeAttributeValue()
341 DataPtr aData = myFeature->data();
342 AttributePtr anAttribute = myFeature->attribute(attributeID());
344 myObject = GeomValidators_Tools::getObject(anAttribute);
345 myShape = getShape();
346 myRefAttribute = AttributePtr();
348 AttributeRefAttrPtr aRefAttr = aData->refattr(attributeID());
350 myIsObject = aRefAttr->isObject();
351 myRefAttribute = aRefAttr->attr();
355 //********************************************************************
356 void ModuleBase_WidgetShapeSelector::restoreAttributeValue(bool theValid)
358 DataPtr aData = myFeature->data();
359 AttributePtr anAttribute = myFeature->attribute(attributeID());
361 setObject(myObject, myShape);
362 AttributeRefAttrPtr aRefAttr = aData->refattr(attributeID());
365 aRefAttr->setAttr(myRefAttribute);
369 //********************************************************************
370 bool ModuleBase_WidgetShapeSelector::setSelectionCustom(const ModuleBase_ViewerPrs& thePrs)
374 // It should be checked by corresponded validator
375 ObjectPtr aObject = thePrs.object();
376 ObjectPtr aCurrentObject = GeomValidators_Tools::getObject(myFeature->attribute(attributeID()));
378 if ((!aCurrentObject) && (!aObject))
381 // It should be checked by corresponded validator
382 // Check that the selected object is result (others can not be accepted)
383 ResultPtr aRes = std::dynamic_pointer_cast<ModelAPI_Result>(aObject);
387 // We can not select a result of our feature
388 const std::list<std::shared_ptr<ModelAPI_Result>>& aResList = myFeature->results();
389 std::list<std::shared_ptr<ModelAPI_Result> >::const_iterator aIt;
390 for (aIt = aResList.cbegin(); aIt != aResList.cend(); ++aIt) {
396 // It should be checked by corresponded validator
398 // Check that object belongs to active document or PartSet
399 DocumentPtr aDoc = aRes->document();
400 SessionPtr aMgr = ModelAPI_Session::get();
401 if (!(aDoc == aMgr->activeDocument()) && !(aDoc == aMgr->moduleDocument()))
404 // It should be checked by corresponded validator
405 // Check that the result has a shape
406 GeomShapePtr aShape = ModelAPI_Tools::shape(aRes);
410 // Get sub-shapes from local selection
411 if (!thePrs.shape().IsNull()) {
412 aShape = std::shared_ptr<GeomAPI_Shape>(new GeomAPI_Shape());
413 aShape->setImpl(new TopoDS_Shape(thePrs.shape()));
415 // Check that the selection corresponds to selection type
416 if (!acceptSubShape(aShape))
419 setObject(aObject, aShape);
423 //********************************************************************
424 void ModuleBase_WidgetShapeSelector::deactivate()
426 activateSelection(false);
427 activateFilters(myWorkshop, false);
428 disconnect(myWorkshop, SIGNAL(selectionChanged()), this, SLOT(onSelectionChanged()));