Salome HOME
Issue #1343 Improvement of Extrusion and Revolution operations: preview planes visual...
[modules/shaper.git] / src / PartSet / PartSet_WidgetSketchCreator.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
2
3 // File:        PartSet_WidgetSketchCreator.cpp
4 // Created:     08 June 2015
5 // Author:      Vitaly SMETANNIKOV
6
7 #include "PartSet_WidgetSketchCreator.h"
8 #include "PartSet_Module.h"
9 #include "PartSet_WidgetSketchLabel.h"
10 #include "PartSet_PreviewPlanes.h"
11
12 #include <Config_Keywords.h>
13
14 #include <XGUI_ModuleConnector.h>
15 #include <XGUI_Workshop.h>
16 #include <XGUI_Displayer.h>
17 #include <XGUI_SelectionMgr.h>
18 #include <XGUI_OperationMgr.h>
19 #include <XGUI_PropertyPanel.h>
20 #include <XGUI_Tools.h>
21 #include <XGUI_ViewerProxy.h>
22
23 #include <GeomAPI_Face.h>
24
25 #include <ModelAPI_Session.h>
26 #include <ModelAPI_ResultBody.h>
27 #include <ModelAPI_AttributeSelection.h>
28 #include <ModelAPI_AttributeSelectionList.h>
29 #include <ModelAPI_Validator.h>
30 #include <ModelAPI_Events.h>
31
32 #include <SketchPlugin_SketchEntity.h>
33 #include <FeaturesPlugin_CompositeBoolean.h>
34
35 #include <ModuleBase_Tools.h>
36 #include <ModuleBase_Operation.h>
37 #include <ModuleBase_IPropertyPanel.h>
38 #include <ModuleBase_OperationFeature.h>
39 #include <Config_WidgetAPI.h>
40
41 #include <Events_Loop.h>
42
43 #include <QLabel>
44 #include <QLineEdit>
45 //#include <QFormLayout>
46 #include <QVBoxLayout>
47 #include <QMessageBox>
48
49 PartSet_WidgetSketchCreator::PartSet_WidgetSketchCreator(QWidget* theParent, 
50                                                          PartSet_Module* theModule,
51                                                          const Config_WidgetAPI* theData)
52 : ModuleBase_WidgetSelector(theParent, theModule->workshop(), theData),
53   myModule(theModule)
54 {
55   myAttributeListID = theData->getProperty("attribute_list_id");
56
57   //QFormLayout* aLayout = new QFormLayout(this);
58   QVBoxLayout* aLayout = new QVBoxLayout(this);
59   ModuleBase_Tools::zeroMargins(aLayout);
60
61   ModuleBase_Tools::adjustMargins(aLayout);
62
63   QString aLabelText = QString::fromStdString(theData->widgetLabel());
64   QString aLabelIcon = QString::fromStdString(theData->widgetIcon());
65
66   myLabel = new QLabel(aLabelText, this);
67   myLabel->setWordWrap(true);
68   aLayout->addWidget(myLabel);
69   /*if (!aLabelIcon.isEmpty())
70     myLabel->setPixmap(QPixmap(aLabelIcon));
71
72
73   QString aToolTip = QString::fromStdString(theData->widgetTooltip());
74   myTextLine = new QLineEdit(this);
75   myTextLine->setReadOnly(true);
76   myTextLine->setToolTip(aToolTip);
77   myTextLine->installEventFilter(this);
78
79   myLabel->setToolTip(aToolTip);
80
81   aLayout->addRow(myLabel, myTextLine);*/
82
83   std::string aTypes = theData->getProperty("shape_types");
84   myShapeTypes = QString(aTypes.c_str()).split(' ', QString::SkipEmptyParts);
85
86   myPreviewPlanes = new PartSet_PreviewPlanes();
87 }
88
89 PartSet_WidgetSketchCreator::~PartSet_WidgetSketchCreator()
90 {
91 }
92
93 QList<QWidget*> PartSet_WidgetSketchCreator::getControls() const
94 {
95   QList<QWidget*> aControls;
96   aControls.append(myLabel);
97   return aControls;
98 }
99
100 bool PartSet_WidgetSketchCreator::restoreValueCustom()
101 {
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()));
107   }*/
108   return true;
109 }
110
111 bool PartSet_WidgetSketchCreator::storeValueCustom() const
112 {
113   return true;
114 }
115
116 void PartSet_WidgetSketchCreator::setVisibleSelectionControl(const bool theSelectionControl)
117 {
118   // hide current widget, activate the next widget
119   XGUI_Workshop* aWorkshop = XGUI_Tools::workshop(myModule->workshop());
120   XGUI_PropertyPanel* aPanel = aWorkshop->propertyPanel();
121   const QList<ModuleBase_ModelWidget*>& aWidgets = aPanel->modelWidgets();
122   foreach(ModuleBase_ModelWidget* aWidget, aWidgets) {
123     if (theSelectionControl) { // hide other controls
124       if (aWidget != this)
125         aWidget->setVisible(false);
126     }
127     else { // hide current control
128       if (aWidget == this)
129         aWidget->setVisible(false);
130       else
131         aWidget->setVisible(true);
132     }
133   }
134
135   if (theSelectionControl) {
136     bool aBodyIsVisualized = myPreviewPlanes->hasVisualizedBodies(myWorkshop);
137     if (!aBodyIsVisualized) {
138       // We have to select a plane before any operation
139       myPreviewPlanes->showPreviewPlanes(myWorkshop);
140     }
141   } else {
142     bool aHidePreview = myPreviewPlanes->isPreviewDisplayed();
143     myPreviewPlanes->showPreviewPlanes(myWorkshop);
144     if (aHidePreview)
145       aWorkshop->viewer()->update();
146   }
147 }
148
149 QIntList PartSet_WidgetSketchCreator::getShapeTypes() const
150 {
151   QIntList aShapeTypes;
152   foreach(QString aType, myShapeTypes) {
153     aShapeTypes.append(ModuleBase_Tools::shapeType(aType));
154   }
155   return aShapeTypes;
156 }
157
158 void PartSet_WidgetSketchCreator::setEditingMode(bool isEditing)
159 {
160   ModuleBase_ModelWidget::setEditingMode(isEditing);
161   if (isEditing)
162     setVisibleSelectionControl(false);
163 }
164
165 bool PartSet_WidgetSketchCreator::isSelectionMode() const
166 {
167   AttributeSelectionListPtr anAttrList = myFeature->data()->selectionList(myAttributeListID);
168   bool aHasValueInList = anAttrList.get() && anAttrList->size() > 0;
169
170   return !aHasValueInList;
171 }
172
173 void PartSet_WidgetSketchCreator::onSelectionChanged()
174 {
175   QList<ModuleBase_ViewerPrs> aSelected = getFilteredSelected();
176
177   if (!startSketchOperation(aSelected)) {
178     QList<ModuleBase_ViewerPrs>::const_iterator anIt = aSelected.begin(), aLast = aSelected.end();
179     bool aProcessed = false;
180     for (; anIt != aLast; anIt++) {
181       ModuleBase_ViewerPrs aValue = *anIt;
182       if (isValidInFilters(aValue))
183         aProcessed = setSelectionCustom(aValue) || aProcessed;
184     }
185     if (aProcessed) {
186       emit valuesChanged();
187       updateObject(myFeature);
188       setVisibleSelectionControl(false);
189       // manually deactivation because the widget was not activated as has no focus acceptin controls
190       deactivate();
191       emit focusOutWidget(this);
192     }
193   }
194 }
195
196 //********************************************************************
197 void PartSet_WidgetSketchCreator::setObject(ObjectPtr theSelectedObject,
198                                             GeomShapePtr theShape)
199 {
200   std::string anAttributeId = myAttributeListID;
201   DataPtr aData = myFeature->data();
202   AttributePtr anAttribute = aData->attribute(anAttributeId);
203   if (anAttribute.get()) {
204     std::string aType = anAttribute->attributeType();
205     if (aType == ModelAPI_AttributeSelectionList::typeId()) {
206       AttributeSelectionListPtr aSelectionListAttr = aData->selectionList(anAttributeId);
207       ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(theSelectedObject);
208       if (!aSelectionListAttr->isInList(aResult, theShape, myIsInValidate))
209         aSelectionListAttr->append(aResult, theShape, myIsInValidate);
210     }
211   }
212 }
213
214 bool PartSet_WidgetSketchCreator::startSketchOperation(const QList<ModuleBase_ViewerPrs>& theValues)
215 {
216   bool aSketchStarted = false;
217
218   if (theValues.size() != 1)
219     return aSketchStarted;
220
221   ModuleBase_ViewerPrs aValue = theValues.front();
222   if (!PartSet_WidgetSketchLabel::canFillSketch(aValue))
223     return aSketchStarted;
224
225   aSketchStarted = true;
226
227   // manually deactivation because the widget was not activated as has no focus acceptin controls
228   deactivate();
229   bool aHidePreview = myPreviewPlanes->isPreviewDisplayed();
230   myPreviewPlanes->erasePreviewPlanes(myWorkshop);
231
232   // Launch Sketch operation
233   CompositeFeaturePtr aCompFeature = 
234     std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(myFeature);
235
236   /// add sketch feature without current feature change.
237   /// it is important to do not change the current feature in order to
238   /// after sketch edition, the extrusion cut feature becomes current
239   SessionPtr aMgr = ModelAPI_Session::get();
240   DocumentPtr aDoc = aMgr->activeDocument();
241   FeaturePtr aPreviousCurrentFeature = aDoc->currentFeature(false);
242   FeaturePtr aSketch = aCompFeature->addFeature("Sketch");
243
244   PartSet_WidgetSketchLabel::fillSketchPlaneBySelection(aSketch, aValue);
245
246   aDoc->setCurrentFeature(aPreviousCurrentFeature, false);
247
248   // start edit operation for the sketch
249   ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
250                                                             (myModule->createOperation("Sketch"));
251   if (aFOperation)
252     aFOperation->setFeature(aSketch);
253   myModule->sendOperation(aFOperation);
254
255   return aSketchStarted;
256 }
257
258 bool PartSet_WidgetSketchCreator::focusTo()
259 {
260   if (isSelectionMode()) {
261     setVisibleSelectionControl(true);
262
263     // we need to call activate here as the widget has no focus accepted controls
264     // if these controls are added here, activate will happens automatically after focusIn()
265     activateCustom();
266     return true;
267   }
268   else {
269     setVisibleSelectionControl(false);
270
271     connect(myModule, SIGNAL(resumed(ModuleBase_Operation*)), SLOT(onResumed(ModuleBase_Operation*)));
272     SessionPtr aMgr = ModelAPI_Session::get();
273     // Open transaction that is general for the previous nested one: it will be closed on nested commit
274     bool aIsOp = aMgr->isOperation();
275     if (!aIsOp) {
276       const static std::string aNestedOpID("Parameters modification");
277       aMgr->startOperation(aNestedOpID, true);
278     }
279     restoreValue();
280   }
281   return false;
282 }
283
284 void PartSet_WidgetSketchCreator::onResumed(ModuleBase_Operation* theOp)
285 {
286   CompositeFeaturePtr aCompFeature = 
287     std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(myFeature);
288   CompositeFeaturePtr aSketchFeature = 
289     std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(aCompFeature->subFeature(0));
290   if (aSketchFeature->numberOfSubs() == 0) {
291     // do nothing, selection control should be shown
292
293     // Abort operation
294     //SessionPtr aMgr = ModelAPI_Session::get();
295     // Close transaction
296     /*
297     bool aIsOp = aMgr->isOperation();
298     if (aIsOp) {
299       const static std::string aNestedOpID("Parameters cancelation");
300       aMgr->startOperation(aNestedOpID, true);
301     }
302     */
303     //theOp->abort();
304   } else {
305     // Update value in attribute selection list
306     XGUI_Workshop* aWorkshop = XGUI_Tools::workshop(myModule->workshop());
307     XGUI_PropertyPanel* aPanel = aWorkshop->propertyPanel();
308     const QList<ModuleBase_ModelWidget*>& aWidgets = aPanel->modelWidgets();
309     foreach(ModuleBase_ModelWidget* aWidget, aWidgets) {
310       if (aWidget->attributeID() == myAttributeListID)
311         aWidget->restoreValue();
312     }
313
314     // Hide sketcher result
315     std::list<ResultPtr> aResults = aSketchFeature->results();
316     std::list<ResultPtr>::const_iterator aIt;
317     for (aIt = aResults.begin(); aIt != aResults.end(); ++aIt) {
318       (*aIt)->setDisplayed(false);
319     }
320     aSketchFeature->setDisplayed(false);
321
322     // restore value in the selection control
323
324
325     // Add Selected body were created the sketcher to list of selected objects
326     std::string anObjectsAttribute = FeaturesPlugin_CompositeBoolean::BOOLEAN_OBJECTS_ID();
327     AttributeSelectionListPtr aSelList = aCompFeature->data()->selectionList(anObjectsAttribute);
328     if (aSelList.get()) {
329       DataPtr aData = aSketchFeature->data();
330       AttributeSelectionPtr aSelAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelection>
331                                     (aData->attribute(SketchPlugin_SketchEntity::EXTERNAL_ID()));
332       ResultPtr aRes = aSelAttr.get() ? aSelAttr->context() : ResultPtr();
333       if (aRes.get()) {
334         SessionPtr aMgr = ModelAPI_Session::get();
335         ModelAPI_ValidatorsFactory* aFactory = aMgr->validators();
336         AttributePtr anAttribute = myFeature->attribute(anObjectsAttribute);
337         std::string aValidatorID, anError;
338         aSelList->append(aRes, GeomShapePtr());
339         if (aFactory->validate(anAttribute, aValidatorID, anError))
340           updateObject(aCompFeature);
341         else
342           aSelList->clear();
343       }
344     }
345   }
346 }