1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
3 // File: PartSet_WidgetSketchCreator.cpp
4 // Created: 08 June 2015
5 // Author: Vitaly SMETANNIKOV
7 #include "PartSet_WidgetSketchCreator.h"
8 #include "PartSet_Module.h"
10 #include <Config_Keywords.h>
12 #include <XGUI_ModuleConnector.h>
13 #include <XGUI_Workshop.h>
14 #include <XGUI_Displayer.h>
15 #include <XGUI_SelectionMgr.h>
16 #include <XGUI_OperationMgr.h>
17 #include <XGUI_PropertyPanel.h>
19 #include <GeomAPI_Face.h>
21 #include <ModelAPI_Session.h>
22 #include <ModelAPI_ResultBody.h>
23 #include <ModelAPI_AttributeSelection.h>
24 #include <ModelAPI_AttributeSelectionList.h>
25 #include <ModelAPI_Validator.h>
26 #include <ModelAPI_Events.h>
28 #include <SketchPlugin_SketchEntity.h>
29 #include <FeaturesPlugin_CompositeBoolean.h>
31 #include <ModuleBase_Tools.h>
32 #include <ModuleBase_Operation.h>
33 #include <ModuleBase_IPropertyPanel.h>
34 #include <ModuleBase_OperationFeature.h>
35 #include <Config_WidgetAPI.h>
37 #include <Events_Loop.h>
41 //#include <QFormLayout>
42 #include <QVBoxLayout>
43 #include <QMessageBox>
45 PartSet_WidgetSketchCreator::PartSet_WidgetSketchCreator(QWidget* theParent,
46 PartSet_Module* theModule,
47 const Config_WidgetAPI* theData)
48 : ModuleBase_WidgetSelector(theParent, theModule->workshop(), theData),
49 myModule(theModule), myUseBody(true)
51 myAttributeListID = theData->getProperty("attribute_list_id");
53 //QFormLayout* aLayout = new QFormLayout(this);
54 QVBoxLayout* aLayout = new QVBoxLayout(this);
55 ModuleBase_Tools::zeroMargins(aLayout);
57 ModuleBase_Tools::adjustMargins(aLayout);
59 QString aLabelText = QString::fromStdString(theData->widgetLabel());
60 QString aLabelIcon = QString::fromStdString(theData->widgetIcon());
62 myLabel = new QLabel(aLabelText, this);
63 myLabel->setWordWrap(true);
64 aLayout->addWidget(myLabel);
65 /*if (!aLabelIcon.isEmpty())
66 myLabel->setPixmap(QPixmap(aLabelIcon));
69 QString aToolTip = QString::fromStdString(theData->widgetTooltip());
70 myTextLine = new QLineEdit(this);
71 myTextLine->setReadOnly(true);
72 myTextLine->setToolTip(aToolTip);
73 myTextLine->installEventFilter(this);
75 myLabel->setToolTip(aToolTip);
77 QString aUseBody = QString::fromStdString(theData->getProperty(USE_BODY));
78 if(!aUseBody.isEmpty()) {
79 myUseBody = QVariant(aUseBody).toBool();
82 aLayout->addRow(myLabel, myTextLine);*/
84 std::string aTypes = theData->getProperty("shape_types");
85 myShapeTypes = QString(aTypes.c_str()).split(' ', QString::SkipEmptyParts);
88 PartSet_WidgetSketchCreator::~PartSet_WidgetSketchCreator()
92 QList<QWidget*> PartSet_WidgetSketchCreator::getControls() const
94 QList<QWidget*> aControls;
95 aControls.append(myLabel);
99 bool PartSet_WidgetSketchCreator::restoreValueCustom()
101 /*CompositeFeaturePtr aCompFeature =
102 std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(myFeature);
103 if (aCompFeature->numberOfSubs() > 0) {
104 FeaturePtr aSubFeature = aCompFeature->subFeature(0);
105 myTextLine->setText(QString::fromStdString(aSubFeature->data()->name()));
110 bool PartSet_WidgetSketchCreator::storeValueCustom() const
115 void PartSet_WidgetSketchCreator::activateCustom()
117 if (isSelectionMode()) {
118 ModuleBase_WidgetSelector::activateCustom();
119 //connect(myModule, SIGNAL(operationLaunched()), SLOT(onStarted()));
121 //setVisibleSelectionControl(true);
124 // setVisibleSelectionControl(false);
125 // emit focusOutWidget(this);
129 void PartSet_WidgetSketchCreator::setVisibleSelectionControl(const bool theSelectionControl)
131 // hide current widget, activate the next widget
132 XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(myModule->workshop());
133 XGUI_Workshop* aWorkshop = aConnector->workshop();
134 XGUI_PropertyPanel* aPanel = aWorkshop->propertyPanel();
135 const QList<ModuleBase_ModelWidget*>& aWidgets = aPanel->modelWidgets();
136 foreach(ModuleBase_ModelWidget* aWidget, aWidgets) {
137 if (theSelectionControl) { // hide other controls
139 aWidget->setVisible(false);
141 else { // hide current control
143 aWidget->setVisible(false);
145 aWidget->setVisible(true);
150 QIntList PartSet_WidgetSketchCreator::getShapeTypes() const
152 QIntList aShapeTypes;
153 foreach(QString aType, myShapeTypes) {
154 aShapeTypes.append(ModuleBase_Tools::shapeType(aType));
159 void PartSet_WidgetSketchCreator::deactivate()
161 if (isSelectionMode()) {
162 ModuleBase_WidgetSelector::activateCustom();
166 bool PartSet_WidgetSketchCreator::isSelectionMode() const
168 //CompositeFeaturePtr aCompFeature =
169 // std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(myFeature);
170 //bool aHasSub = aCompFeature->numberOfSubs() > 0;
172 AttributeSelectionListPtr anAttrList = myFeature->data()->selectionList(myAttributeListID);
173 bool aHasValueInList = anAttrList.get() && anAttrList->size() > 0;
175 return !aHasValueInList;//aHasSub || aHasValueInList;
178 void PartSet_WidgetSketchCreator::onSelectionChanged()
180 QList<ModuleBase_ViewerPrs> aSelected = getFilteredSelected();
182 if (aSelected.size() == 1) { // plane or planar face of not sketch object
183 startSketchOperation();
185 else if (aSelected.size() > 1) {
186 QList<ModuleBase_ViewerPrs>::const_iterator anIt = aSelected.begin(), aLast = aSelected.end();
188 for (; anIt != aLast; anIt++) {
189 ModuleBase_ViewerPrs aValue = *anIt;
190 if (isValidInFilters(aValue))
191 aProcessed = setSelectionCustom(aValue);
194 emit valuesChanged();
195 updateObject(myFeature);
196 setVisibleSelectionControl(false);
197 emit focusOutWidget(this);
202 //********************************************************************
203 void PartSet_WidgetSketchCreator::setObject(ObjectPtr theSelectedObject,
204 GeomShapePtr theShape)
206 std::string anAttributeId = myAttributeListID;
207 DataPtr aData = myFeature->data();
208 AttributePtr anAttribute = aData->attribute(anAttributeId);
209 if (anAttribute.get()) {
210 std::string aType = anAttribute->attributeType();
211 if (aType == ModelAPI_AttributeSelectionList::typeId()) {
212 AttributeSelectionListPtr aSelectionListAttr = aData->selectionList(anAttributeId);
213 ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(theSelectedObject);
214 if (!aSelectionListAttr->isInList(aResult, theShape, myIsInValidate))
215 aSelectionListAttr->append(aResult, theShape, myIsInValidate);
219 void PartSet_WidgetSketchCreator::onStarted()
221 disconnect(myModule, SIGNAL(operationLaunched()), this, SLOT(onStarted()));
223 setVisibleSelectionControl(true);
226 void PartSet_WidgetSketchCreator::startSketchOperation()
228 // Check that model already has bodies
229 /*XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(myModule->workshop());
230 XGUI_Workshop* aWorkshop = aConnector->workshop();
231 XGUI_Displayer* aDisp = aWorkshop->displayer();
232 QObjectPtrList aObjList = aDisp->displayedObjects();
233 bool aHasBody = !myUseBody;
236 foreach(ObjectPtr aObj, aObjList) {
237 aBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(aObj);
238 if (aBody.get() != NULL) {
246 // Launch Sketch operation
247 CompositeFeaturePtr aCompFeature =
248 std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(myFeature);
250 /// add sketch feature without current feature change.
251 /// it is important to do not change the current feature in order to
252 /// after sketch edition, the extrusion cut feature becomes current
253 SessionPtr aMgr = ModelAPI_Session::get();
254 DocumentPtr aDoc = aMgr->activeDocument();
255 FeaturePtr aPreviousCurrentFeature = aDoc->currentFeature(false);
256 FeaturePtr aSketch = aCompFeature->addFeature("Sketch");
257 aDoc->setCurrentFeature(aPreviousCurrentFeature, false);
259 // start edit operation for the sketch
260 ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
261 (myModule->createOperation("Sketch"));
263 aFOperation->setFeature(aSketch);
264 myModule->sendOperation(aFOperation);
265 //connect(anOperation, SIGNAL(aborted()), aWorkshop->operationMgr(), SLOT(abortAllOperations()));
268 // Break current operation
269 std::string anOperationName = feature()->getKind();
270 QString aTitle = tr( anOperationName.c_str() );
271 QMessageBox::warning(this, aTitle,
272 tr("There are no bodies found. Operation aborted."), QMessageBox::Ok);
273 ModuleBase_Operation* aOp = myModule->workshop()->currentOperation();
278 bool PartSet_WidgetSketchCreator::focusTo()
280 if (isSelectionMode()) {
281 //CompositeFeaturePtr aCompFeature =
282 // std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(myFeature);
283 // if (aCompFeature->numberOfSubs() == 0)
284 // return ModuleBase_ModelWidget::focusTo();
285 connect(myModule, SIGNAL(operationLaunched()), SLOT(onStarted()));
286 // we need to call activate here as the widget has no focus accepted controls
287 // if these controls are added here, activate will happens automatically after focusIn()
292 connect(myModule, SIGNAL(resumed(ModuleBase_Operation*)), SLOT(onResumed(ModuleBase_Operation*)));
293 SessionPtr aMgr = ModelAPI_Session::get();
294 // Open transaction that is general for the previous nested one: it will be closed on nested commit
295 bool aIsOp = aMgr->isOperation();
297 const static std::string aNestedOpID("Parameters modification");
298 aMgr->startOperation(aNestedOpID, true);
305 void PartSet_WidgetSketchCreator::onResumed(ModuleBase_Operation* theOp)
307 CompositeFeaturePtr aCompFeature =
308 std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(myFeature);
309 CompositeFeaturePtr aSketchFeature =
310 std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(aCompFeature->subFeature(0));
311 if (aSketchFeature->numberOfSubs() == 0) {
313 SessionPtr aMgr = ModelAPI_Session::get();
316 bool aIsOp = aMgr->isOperation();
318 const static std::string aNestedOpID("Parameters cancelation");
319 aMgr->startOperation(aNestedOpID, true);
324 // Hide sketcher result
325 std::list<ResultPtr> aResults = aSketchFeature->results();
326 std::list<ResultPtr>::const_iterator aIt;
327 for (aIt = aResults.begin(); aIt != aResults.end(); ++aIt) {
328 (*aIt)->setDisplayed(false);
330 aSketchFeature->setDisplayed(false);
333 // Add Selected body were created the sketcher to list of selected objects
334 DataPtr aData = aSketchFeature->data();
335 AttributeSelectionPtr aSelAttr =
336 std::dynamic_pointer_cast<ModelAPI_AttributeSelection>
337 (aData->attribute(SketchPlugin_SketchEntity::EXTERNAL_ID()));
338 if (aSelAttr.get()) {
339 ResultPtr aRes = aSelAttr->context();
340 GeomShapePtr aShape = aSelAttr->value();
342 std::string anObjectsAttribute = FeaturesPlugin_CompositeBoolean::BOOLEAN_OBJECTS_ID();
343 SessionPtr aMgr = ModelAPI_Session::get();
344 ModelAPI_ValidatorsFactory* aFactory = aMgr->validators();
345 AttributePtr anAttribute = myFeature->attribute(anObjectsAttribute);
346 std::string aValidatorID, anError;
347 AttributeSelectionListPtr aSelList = aCompFeature->data()->selectionList(anObjectsAttribute);
348 aSelList->append(aRes, GeomShapePtr());
349 if (aFactory->validate(anAttribute, aValidatorID, anError))
350 updateObject(aCompFeature);
357 // this is a workarount to display the feature results in the operation selection mode
358 // if this is absent, sketch point/line local selection is available on extrusion cut result
359 static Events_ID anUpdateEvent = Events_Loop::eventByName(EVENT_OBJECT_UPDATED);
360 ModelAPI_EventCreator::get()->sendUpdated(feature(), anUpdateEvent);
361 updateObject(feature());