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