]> SALOME platform Git repositories - modules/shaper.git/blob - src/PartSet/PartSet_WidgetSketchCreator.cpp
Salome HOME
Issue #1343 Improvement of Extrusion and Revolution operations: sketch is filled...
[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
11 #include <Config_Keywords.h>
12
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
20 #include <GeomAPI_Face.h>
21
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>
28
29 #include <SketchPlugin_SketchEntity.h>
30 #include <FeaturesPlugin_CompositeBoolean.h>
31
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>
37
38 #include <Events_Loop.h>
39
40 #include <QLabel>
41 #include <QLineEdit>
42 //#include <QFormLayout>
43 #include <QVBoxLayout>
44 #include <QMessageBox>
45
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)
51 {
52   myAttributeListID = theData->getProperty("attribute_list_id");
53
54   //QFormLayout* aLayout = new QFormLayout(this);
55   QVBoxLayout* aLayout = new QVBoxLayout(this);
56   ModuleBase_Tools::zeroMargins(aLayout);
57
58   ModuleBase_Tools::adjustMargins(aLayout);
59
60   QString aLabelText = QString::fromStdString(theData->widgetLabel());
61   QString aLabelIcon = QString::fromStdString(theData->widgetIcon());
62
63   myLabel = new QLabel(aLabelText, this);
64   myLabel->setWordWrap(true);
65   aLayout->addWidget(myLabel);
66   /*if (!aLabelIcon.isEmpty())
67     myLabel->setPixmap(QPixmap(aLabelIcon));
68
69
70   QString aToolTip = QString::fromStdString(theData->widgetTooltip());
71   myTextLine = new QLineEdit(this);
72   myTextLine->setReadOnly(true);
73   myTextLine->setToolTip(aToolTip);
74   myTextLine->installEventFilter(this);
75
76   myLabel->setToolTip(aToolTip);
77
78   QString aUseBody = QString::fromStdString(theData->getProperty(USE_BODY));
79   if(!aUseBody.isEmpty()) {
80     myUseBody = QVariant(aUseBody).toBool();
81   }
82
83   aLayout->addRow(myLabel, myTextLine);*/
84
85   std::string aTypes = theData->getProperty("shape_types");
86   myShapeTypes = QString(aTypes.c_str()).split(' ', QString::SkipEmptyParts);
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::activateCustom()
117 {
118   if (isSelectionMode()) {
119     ModuleBase_WidgetSelector::activateCustom();
120     //connect(myModule, SIGNAL(operationLaunched()), SLOT(onStarted()));
121
122     //setVisibleSelectionControl(true);
123   }
124   //else {
125   //  setVisibleSelectionControl(false);
126   //  emit focusOutWidget(this);
127   //}
128 }
129
130 void PartSet_WidgetSketchCreator::setVisibleSelectionControl(const bool theSelectionControl)
131 {
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
139       if (aWidget != this)
140         aWidget->setVisible(false);
141     }
142     else { // hide current control
143       if (aWidget == this)
144         aWidget->setVisible(false);
145       else
146         aWidget->setVisible(true);
147     }
148   }
149 }
150
151 QIntList PartSet_WidgetSketchCreator::getShapeTypes() const
152 {
153   QIntList aShapeTypes;
154   foreach(QString aType, myShapeTypes) {
155     aShapeTypes.append(ModuleBase_Tools::shapeType(aType));
156   }
157   return aShapeTypes;
158 }
159
160 void PartSet_WidgetSketchCreator::deactivate()
161 {
162   if (isSelectionMode()) {
163     ModuleBase_WidgetSelector::activateCustom();
164   }
165 }
166
167 bool PartSet_WidgetSketchCreator::isSelectionMode() const
168 {
169   //CompositeFeaturePtr aCompFeature =
170   //  std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(myFeature);
171   //bool aHasSub = aCompFeature->numberOfSubs() > 0;
172
173   AttributeSelectionListPtr anAttrList = myFeature->data()->selectionList(myAttributeListID);
174   bool aHasValueInList = anAttrList.get() && anAttrList->size() > 0;
175
176   return !aHasValueInList;//aHasSub || aHasValueInList;
177 }
178
179 void PartSet_WidgetSketchCreator::onSelectionChanged()
180 {
181   QList<ModuleBase_ViewerPrs> aSelected = getFilteredSelected();
182
183   if (aSelected.size() == 1) { // plane or planar face of not sketch object
184     startSketchOperation(aSelected.front());
185   }
186   else if (aSelected.size() > 1) {
187     QList<ModuleBase_ViewerPrs>::const_iterator anIt = aSelected.begin(), aLast = aSelected.end();
188     bool aProcessed;
189     for (; anIt != aLast; anIt++) {
190       ModuleBase_ViewerPrs aValue = *anIt;
191       if (isValidInFilters(aValue))
192         aProcessed = setSelectionCustom(aValue);
193     }
194     if (aProcessed) {
195       emit valuesChanged();
196       updateObject(myFeature);
197       setVisibleSelectionControl(false);
198       emit focusOutWidget(this);
199     }
200   }
201 }
202
203 //********************************************************************
204 void PartSet_WidgetSketchCreator::setObject(ObjectPtr theSelectedObject,
205                                             GeomShapePtr theShape)
206 {
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);
217     }
218   }
219 }
220 void PartSet_WidgetSketchCreator::onStarted()
221 {
222   disconnect(myModule, SIGNAL(operationLaunched()), this, SLOT(onStarted()));
223
224   setVisibleSelectionControl(true);
225 }
226
227 void PartSet_WidgetSketchCreator::startSketchOperation(const ModuleBase_ViewerPrs& theValue)
228 {
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;
235   ResultBodyPtr aBody;
236   if(!aHasBody) {
237     foreach(ObjectPtr aObj, aObjList) {
238       aBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(aObj);
239       if (aBody.get() != NULL) {
240         aHasBody = true;
241         break;
242       }
243     }
244   }*/
245
246   //if (aHasBody) {
247     // Launch Sketch operation
248     CompositeFeaturePtr aCompFeature = 
249       std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(myFeature);
250
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");
258
259     PartSet_WidgetSketchLabel::fillSketchPlaneBySelection(aSketch, theValue);
260
261     aDoc->setCurrentFeature(aPreviousCurrentFeature, false);
262
263     // start edit operation for the sketch
264     ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
265                                                              (myModule->createOperation("Sketch"));
266     if (aFOperation)
267       aFOperation->setFeature(aSketch);
268     myModule->sendOperation(aFOperation);
269     //connect(anOperation, SIGNAL(aborted()), aWorkshop->operationMgr(), SLOT(abortAllOperations()));
270   //}
271   /* else {
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();
278     aOp->abort();
279   }*/
280 }
281
282 bool PartSet_WidgetSketchCreator::focusTo()
283 {
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()
292     activate();
293     return true;
294   }
295   else {
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();
300     if (!aIsOp) {
301       const static std::string aNestedOpID("Parameters modification");
302       aMgr->startOperation(aNestedOpID, true);
303     }
304     restoreValue();
305   }
306   return false;
307 }
308
309 void PartSet_WidgetSketchCreator::onResumed(ModuleBase_Operation* theOp)
310 {
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) {
316     // Abort operation
317     SessionPtr aMgr = ModelAPI_Session::get();
318     // Close transaction
319     /*
320     bool aIsOp = aMgr->isOperation();
321     if (aIsOp) {
322       const static std::string aNestedOpID("Parameters cancelation");
323       aMgr->startOperation(aNestedOpID, true);
324     }
325     */
326     theOp->abort();
327   } else {
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);
333     }
334     aSketchFeature->setDisplayed(false);
335
336     if(myUseBody) {
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();
345         if (aRes.get()) {
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);
355           else
356             aSelList->clear();
357         }
358       }
359     }
360     else {
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());
366     }
367   }
368 }