Salome HOME
308dd965f0f544f8e1d579071a0bb958266e6715
[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
18 #include <GeomAPI_Face.h>
19
20 #include <ModelAPI_Session.h>
21 #include <ModelAPI_ResultBody.h>
22 #include <ModelAPI_AttributeSelection.h>
23 #include <ModelAPI_AttributeSelectionList.h>
24 #include <ModelAPI_Validator.h>
25 #include <ModelAPI_Events.h>
26
27 #include <SketchPlugin_SketchEntity.h>
28 #include <FeaturesPlugin_CompositeBoolean.h>
29
30 #include <ModuleBase_Tools.h>
31 #include <ModuleBase_Operation.h>
32 #include <ModuleBase_IPropertyPanel.h>
33 #include <ModuleBase_OperationFeature.h>
34 #include <Config_WidgetAPI.h>
35
36 #include <Events_Loop.h>
37
38 #include <QLabel>
39 #include <QLineEdit>
40 #include <QFormLayout>
41 #include <QMessageBox>
42
43 PartSet_WidgetSketchCreator::PartSet_WidgetSketchCreator(QWidget* theParent, 
44                                                          PartSet_Module* theModule,
45                                                          const Config_WidgetAPI* theData,
46                                                          const std::string& theParentId)
47 : ModuleBase_ModelWidget(theParent, theData, theParentId), myModule(theModule), myUseBody(true)
48 {
49   QFormLayout* aLayout = new QFormLayout(this);
50   ModuleBase_Tools::adjustMargins(aLayout);
51
52   QString aLabelText = QString::fromStdString(theData->widgetLabel());
53   QString aLabelIcon = QString::fromStdString(theData->widgetIcon());
54   myLabel = new QLabel(aLabelText, this);
55   if (!aLabelIcon.isEmpty())
56     myLabel->setPixmap(QPixmap(aLabelIcon));
57
58
59   QString aToolTip = QString::fromStdString(theData->widgetTooltip());
60   myTextLine = new QLineEdit(this);
61   myTextLine->setReadOnly(true);
62   myTextLine->setToolTip(aToolTip);
63   myTextLine->installEventFilter(this);
64
65   myLabel->setToolTip(aToolTip);
66
67   QString aUseBody = QString::fromStdString(theData->getProperty(USE_BODY));
68   if(!aUseBody.isEmpty()) {
69     myUseBody = QVariant(aUseBody).toBool();
70   }
71
72   aLayout->addRow(myLabel, myTextLine);
73 }
74
75 PartSet_WidgetSketchCreator::~PartSet_WidgetSketchCreator()
76 {
77 }
78
79 QList<QWidget*> PartSet_WidgetSketchCreator::getControls() const
80 {
81   QList<QWidget*> aControls;
82   aControls.append(myTextLine);
83   return aControls;
84 }
85
86 bool PartSet_WidgetSketchCreator::restoreValueCustom()
87 {
88   CompositeFeaturePtr aCompFeature = 
89     std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(myFeature);
90   if (aCompFeature->numberOfSubs() > 0) {
91     FeaturePtr aSubFeature = aCompFeature->subFeature(0);
92     myTextLine->setText(QString::fromStdString(aSubFeature->data()->name()));
93   }
94   return true;
95 }
96
97 bool PartSet_WidgetSketchCreator::storeValueCustom() const
98 {
99   return true;
100 }
101
102 void PartSet_WidgetSketchCreator::activateCustom()
103 {
104   CompositeFeaturePtr aCompFeature = 
105     std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(myFeature);
106   if (aCompFeature->numberOfSubs() == 0)
107     connect(myModule, SIGNAL(operationLaunched()), SLOT(onStarted()));
108 }
109
110 void PartSet_WidgetSketchCreator::onStarted()
111 {
112   disconnect(myModule, SIGNAL(operationLaunched()), this, SLOT(onStarted()));
113
114   // Check that model already has bodies
115   XGUI_ModuleConnector* aConnector = dynamic_cast<XGUI_ModuleConnector*>(myModule->workshop());
116   XGUI_Workshop* aWorkshop = aConnector->workshop();
117   XGUI_Displayer* aDisp = aWorkshop->displayer();
118   QObjectPtrList aObjList = aDisp->displayedObjects();
119   bool aHasBody = !myUseBody;
120   ResultBodyPtr aBody;
121   if(!aHasBody) {
122     foreach(ObjectPtr aObj, aObjList) {
123       aBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(aObj);
124       if (aBody.get() != NULL) {
125         aHasBody = true;
126         break;
127       }
128     }
129   }
130
131   if (aHasBody) {
132     // Launch Sketch operation
133     CompositeFeaturePtr aCompFeature = 
134       std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(myFeature);
135
136     /// add sketch feature without current feature change.
137     /// it is important to do not change the current feature in order to
138     /// after sketch edition, the extrusion cut feature becomes current
139     SessionPtr aMgr = ModelAPI_Session::get();
140     DocumentPtr aDoc = aMgr->activeDocument();
141     FeaturePtr aPreviousCurrentFeature = aDoc->currentFeature(false);
142     FeaturePtr aSketch = aCompFeature->addFeature("Sketch");
143     aDoc->setCurrentFeature(aPreviousCurrentFeature, false);
144
145     // start edit operation for the sketch
146     ModuleBase_OperationFeature* aFOperation = dynamic_cast<ModuleBase_OperationFeature*>
147                                                              (myModule->createOperation("Sketch"));
148     if (aFOperation)
149       aFOperation->setFeature(aSketch);
150     myModule->sendOperation(aFOperation);
151     //connect(anOperation, SIGNAL(aborted()), aWorkshop->operationMgr(), SLOT(abortAllOperations()));
152   } else {
153     // Break current operation
154     std::string anOperationName = feature()->getKind();
155     QString aTitle = tr( anOperationName.c_str() );
156     QMessageBox::warning(this, aTitle,
157         tr("There are no bodies found. Operation aborted."), QMessageBox::Ok);
158     ModuleBase_Operation* aOp = myModule->workshop()->currentOperation();
159     aOp->abort();
160   }
161 }
162
163 bool PartSet_WidgetSketchCreator::focusTo()
164 {
165   CompositeFeaturePtr aCompFeature = 
166     std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(myFeature);
167   if (aCompFeature->numberOfSubs() == 0)
168     return ModuleBase_ModelWidget::focusTo(); 
169
170   connect(myModule, SIGNAL(resumed(ModuleBase_Operation*)), SLOT(onResumed(ModuleBase_Operation*)));
171   SessionPtr aMgr = ModelAPI_Session::get();
172   // Open transaction that is general for the previous nested one: it will be closed on nested commit
173   bool aIsOp = aMgr->isOperation();
174   if (!aIsOp) {
175     const static std::string aNestedOpID("Parameters modification");
176     aMgr->startOperation(aNestedOpID, true);
177   }
178
179   restoreValue();
180   return false;
181 }
182
183 void PartSet_WidgetSketchCreator::onResumed(ModuleBase_Operation* theOp)
184 {
185   CompositeFeaturePtr aCompFeature = 
186     std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(myFeature);
187   CompositeFeaturePtr aSketchFeature = 
188     std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(aCompFeature->subFeature(0));
189   if (aSketchFeature->numberOfSubs() == 0) {
190     // Abort operation
191     SessionPtr aMgr = ModelAPI_Session::get();
192     // Close transaction
193     /*
194     bool aIsOp = aMgr->isOperation();
195     if (aIsOp) {
196       const static std::string aNestedOpID("Parameters cancelation");
197       aMgr->startOperation(aNestedOpID, true);
198     }
199     */
200     theOp->abort();
201   } else {
202     // Hide sketcher result
203     std::list<ResultPtr> aResults = aSketchFeature->results();
204     std::list<ResultPtr>::const_iterator aIt;
205     for (aIt = aResults.begin(); aIt != aResults.end(); ++aIt) {
206       (*aIt)->setDisplayed(false);
207     }
208     aSketchFeature->setDisplayed(false);
209
210     if(myUseBody) {
211       // Add Selected body were created the sketcher to list of selected objects
212       DataPtr aData = aSketchFeature->data();
213       AttributeSelectionPtr aSelAttr = 
214         std::dynamic_pointer_cast<ModelAPI_AttributeSelection>
215         (aData->attribute(SketchPlugin_SketchEntity::EXTERNAL_ID()));
216       if (aSelAttr.get()) {
217         ResultPtr aRes = aSelAttr->context();
218         GeomShapePtr aShape = aSelAttr->value();
219         if (aRes.get()) {
220           std::string anObjectsAttribute = FeaturesPlugin_CompositeBoolean::BOOLEAN_OBJECTS_ID();
221           SessionPtr aMgr = ModelAPI_Session::get();
222           ModelAPI_ValidatorsFactory* aFactory = aMgr->validators();
223           AttributePtr anAttribute = myFeature->attribute(anObjectsAttribute);
224           std::string aValidatorID, anError;
225           AttributeSelectionListPtr aSelList = aCompFeature->data()->selectionList(anObjectsAttribute);
226           aSelList->append(aRes, GeomShapePtr());
227           if (aFactory->validate(anAttribute, aValidatorID, anError))
228             updateObject(aCompFeature);
229           else
230             aSelList->clear();
231         }
232       }
233     }
234     else {
235       // this is a workarount to display the feature results in the operation selection mode
236       // if this is absent, sketch point/line local selection is available on extrusion cut result
237       static Events_ID anUpdateEvent = Events_Loop::eventByName(EVENT_OBJECT_UPDATED);
238       ModelAPI_EventCreator::get()->sendUpdated(feature(), anUpdateEvent);
239       updateObject(feature());
240     }
241   }
242 }