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>
19 #include <XGUI_Tools.h>
21 #include <GeomAPI_Face.h>
23 #include <ModelAPI_Session.h>
24 #include <ModelAPI_ResultBody.h>
25 #include <ModelAPI_AttributeSelection.h>
26 #include <ModelAPI_AttributeSelectionList.h>
27 #include <ModelAPI_Validator.h>
28 #include <ModelAPI_Events.h>
30 #include <SketchPlugin_SketchEntity.h>
31 #include <FeaturesPlugin_CompositeBoolean.h>
33 #include <ModuleBase_Tools.h>
34 #include <ModuleBase_Operation.h>
35 #include <ModuleBase_IPropertyPanel.h>
36 #include <ModuleBase_OperationFeature.h>
37 #include <Config_WidgetAPI.h>
39 #include <Events_Loop.h>
43 //#include <QFormLayout>
44 #include <QVBoxLayout>
45 #include <QMessageBox>
47 PartSet_WidgetSketchCreator::PartSet_WidgetSketchCreator(QWidget* theParent,
48 PartSet_Module* theModule,
49 const Config_WidgetAPI* theData)
50 : ModuleBase_WidgetSelector(theParent, theModule->workshop(), theData),
51 myModule(theModule), myUseBody(true)
53 myAttributeListID = theData->getProperty("attribute_list_id");
55 //QFormLayout* aLayout = new QFormLayout(this);
56 QVBoxLayout* aLayout = new QVBoxLayout(this);
57 ModuleBase_Tools::zeroMargins(aLayout);
59 ModuleBase_Tools::adjustMargins(aLayout);
61 QString aLabelText = QString::fromStdString(theData->widgetLabel());
62 QString aLabelIcon = QString::fromStdString(theData->widgetIcon());
64 myLabel = new QLabel(aLabelText, this);
65 myLabel->setWordWrap(true);
66 aLayout->addWidget(myLabel);
67 /*if (!aLabelIcon.isEmpty())
68 myLabel->setPixmap(QPixmap(aLabelIcon));
71 QString aToolTip = QString::fromStdString(theData->widgetTooltip());
72 myTextLine = new QLineEdit(this);
73 myTextLine->setReadOnly(true);
74 myTextLine->setToolTip(aToolTip);
75 myTextLine->installEventFilter(this);
77 myLabel->setToolTip(aToolTip);
79 QString aUseBody = QString::fromStdString(theData->getProperty(USE_BODY));
80 if(!aUseBody.isEmpty()) {
81 myUseBody = QVariant(aUseBody).toBool();
84 aLayout->addRow(myLabel, myTextLine);*/
86 std::string aTypes = theData->getProperty("shape_types");
87 myShapeTypes = QString(aTypes.c_str()).split(' ', QString::SkipEmptyParts);
90 PartSet_WidgetSketchCreator::~PartSet_WidgetSketchCreator()
94 QList<QWidget*> PartSet_WidgetSketchCreator::getControls() const
96 QList<QWidget*> aControls;
97 aControls.append(myLabel);
101 bool PartSet_WidgetSketchCreator::restoreValueCustom()
103 /*CompositeFeaturePtr aCompFeature =
104 std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(myFeature);
105 if (aCompFeature->numberOfSubs() > 0) {
106 FeaturePtr aSubFeature = aCompFeature->subFeature(0);
107 myTextLine->setText(QString::fromStdString(aSubFeature->data()->name()));
112 bool PartSet_WidgetSketchCreator::storeValueCustom() const
117 void PartSet_WidgetSketchCreator::setVisibleSelectionControl(const bool theSelectionControl)
119 // hide current widget, activate the next widget
120 XGUI_Workshop* aWorkshop = XGUI_Tools::workshop(myModule->workshop());
121 XGUI_PropertyPanel* aPanel = aWorkshop->propertyPanel();
122 const QList<ModuleBase_ModelWidget*>& aWidgets = aPanel->modelWidgets();
123 foreach(ModuleBase_ModelWidget* aWidget, aWidgets) {
124 if (theSelectionControl) { // hide other controls
126 aWidget->setVisible(false);
128 else { // hide current control
130 aWidget->setVisible(false);
132 aWidget->setVisible(true);
137 QIntList PartSet_WidgetSketchCreator::getShapeTypes() const
139 QIntList aShapeTypes;
140 foreach(QString aType, myShapeTypes) {
141 aShapeTypes.append(ModuleBase_Tools::shapeType(aType));
146 void PartSet_WidgetSketchCreator::setEditingMode(bool isEditing)
148 ModuleBase_ModelWidget::setEditingMode(isEditing);
150 setVisibleSelectionControl(false);
153 bool PartSet_WidgetSketchCreator::isSelectionMode() const
155 AttributeSelectionListPtr anAttrList = myFeature->data()->selectionList(myAttributeListID);
156 bool aHasValueInList = anAttrList.get() && anAttrList->size() > 0;
158 return !aHasValueInList;
161 void PartSet_WidgetSketchCreator::onSelectionChanged()
163 QList<ModuleBase_ViewerPrs> aSelected = getFilteredSelected();
165 if (!startSketchOperation(aSelected)) {
166 QList<ModuleBase_ViewerPrs>::const_iterator anIt = aSelected.begin(), aLast = aSelected.end();
167 bool aProcessed = false;
168 for (; anIt != aLast; anIt++) {
169 ModuleBase_ViewerPrs aValue = *anIt;
170 if (isValidInFilters(aValue))
171 aProcessed = setSelectionCustom(aValue) || aProcessed;
174 emit valuesChanged();
175 updateObject(myFeature);
176 setVisibleSelectionControl(false);
177 // manually deactivation because the widget was not activated as has no focus acceptin controls
179 emit focusOutWidget(this);
184 //********************************************************************
185 void PartSet_WidgetSketchCreator::setObject(ObjectPtr theSelectedObject,
186 GeomShapePtr theShape)
188 std::string anAttributeId = myAttributeListID;
189 DataPtr aData = myFeature->data();
190 AttributePtr anAttribute = aData->attribute(anAttributeId);
191 if (anAttribute.get()) {
192 std::string aType = anAttribute->attributeType();
193 if (aType == ModelAPI_AttributeSelectionList::typeId()) {
194 AttributeSelectionListPtr aSelectionListAttr = aData->selectionList(anAttributeId);
195 ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(theSelectedObject);
196 if (!aSelectionListAttr->isInList(aResult, theShape, myIsInValidate))
197 aSelectionListAttr->append(aResult, theShape, myIsInValidate);
202 bool PartSet_WidgetSketchCreator::startSketchOperation(const QList<ModuleBase_ViewerPrs>& theValues)
204 bool aSketchStarted = false;
206 if (theValues.size() != 1)
207 return aSketchStarted;
209 ModuleBase_ViewerPrs aValue = theValues.front();
210 if (!PartSet_WidgetSketchLabel::canFillSketch(aValue))
211 return aSketchStarted;
213 aSketchStarted = true;
215 // manually deactivation because the widget was not activated as has no focus acceptin controls
218 // Launch Sketch operation
219 CompositeFeaturePtr aCompFeature =
220 std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(myFeature);
222 /// add sketch feature without current feature change.
223 /// it is important to do not change the current feature in order to
224 /// after sketch edition, the extrusion cut feature becomes current
225 SessionPtr aMgr = ModelAPI_Session::get();
226 DocumentPtr aDoc = aMgr->activeDocument();
227 FeaturePtr aPreviousCurrentFeature = aDoc->currentFeature(false);
228 FeaturePtr aSketch = aCompFeature->addFeature("Sketch");
230 PartSet_WidgetSketchLabel::fillSketchPlaneBySelection(aSketch, aValue);
232 aDoc->setCurrentFeature(aPreviousCurrentFeature, false);
234 // start edit operation for the sketch
235 ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
236 (myModule->createOperation("Sketch"));
238 aFOperation->setFeature(aSketch);
239 myModule->sendOperation(aFOperation);
241 return aSketchStarted;
244 bool PartSet_WidgetSketchCreator::focusTo()
246 if (isSelectionMode()) {
247 setVisibleSelectionControl(true);
249 // we need to call activate here as the widget has no focus accepted controls
250 // if these controls are added here, activate will happens automatically after focusIn()
255 setVisibleSelectionControl(false);
257 connect(myModule, SIGNAL(resumed(ModuleBase_Operation*)), SLOT(onResumed(ModuleBase_Operation*)));
258 SessionPtr aMgr = ModelAPI_Session::get();
259 // Open transaction that is general for the previous nested one: it will be closed on nested commit
260 bool aIsOp = aMgr->isOperation();
262 const static std::string aNestedOpID("Parameters modification");
263 aMgr->startOperation(aNestedOpID, true);
270 void PartSet_WidgetSketchCreator::onResumed(ModuleBase_Operation* theOp)
272 CompositeFeaturePtr aCompFeature =
273 std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(myFeature);
274 CompositeFeaturePtr aSketchFeature =
275 std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(aCompFeature->subFeature(0));
276 if (aSketchFeature->numberOfSubs() == 0) {
277 // do nothing, selection control should be shown
280 //SessionPtr aMgr = ModelAPI_Session::get();
283 bool aIsOp = aMgr->isOperation();
285 const static std::string aNestedOpID("Parameters cancelation");
286 aMgr->startOperation(aNestedOpID, true);
291 // Update value in attribute selection list
292 XGUI_Workshop* aWorkshop = XGUI_Tools::workshop(myModule->workshop());
293 XGUI_PropertyPanel* aPanel = aWorkshop->propertyPanel();
294 const QList<ModuleBase_ModelWidget*>& aWidgets = aPanel->modelWidgets();
295 foreach(ModuleBase_ModelWidget* aWidget, aWidgets) {
296 if (aWidget->attributeID() == myAttributeListID)
297 aWidget->restoreValue();
300 // Hide sketcher result
301 std::list<ResultPtr> aResults = aSketchFeature->results();
302 std::list<ResultPtr>::const_iterator aIt;
303 for (aIt = aResults.begin(); aIt != aResults.end(); ++aIt) {
304 (*aIt)->setDisplayed(false);
306 aSketchFeature->setDisplayed(false);
308 // restore value in the selection control
311 // Add Selected body were created the sketcher to list of selected objects
313 std::string anObjectsAttribute = FeaturesPlugin_CompositeBoolean::BOOLEAN_OBJECTS_ID();
314 AttributeSelectionListPtr aSelList = aCompFeature->data()->selectionList(anObjectsAttribute);
315 if (aSelList.get()) {
316 DataPtr aData = aSketchFeature->data();
317 AttributeSelectionPtr aSelAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelection>
318 (aData->attribute(SketchPlugin_SketchEntity::EXTERNAL_ID()));
319 ResultPtr aRes = aSelAttr.get() ? aSelAttr->context() : ResultPtr();
321 SessionPtr aMgr = ModelAPI_Session::get();
322 ModelAPI_ValidatorsFactory* aFactory = aMgr->validators();
323 AttributePtr anAttribute = myFeature->attribute(anObjectsAttribute);
324 std::string aValidatorID, anError;
325 aSelList->append(aRes, GeomShapePtr());
326 if (aFactory->validate(anAttribute, aValidatorID, anError))
327 updateObject(aCompFeature);
334 // this is a workarount to display the feature results in the operation selection mode
335 // if this is absent, sketch point/line local selection is available on extrusion cut result
336 static Events_ID anUpdateEvent = Events_Loop::eventByName(EVENT_OBJECT_UPDATED);
337 ModelAPI_EventCreator::get()->sendUpdated(feature(), anUpdateEvent);
338 updateObject(feature());