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