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"
9 #include "PartSet_WidgetSketchLabel.h"
11 #include <Config_Keywords.h>
13 #include <XGUI_ModuleConnector.h>
14 #include <XGUI_Workshop.h>
15 #include <XGUI_Displayer.h>
16 #include <XGUI_SelectionMgr.h>
17 #include <XGUI_OperationMgr.h>
18 #include <XGUI_PropertyPanel.h>
20 #include <GeomAPI_Face.h>
22 #include <ModelAPI_Session.h>
23 #include <ModelAPI_ResultBody.h>
24 #include <ModelAPI_AttributeSelection.h>
25 #include <ModelAPI_AttributeSelectionList.h>
26 #include <ModelAPI_Validator.h>
27 #include <ModelAPI_Events.h>
29 #include <SketchPlugin_SketchEntity.h>
30 #include <FeaturesPlugin_CompositeBoolean.h>
32 #include <ModuleBase_Tools.h>
33 #include <ModuleBase_Operation.h>
34 #include <ModuleBase_IPropertyPanel.h>
35 #include <ModuleBase_OperationFeature.h>
36 #include <Config_WidgetAPI.h>
38 #include <Events_Loop.h>
42 //#include <QFormLayout>
43 #include <QVBoxLayout>
44 #include <QMessageBox>
46 PartSet_WidgetSketchCreator::PartSet_WidgetSketchCreator(QWidget* theParent,
47 PartSet_Module* theModule,
48 const Config_WidgetAPI* theData)
49 : ModuleBase_WidgetSelector(theParent, theModule->workshop(), theData),
50 myModule(theModule), myUseBody(true)
52 myAttributeListID = theData->getProperty("attribute_list_id");
54 //QFormLayout* aLayout = new QFormLayout(this);
55 QVBoxLayout* aLayout = new QVBoxLayout(this);
56 ModuleBase_Tools::zeroMargins(aLayout);
58 ModuleBase_Tools::adjustMargins(aLayout);
60 QString aLabelText = QString::fromStdString(theData->widgetLabel());
61 QString aLabelIcon = QString::fromStdString(theData->widgetIcon());
63 myLabel = new QLabel(aLabelText, this);
64 myLabel->setWordWrap(true);
65 aLayout->addWidget(myLabel);
66 /*if (!aLabelIcon.isEmpty())
67 myLabel->setPixmap(QPixmap(aLabelIcon));
70 QString aToolTip = QString::fromStdString(theData->widgetTooltip());
71 myTextLine = new QLineEdit(this);
72 myTextLine->setReadOnly(true);
73 myTextLine->setToolTip(aToolTip);
74 myTextLine->installEventFilter(this);
76 myLabel->setToolTip(aToolTip);
78 QString aUseBody = QString::fromStdString(theData->getProperty(USE_BODY));
79 if(!aUseBody.isEmpty()) {
80 myUseBody = QVariant(aUseBody).toBool();
83 aLayout->addRow(myLabel, myTextLine);*/
85 std::string aTypes = theData->getProperty("shape_types");
86 myShapeTypes = QString(aTypes.c_str()).split(' ', QString::SkipEmptyParts);
89 PartSet_WidgetSketchCreator::~PartSet_WidgetSketchCreator()
93 QList<QWidget*> PartSet_WidgetSketchCreator::getControls() const
95 QList<QWidget*> aControls;
96 aControls.append(myLabel);
100 bool PartSet_WidgetSketchCreator::restoreValueCustom()
102 /*CompositeFeaturePtr aCompFeature =
103 std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(myFeature);
104 if (aCompFeature->numberOfSubs() > 0) {
105 FeaturePtr aSubFeature = aCompFeature->subFeature(0);
106 myTextLine->setText(QString::fromStdString(aSubFeature->data()->name()));
111 bool PartSet_WidgetSketchCreator::storeValueCustom() const
116 void PartSet_WidgetSketchCreator::activateCustom()
118 if (isSelectionMode()) {
119 ModuleBase_WidgetSelector::activateCustom();
120 //connect(myModule, SIGNAL(operationLaunched()), SLOT(onStarted()));
122 //setVisibleSelectionControl(true);
125 // setVisibleSelectionControl(false);
126 // emit focusOutWidget(this);
130 void PartSet_WidgetSketchCreator::setVisibleSelectionControl(const bool theSelectionControl)
132 // hide current widget, activate the next widget
133 XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(myModule->workshop());
134 XGUI_Workshop* aWorkshop = aConnector->workshop();
135 XGUI_PropertyPanel* aPanel = aWorkshop->propertyPanel();
136 const QList<ModuleBase_ModelWidget*>& aWidgets = aPanel->modelWidgets();
137 foreach(ModuleBase_ModelWidget* aWidget, aWidgets) {
138 if (theSelectionControl) { // hide other controls
140 aWidget->setVisible(false);
142 else { // hide current control
144 aWidget->setVisible(false);
146 aWidget->setVisible(true);
151 QIntList PartSet_WidgetSketchCreator::getShapeTypes() const
153 QIntList aShapeTypes;
154 foreach(QString aType, myShapeTypes) {
155 aShapeTypes.append(ModuleBase_Tools::shapeType(aType));
160 void PartSet_WidgetSketchCreator::deactivate()
162 if (isSelectionMode()) {
163 ModuleBase_WidgetSelector::activateCustom();
167 bool PartSet_WidgetSketchCreator::isSelectionMode() const
169 //CompositeFeaturePtr aCompFeature =
170 // std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(myFeature);
171 //bool aHasSub = aCompFeature->numberOfSubs() > 0;
173 AttributeSelectionListPtr anAttrList = myFeature->data()->selectionList(myAttributeListID);
174 bool aHasValueInList = anAttrList.get() && anAttrList->size() > 0;
176 return !aHasValueInList;//aHasSub || aHasValueInList;
179 void PartSet_WidgetSketchCreator::onSelectionChanged()
181 QList<ModuleBase_ViewerPrs> aSelected = getFilteredSelected();
183 if (aSelected.size() == 1) { // plane or planar face of not sketch object
184 startSketchOperation(aSelected.front());
186 else if (aSelected.size() > 1) {
187 QList<ModuleBase_ViewerPrs>::const_iterator anIt = aSelected.begin(), aLast = aSelected.end();
189 for (; anIt != aLast; anIt++) {
190 ModuleBase_ViewerPrs aValue = *anIt;
191 if (isValidInFilters(aValue))
192 aProcessed = setSelectionCustom(aValue);
195 emit valuesChanged();
196 updateObject(myFeature);
197 setVisibleSelectionControl(false);
198 emit focusOutWidget(this);
203 //********************************************************************
204 void PartSet_WidgetSketchCreator::setObject(ObjectPtr theSelectedObject,
205 GeomShapePtr theShape)
207 std::string anAttributeId = myAttributeListID;
208 DataPtr aData = myFeature->data();
209 AttributePtr anAttribute = aData->attribute(anAttributeId);
210 if (anAttribute.get()) {
211 std::string aType = anAttribute->attributeType();
212 if (aType == ModelAPI_AttributeSelectionList::typeId()) {
213 AttributeSelectionListPtr aSelectionListAttr = aData->selectionList(anAttributeId);
214 ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(theSelectedObject);
215 if (!aSelectionListAttr->isInList(aResult, theShape, myIsInValidate))
216 aSelectionListAttr->append(aResult, theShape, myIsInValidate);
220 void PartSet_WidgetSketchCreator::onStarted()
222 disconnect(myModule, SIGNAL(operationLaunched()), this, SLOT(onStarted()));
224 setVisibleSelectionControl(true);
227 void PartSet_WidgetSketchCreator::startSketchOperation(const ModuleBase_ViewerPrs& theValue)
229 // Check that model already has bodies
230 /*XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(myModule->workshop());
231 XGUI_Workshop* aWorkshop = aConnector->workshop();
232 XGUI_Displayer* aDisp = aWorkshop->displayer();
233 QObjectPtrList aObjList = aDisp->displayedObjects();
234 bool aHasBody = !myUseBody;
237 foreach(ObjectPtr aObj, aObjList) {
238 aBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(aObj);
239 if (aBody.get() != NULL) {
247 // Launch Sketch operation
248 CompositeFeaturePtr aCompFeature =
249 std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(myFeature);
251 /// add sketch feature without current feature change.
252 /// it is important to do not change the current feature in order to
253 /// after sketch edition, the extrusion cut feature becomes current
254 SessionPtr aMgr = ModelAPI_Session::get();
255 DocumentPtr aDoc = aMgr->activeDocument();
256 FeaturePtr aPreviousCurrentFeature = aDoc->currentFeature(false);
257 FeaturePtr aSketch = aCompFeature->addFeature("Sketch");
259 PartSet_WidgetSketchLabel::fillSketchPlaneBySelection(aSketch, theValue);
261 aDoc->setCurrentFeature(aPreviousCurrentFeature, false);
263 // start edit operation for the sketch
264 ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
265 (myModule->createOperation("Sketch"));
267 aFOperation->setFeature(aSketch);
268 myModule->sendOperation(aFOperation);
269 //connect(anOperation, SIGNAL(aborted()), aWorkshop->operationMgr(), SLOT(abortAllOperations()));
272 // Break current operation
273 std::string anOperationName = feature()->getKind();
274 QString aTitle = tr( anOperationName.c_str() );
275 QMessageBox::warning(this, aTitle,
276 tr("There are no bodies found. Operation aborted."), QMessageBox::Ok);
277 ModuleBase_Operation* aOp = myModule->workshop()->currentOperation();
282 bool PartSet_WidgetSketchCreator::focusTo()
284 if (isSelectionMode()) {
285 //CompositeFeaturePtr aCompFeature =
286 // std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(myFeature);
287 // if (aCompFeature->numberOfSubs() == 0)
288 // return ModuleBase_ModelWidget::focusTo();
289 connect(myModule, SIGNAL(operationLaunched()), SLOT(onStarted()));
290 // we need to call activate here as the widget has no focus accepted controls
291 // if these controls are added here, activate will happens automatically after focusIn()
296 connect(myModule, SIGNAL(resumed(ModuleBase_Operation*)), SLOT(onResumed(ModuleBase_Operation*)));
297 SessionPtr aMgr = ModelAPI_Session::get();
298 // Open transaction that is general for the previous nested one: it will be closed on nested commit
299 bool aIsOp = aMgr->isOperation();
301 const static std::string aNestedOpID("Parameters modification");
302 aMgr->startOperation(aNestedOpID, true);
309 void PartSet_WidgetSketchCreator::onResumed(ModuleBase_Operation* theOp)
311 CompositeFeaturePtr aCompFeature =
312 std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(myFeature);
313 CompositeFeaturePtr aSketchFeature =
314 std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(aCompFeature->subFeature(0));
315 if (aSketchFeature->numberOfSubs() == 0) {
317 SessionPtr aMgr = ModelAPI_Session::get();
320 bool aIsOp = aMgr->isOperation();
322 const static std::string aNestedOpID("Parameters cancelation");
323 aMgr->startOperation(aNestedOpID, true);
328 // Hide sketcher result
329 std::list<ResultPtr> aResults = aSketchFeature->results();
330 std::list<ResultPtr>::const_iterator aIt;
331 for (aIt = aResults.begin(); aIt != aResults.end(); ++aIt) {
332 (*aIt)->setDisplayed(false);
334 aSketchFeature->setDisplayed(false);
337 // Add Selected body were created the sketcher to list of selected objects
338 DataPtr aData = aSketchFeature->data();
339 AttributeSelectionPtr aSelAttr =
340 std::dynamic_pointer_cast<ModelAPI_AttributeSelection>
341 (aData->attribute(SketchPlugin_SketchEntity::EXTERNAL_ID()));
342 if (aSelAttr.get()) {
343 ResultPtr aRes = aSelAttr->context();
344 GeomShapePtr aShape = aSelAttr->value();
346 std::string anObjectsAttribute = FeaturesPlugin_CompositeBoolean::BOOLEAN_OBJECTS_ID();
347 SessionPtr aMgr = ModelAPI_Session::get();
348 ModelAPI_ValidatorsFactory* aFactory = aMgr->validators();
349 AttributePtr anAttribute = myFeature->attribute(anObjectsAttribute);
350 std::string aValidatorID, anError;
351 AttributeSelectionListPtr aSelList = aCompFeature->data()->selectionList(anObjectsAttribute);
352 aSelList->append(aRes, GeomShapePtr());
353 if (aFactory->validate(anAttribute, aValidatorID, anError))
354 updateObject(aCompFeature);
361 // this is a workarount to display the feature results in the operation selection mode
362 // if this is absent, sketch point/line local selection is available on extrusion cut result
363 static Events_ID anUpdateEvent = Events_Loop::eventByName(EVENT_OBJECT_UPDATED);
364 ModelAPI_EventCreator::get()->sendUpdated(feature(), anUpdateEvent);
365 updateObject(feature());