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