]> SALOME platform Git repositories - modules/shaper.git/blob - src/PartSet/PartSet_WidgetSketchCreator.cpp
Salome HOME
71069fe365f10c0bb4e79025aaf201f3eda19782
[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
10 #include <Config_Keywords.h>
11
12 #include <XGUI_ModuleConnector.h>
13 #include <XGUI_Workshop.h>
14 #include <XGUI_Displayer.h>
15 #include <XGUI_SelectionMgr.h>
16 #include <XGUI_OperationMgr.h>
17 #include <XGUI_PropertyPanel.h>
18
19 #include <GeomAPI_Face.h>
20
21 #include <ModelAPI_Session.h>
22 #include <ModelAPI_ResultBody.h>
23 #include <ModelAPI_AttributeSelection.h>
24 #include <ModelAPI_AttributeSelectionList.h>
25 #include <ModelAPI_Validator.h>
26 #include <ModelAPI_Events.h>
27
28 #include <SketchPlugin_SketchEntity.h>
29 #include <FeaturesPlugin_CompositeBoolean.h>
30
31 #include <ModuleBase_Tools.h>
32 #include <ModuleBase_Operation.h>
33 #include <ModuleBase_IPropertyPanel.h>
34 #include <ModuleBase_OperationFeature.h>
35 #include <Config_WidgetAPI.h>
36
37 #include <Events_Loop.h>
38
39 #include <QLabel>
40 #include <QLineEdit>
41 //#include <QFormLayout>
42 #include <QVBoxLayout>
43 #include <QMessageBox>
44
45 PartSet_WidgetSketchCreator::PartSet_WidgetSketchCreator(QWidget* theParent, 
46                                                          PartSet_Module* theModule,
47                                                          const Config_WidgetAPI* theData)
48 : ModuleBase_WidgetSelector(theParent, theModule->workshop(), theData),
49   myModule(theModule), myUseBody(true)
50 {
51   myAttributeListID = theData->getProperty("attribute_list_id");
52
53   //QFormLayout* aLayout = new QFormLayout(this);
54   QVBoxLayout* aLayout = new QVBoxLayout(this);
55   ModuleBase_Tools::zeroMargins(aLayout);
56
57   ModuleBase_Tools::adjustMargins(aLayout);
58
59   QString aLabelText = QString::fromStdString(theData->widgetLabel());
60   QString aLabelIcon = QString::fromStdString(theData->widgetIcon());
61
62   myLabel = new QLabel(aLabelText, this);
63   myLabel->setWordWrap(true);
64   aLayout->addWidget(myLabel);
65   /*if (!aLabelIcon.isEmpty())
66     myLabel->setPixmap(QPixmap(aLabelIcon));
67
68
69   QString aToolTip = QString::fromStdString(theData->widgetTooltip());
70   myTextLine = new QLineEdit(this);
71   myTextLine->setReadOnly(true);
72   myTextLine->setToolTip(aToolTip);
73   myTextLine->installEventFilter(this);
74
75   myLabel->setToolTip(aToolTip);
76
77   QString aUseBody = QString::fromStdString(theData->getProperty(USE_BODY));
78   if(!aUseBody.isEmpty()) {
79     myUseBody = QVariant(aUseBody).toBool();
80   }
81
82   aLayout->addRow(myLabel, myTextLine);*/
83
84   std::string aTypes = theData->getProperty("shape_types");
85   myShapeTypes = QString(aTypes.c_str()).split(' ', QString::SkipEmptyParts);
86 }
87
88 PartSet_WidgetSketchCreator::~PartSet_WidgetSketchCreator()
89 {
90 }
91
92 QList<QWidget*> PartSet_WidgetSketchCreator::getControls() const
93 {
94   QList<QWidget*> aControls;
95   aControls.append(myLabel);
96   return aControls;
97 }
98
99 bool PartSet_WidgetSketchCreator::restoreValueCustom()
100 {
101   /*CompositeFeaturePtr aCompFeature = 
102     std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(myFeature);
103   if (aCompFeature->numberOfSubs() > 0) {
104     FeaturePtr aSubFeature = aCompFeature->subFeature(0);
105     myTextLine->setText(QString::fromStdString(aSubFeature->data()->name()));
106   }*/
107   return true;
108 }
109
110 bool PartSet_WidgetSketchCreator::storeValueCustom() const
111 {
112   return true;
113 }
114
115 void PartSet_WidgetSketchCreator::activateCustom()
116 {
117   if (isSelectionMode()) {
118     ModuleBase_WidgetSelector::activateCustom();
119     //connect(myModule, SIGNAL(operationLaunched()), SLOT(onStarted()));
120
121     //setVisibleSelectionControl(true);
122   }
123   //else {
124   //  setVisibleSelectionControl(false);
125   //  emit focusOutWidget(this);
126   //}
127 }
128
129 void PartSet_WidgetSketchCreator::setVisibleSelectionControl(const bool theSelectionControl)
130 {
131   // hide current widget, activate the next widget
132   XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(myModule->workshop());
133   XGUI_Workshop* aWorkshop = aConnector->workshop();
134   XGUI_PropertyPanel* aPanel = aWorkshop->propertyPanel();
135   const QList<ModuleBase_ModelWidget*>& aWidgets = aPanel->modelWidgets();
136   foreach(ModuleBase_ModelWidget* aWidget, aWidgets) {
137     if (theSelectionControl) { // hide other controls
138       if (aWidget != this)
139         aWidget->setVisible(false);
140     }
141     else { // hide current control
142       if (aWidget == this)
143         aWidget->setVisible(false);
144       else
145         aWidget->setVisible(true);
146     }
147   }
148 }
149
150 QIntList PartSet_WidgetSketchCreator::getShapeTypes() const
151 {
152   QIntList aShapeTypes;
153   foreach(QString aType, myShapeTypes) {
154     aShapeTypes.append(ModuleBase_Tools::shapeType(aType));
155   }
156   return aShapeTypes;
157 }
158
159 void PartSet_WidgetSketchCreator::deactivate()
160 {
161   if (isSelectionMode()) {
162     ModuleBase_WidgetSelector::activateCustom();
163   }
164 }
165
166 bool PartSet_WidgetSketchCreator::isSelectionMode() const
167 {
168   //CompositeFeaturePtr aCompFeature =
169   //  std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(myFeature);
170   //bool aHasSub = aCompFeature->numberOfSubs() > 0;
171
172   AttributeSelectionListPtr anAttrList = myFeature->data()->selectionList(myAttributeListID);
173   bool aHasValueInList = anAttrList.get() && anAttrList->size() > 0;
174
175   return !aHasValueInList;//aHasSub || aHasValueInList;
176 }
177
178 void PartSet_WidgetSketchCreator::onSelectionChanged()
179 {
180   QList<ModuleBase_ViewerPrs> aSelected = getFilteredSelected();
181
182   if (aSelected.size() == 1) { // plane or planar face of not sketch object
183     startSketchOperation();
184   }
185   else if (aSelected.size() > 1) {
186     QList<ModuleBase_ViewerPrs>::const_iterator anIt = aSelected.begin(), aLast = aSelected.end();
187     bool aProcessed;
188     for (; anIt != aLast; anIt++) {
189       ModuleBase_ViewerPrs aValue = *anIt;
190       if (isValidInFilters(aValue))
191         aProcessed = setSelectionCustom(aValue);
192     }
193     if (aProcessed) {
194       emit valuesChanged();
195       updateObject(myFeature);
196       setVisibleSelectionControl(false);
197       emit focusOutWidget(this);
198     }
199   }
200 }
201
202 //********************************************************************
203 void PartSet_WidgetSketchCreator::setObject(ObjectPtr theSelectedObject,
204                                             GeomShapePtr theShape)
205 {
206   std::string anAttributeId = myAttributeListID;
207   DataPtr aData = myFeature->data();
208   AttributePtr anAttribute = aData->attribute(anAttributeId);
209   if (anAttribute.get()) {
210     std::string aType = anAttribute->attributeType();
211     if (aType == ModelAPI_AttributeSelectionList::typeId()) {
212       AttributeSelectionListPtr aSelectionListAttr = aData->selectionList(anAttributeId);
213       ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(theSelectedObject);
214       if (!aSelectionListAttr->isInList(aResult, theShape, myIsInValidate))
215         aSelectionListAttr->append(aResult, theShape, myIsInValidate);
216     }
217   }
218 }
219 void PartSet_WidgetSketchCreator::onStarted()
220 {
221   disconnect(myModule, SIGNAL(operationLaunched()), this, SLOT(onStarted()));
222
223   setVisibleSelectionControl(true);
224 }
225
226 void PartSet_WidgetSketchCreator::startSketchOperation()
227 {
228   // Check that model already has bodies
229   /*XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(myModule->workshop());
230   XGUI_Workshop* aWorkshop = aConnector->workshop();
231   XGUI_Displayer* aDisp = aWorkshop->displayer();
232   QObjectPtrList aObjList = aDisp->displayedObjects();
233   bool aHasBody = !myUseBody;
234   ResultBodyPtr aBody;
235   if(!aHasBody) {
236     foreach(ObjectPtr aObj, aObjList) {
237       aBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(aObj);
238       if (aBody.get() != NULL) {
239         aHasBody = true;
240         break;
241       }
242     }
243   }*/
244
245   //if (aHasBody) {
246     // Launch Sketch operation
247     CompositeFeaturePtr aCompFeature = 
248       std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(myFeature);
249
250     /// add sketch feature without current feature change.
251     /// it is important to do not change the current feature in order to
252     /// after sketch edition, the extrusion cut feature becomes current
253     SessionPtr aMgr = ModelAPI_Session::get();
254     DocumentPtr aDoc = aMgr->activeDocument();
255     FeaturePtr aPreviousCurrentFeature = aDoc->currentFeature(false);
256     FeaturePtr aSketch = aCompFeature->addFeature("Sketch");
257     aDoc->setCurrentFeature(aPreviousCurrentFeature, false);
258
259     // start edit operation for the sketch
260     ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
261                                                              (myModule->createOperation("Sketch"));
262     if (aFOperation)
263       aFOperation->setFeature(aSketch);
264     myModule->sendOperation(aFOperation);
265     //connect(anOperation, SIGNAL(aborted()), aWorkshop->operationMgr(), SLOT(abortAllOperations()));
266   //}
267   /* else {
268     // Break current operation
269     std::string anOperationName = feature()->getKind();
270     QString aTitle = tr( anOperationName.c_str() );
271     QMessageBox::warning(this, aTitle,
272         tr("There are no bodies found. Operation aborted."), QMessageBox::Ok);
273     ModuleBase_Operation* aOp = myModule->workshop()->currentOperation();
274     aOp->abort();
275   }*/
276 }
277
278 bool PartSet_WidgetSketchCreator::focusTo()
279 {
280   if (isSelectionMode()) {
281     //CompositeFeaturePtr aCompFeature = 
282     //   std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(myFeature);
283     // if (aCompFeature->numberOfSubs() == 0)
284     //   return ModuleBase_ModelWidget::focusTo(); 
285     connect(myModule, SIGNAL(operationLaunched()), SLOT(onStarted()));
286     // we need to call activate here as the widget has no focus accepted controls
287     // if these controls are added here, activate will happens automatically after focusIn()
288     activate();
289     return true;
290   }
291   else {
292     connect(myModule, SIGNAL(resumed(ModuleBase_Operation*)), SLOT(onResumed(ModuleBase_Operation*)));
293     SessionPtr aMgr = ModelAPI_Session::get();
294     // Open transaction that is general for the previous nested one: it will be closed on nested commit
295     bool aIsOp = aMgr->isOperation();
296     if (!aIsOp) {
297       const static std::string aNestedOpID("Parameters modification");
298       aMgr->startOperation(aNestedOpID, true);
299     }
300     restoreValue();
301   }
302   return false;
303 }
304
305 void PartSet_WidgetSketchCreator::onResumed(ModuleBase_Operation* theOp)
306 {
307   CompositeFeaturePtr aCompFeature = 
308     std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(myFeature);
309   CompositeFeaturePtr aSketchFeature = 
310     std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(aCompFeature->subFeature(0));
311   if (aSketchFeature->numberOfSubs() == 0) {
312     // Abort operation
313     SessionPtr aMgr = ModelAPI_Session::get();
314     // Close transaction
315     /*
316     bool aIsOp = aMgr->isOperation();
317     if (aIsOp) {
318       const static std::string aNestedOpID("Parameters cancelation");
319       aMgr->startOperation(aNestedOpID, true);
320     }
321     */
322     theOp->abort();
323   } else {
324     // Hide sketcher result
325     std::list<ResultPtr> aResults = aSketchFeature->results();
326     std::list<ResultPtr>::const_iterator aIt;
327     for (aIt = aResults.begin(); aIt != aResults.end(); ++aIt) {
328       (*aIt)->setDisplayed(false);
329     }
330     aSketchFeature->setDisplayed(false);
331
332     if(myUseBody) {
333       // Add Selected body were created the sketcher to list of selected objects
334       DataPtr aData = aSketchFeature->data();
335       AttributeSelectionPtr aSelAttr = 
336         std::dynamic_pointer_cast<ModelAPI_AttributeSelection>
337         (aData->attribute(SketchPlugin_SketchEntity::EXTERNAL_ID()));
338       if (aSelAttr.get()) {
339         ResultPtr aRes = aSelAttr->context();
340         GeomShapePtr aShape = aSelAttr->value();
341         if (aRes.get()) {
342           std::string anObjectsAttribute = FeaturesPlugin_CompositeBoolean::BOOLEAN_OBJECTS_ID();
343           SessionPtr aMgr = ModelAPI_Session::get();
344           ModelAPI_ValidatorsFactory* aFactory = aMgr->validators();
345           AttributePtr anAttribute = myFeature->attribute(anObjectsAttribute);
346           std::string aValidatorID, anError;
347           AttributeSelectionListPtr aSelList = aCompFeature->data()->selectionList(anObjectsAttribute);
348           aSelList->append(aRes, GeomShapePtr());
349           if (aFactory->validate(anAttribute, aValidatorID, anError))
350             updateObject(aCompFeature);
351           else
352             aSelList->clear();
353         }
354       }
355     }
356     else {
357       // this is a workarount to display the feature results in the operation selection mode
358       // if this is absent, sketch point/line local selection is available on extrusion cut result
359       static Events_ID anUpdateEvent = Events_Loop::eventByName(EVENT_OBJECT_UPDATED);
360       ModelAPI_EventCreator::get()->sendUpdated(feature(), anUpdateEvent);
361       updateObject(feature());
362     }
363   }
364 }