Salome HOME
cecf69f4dd94c001d488fea56d239644dd23fa65
[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 #include <XGUI_Tools.h>
20
21 #include <GeomAPI_Face.h>
22
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>
29
30 #include <SketchPlugin_SketchEntity.h>
31 #include <FeaturesPlugin_CompositeBoolean.h>
32
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>
38
39 #include <Events_Loop.h>
40
41 #include <QLabel>
42 #include <QLineEdit>
43 //#include <QFormLayout>
44 #include <QVBoxLayout>
45 #include <QMessageBox>
46
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)
52 {
53   myAttributeListID = theData->getProperty("attribute_list_id");
54
55   //QFormLayout* aLayout = new QFormLayout(this);
56   QVBoxLayout* aLayout = new QVBoxLayout(this);
57   ModuleBase_Tools::zeroMargins(aLayout);
58
59   ModuleBase_Tools::adjustMargins(aLayout);
60
61   QString aLabelText = QString::fromStdString(theData->widgetLabel());
62   QString aLabelIcon = QString::fromStdString(theData->widgetIcon());
63
64   myLabel = new QLabel(aLabelText, this);
65   myLabel->setWordWrap(true);
66   aLayout->addWidget(myLabel);
67   /*if (!aLabelIcon.isEmpty())
68     myLabel->setPixmap(QPixmap(aLabelIcon));
69
70
71   QString aToolTip = QString::fromStdString(theData->widgetTooltip());
72   myTextLine = new QLineEdit(this);
73   myTextLine->setReadOnly(true);
74   myTextLine->setToolTip(aToolTip);
75   myTextLine->installEventFilter(this);
76
77   myLabel->setToolTip(aToolTip);
78
79   QString aUseBody = QString::fromStdString(theData->getProperty(USE_BODY));
80   if(!aUseBody.isEmpty()) {
81     myUseBody = QVariant(aUseBody).toBool();
82   }
83
84   aLayout->addRow(myLabel, myTextLine);*/
85
86   std::string aTypes = theData->getProperty("shape_types");
87   myShapeTypes = QString(aTypes.c_str()).split(' ', QString::SkipEmptyParts);
88 }
89
90 PartSet_WidgetSketchCreator::~PartSet_WidgetSketchCreator()
91 {
92 }
93
94 QList<QWidget*> PartSet_WidgetSketchCreator::getControls() const
95 {
96   QList<QWidget*> aControls;
97   aControls.append(myLabel);
98   return aControls;
99 }
100
101 bool PartSet_WidgetSketchCreator::restoreValueCustom()
102 {
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()));
108   }*/
109   return true;
110 }
111
112 bool PartSet_WidgetSketchCreator::storeValueCustom() const
113 {
114   return true;
115 }
116
117 void PartSet_WidgetSketchCreator::setVisibleSelectionControl(const bool theSelectionControl)
118 {
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
125       if (aWidget != this)
126         aWidget->setVisible(false);
127     }
128     else { // hide current control
129       if (aWidget == this)
130         aWidget->setVisible(false);
131       else
132         aWidget->setVisible(true);
133     }
134   }
135 }
136
137 QIntList PartSet_WidgetSketchCreator::getShapeTypes() const
138 {
139   QIntList aShapeTypes;
140   foreach(QString aType, myShapeTypes) {
141     aShapeTypes.append(ModuleBase_Tools::shapeType(aType));
142   }
143   return aShapeTypes;
144 }
145
146 void PartSet_WidgetSketchCreator::setEditingMode(bool isEditing)
147 {
148   ModuleBase_ModelWidget::setEditingMode(isEditing);
149   if (isEditing)
150     setVisibleSelectionControl(false);
151 }
152
153 bool PartSet_WidgetSketchCreator::isSelectionMode() const
154 {
155   AttributeSelectionListPtr anAttrList = myFeature->data()->selectionList(myAttributeListID);
156   bool aHasValueInList = anAttrList.get() && anAttrList->size() > 0;
157
158   return !aHasValueInList;
159 }
160
161 void PartSet_WidgetSketchCreator::onSelectionChanged()
162 {
163   QList<ModuleBase_ViewerPrs> aSelected = getFilteredSelected();
164
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;
172     }
173     if (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
178       deactivate();
179       emit focusOutWidget(this);
180     }
181   }
182 }
183
184 //********************************************************************
185 void PartSet_WidgetSketchCreator::setObject(ObjectPtr theSelectedObject,
186                                             GeomShapePtr theShape)
187 {
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);
198     }
199   }
200 }
201
202 bool PartSet_WidgetSketchCreator::startSketchOperation(const QList<ModuleBase_ViewerPrs>& theValues)
203 {
204   bool aSketchStarted = false;
205
206   if (theValues.size() != 1)
207     return aSketchStarted;
208
209   ModuleBase_ViewerPrs aValue = theValues.front();
210   if (!PartSet_WidgetSketchLabel::canFillSketch(aValue))
211     return aSketchStarted;
212
213   aSketchStarted = true;
214
215   // manually deactivation because the widget was not activated as has no focus acceptin controls
216   deactivate();
217
218   // Launch Sketch operation
219   CompositeFeaturePtr aCompFeature = 
220     std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(myFeature);
221
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");
229
230   PartSet_WidgetSketchLabel::fillSketchPlaneBySelection(aSketch, aValue);
231
232   aDoc->setCurrentFeature(aPreviousCurrentFeature, false);
233
234   // start edit operation for the sketch
235   ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
236                                                             (myModule->createOperation("Sketch"));
237   if (aFOperation)
238     aFOperation->setFeature(aSketch);
239   myModule->sendOperation(aFOperation);
240
241   return aSketchStarted;
242 }
243
244 bool PartSet_WidgetSketchCreator::focusTo()
245 {
246   if (isSelectionMode()) {
247     setVisibleSelectionControl(true);
248
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()
251     activateCustom();
252     return true;
253   }
254   else {
255     setVisibleSelectionControl(false);
256
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();
261     if (!aIsOp) {
262       const static std::string aNestedOpID("Parameters modification");
263       aMgr->startOperation(aNestedOpID, true);
264     }
265     restoreValue();
266   }
267   return false;
268 }
269
270 void PartSet_WidgetSketchCreator::onResumed(ModuleBase_Operation* theOp)
271 {
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
278
279     // Abort operation
280     //SessionPtr aMgr = ModelAPI_Session::get();
281     // Close transaction
282     /*
283     bool aIsOp = aMgr->isOperation();
284     if (aIsOp) {
285       const static std::string aNestedOpID("Parameters cancelation");
286       aMgr->startOperation(aNestedOpID, true);
287     }
288     */
289     //theOp->abort();
290   } else {
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();
298     }
299
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);
305     }
306     aSketchFeature->setDisplayed(false);
307
308     // restore value in the selection control
309
310
311     // Add Selected body were created the sketcher to list of selected objects
312     if(myUseBody) {
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();
320         if (aRes.get()) {
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);
328           else
329             aSelList->clear();
330         }
331       }
332     }
333     else {
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());
339     }
340   }
341 }