]> SALOME platform Git repositories - modules/shaper.git/blob - src/ModuleBase/ModuleBase_WidgetSelector.cpp
Salome HOME
Reusing SUIT libraries
[modules/shaper.git] / src / ModuleBase / ModuleBase_WidgetSelector.cpp
1 // File:        ModuleBase_WidgetSelector.h
2 // Created:     2 June 2014
3 // Author:      Vitaly Smetannikov
4
5
6 #include "ModuleBase_WidgetSelector.h"
7 #include "ModuleBase_IWorkshop.h"
8 #include "ModuleBase_Tools.h"
9
10 #include <Events_Loop.h>
11 #include <ModelAPI_Events.h>
12
13 #include <ModelAPI_Data.h>
14 #include <ModelAPI_Object.h>
15 #include <ModelAPI_Result.h>
16 #include <ModelAPI_AttributeReference.h>
17 #include <Config_WidgetAPI.h>
18
19 #include <GeomAPI_Shape.h>
20
21 #include <TopoDS_Shape.hxx>
22 #include <TopExp_Explorer.hxx>
23
24 #include <QWidget>
25 #include <QLayout>
26 #include <QLabel>
27 #include <QLineEdit>
28 #include <QToolButton>
29 #include <QString>
30 #include <QEvent>
31 #include <QDockWidget>
32
33 #include <stdexcept>
34
35
36 typedef QMap<QString, TopAbs_ShapeEnum> ShapeTypes;
37 static ShapeTypes MyShapeTypes;
38
39 TopAbs_ShapeEnum ModuleBase_WidgetSelector::shapeType(const QString& theType)
40 {
41   if (MyShapeTypes.count() == 0) {
42     MyShapeTypes["face"] = TopAbs_FACE;
43     MyShapeTypes["vertex"] = TopAbs_VERTEX;
44     MyShapeTypes["wire"] = TopAbs_WIRE;
45     MyShapeTypes["edge"] = TopAbs_EDGE;
46     MyShapeTypes["shell"] = TopAbs_SHELL;
47     MyShapeTypes["solid"] = TopAbs_SOLID;
48   }
49   if (MyShapeTypes.contains(theType)) 
50     return MyShapeTypes[theType];
51   throw std::invalid_argument("Shape type defined in XML is not implemented!");
52 }
53
54
55
56
57 ModuleBase_WidgetSelector::ModuleBase_WidgetSelector(QWidget* theParent, 
58                                                      ModuleBase_IWorkshop* theWorkshop, 
59                                                      const Config_WidgetAPI* theData,
60                                                      const std::string& theParentId)
61 : ModuleBase_ModelWidget(theParent, theData, theParentId), myWorkshop(theWorkshop), myActivateOnStart(false)
62 {
63   myContainer = new QWidget(theParent);
64   QHBoxLayout* aLayout = new QHBoxLayout(myContainer);
65
66   aLayout->setContentsMargins(0, 0, 0, 0);
67   QString aLabelText = QString::fromStdString(theData->widgetLabel());
68   QString aLabelIcon = QString::fromStdString(theData->widgetIcon());
69   myLabel = new QLabel(aLabelText, myContainer);
70   myLabel->setPixmap(QPixmap(aLabelIcon));
71
72   aLayout->addWidget(myLabel);
73
74   QString aToolTip = QString::fromStdString(theData->widgetTooltip());
75   myTextLine = new QLineEdit(myContainer);
76   myTextLine->setReadOnly(true);
77   myTextLine->setToolTip(aToolTip);
78   myTextLine->installEventFilter(this);
79
80   aLayout->addWidget(myTextLine);
81
82   myActivateBtn = new QToolButton(myContainer);
83   myActivateBtn->setIcon(QIcon(":icons/hand_point.png"));
84   myActivateBtn->setCheckable(true);
85   myActivateBtn->setToolTip(tr("Activate/Deactivate selection"));
86   connect(myActivateBtn, SIGNAL(toggled(bool)), this, SLOT(activateSelection(bool)));
87
88   aLayout->addWidget(myActivateBtn);
89
90   QString aActivateTxt = QString::fromStdString(theData->getProperty("activate"));
91   if (!aActivateTxt.isNull()) {
92     myActivateOnStart = (aActivateTxt == "true");
93   }
94
95   std::string aTypes = theData->getProperty("shape_types");
96   myShapeTypes = QString(aTypes.c_str()).split(',');
97 }
98
99 //********************************************************************
100 ModuleBase_WidgetSelector::~ModuleBase_WidgetSelector()
101 {
102 }
103
104 //********************************************************************
105 bool ModuleBase_WidgetSelector::storeValue(ObjectPtr theObject) const
106 {
107   FeaturePtr aSelectedFeature = ModuleBase_Tools::feature(mySelectedObject);
108   if (aSelectedFeature == theObject) // In order to avoid selection of the same object
109     return false;
110
111   DataPtr aData = theObject->data();
112   boost::shared_ptr<ModelAPI_AttributeReference> aRef = 
113     boost::dynamic_pointer_cast<ModelAPI_AttributeReference>(aData->attribute(attributeID()));
114
115   ObjectPtr aObject = aRef->value();
116   if (!(aObject && aObject->isSame(mySelectedObject))) {
117     aRef->setValue(mySelectedObject);
118     updateObject(theObject);
119   }
120   return true;
121 }
122
123 //********************************************************************
124 bool ModuleBase_WidgetSelector::restoreValue(ObjectPtr theObject)
125 {
126   DataPtr aData = theObject->data();
127   boost::shared_ptr<ModelAPI_AttributeReference> aRef = aData->reference(attributeID());
128
129   bool isBlocked = this->blockSignals(true);
130   mySelectedObject = aRef->value();
131   updateSelectionName(); 
132
133   this->blockSignals(isBlocked);
134   return true;
135 }
136
137 //********************************************************************
138 QList<QWidget*> ModuleBase_WidgetSelector::getControls() const
139 {
140   QList<QWidget*> aControls;
141   aControls.append(myLabel);
142   aControls.append(myTextLine);
143   aControls.append(myActivateBtn);
144   return aControls;
145 }
146
147 //********************************************************************
148 void ModuleBase_WidgetSelector::onSelectionChanged()
149 {
150   QList<ObjectPtr> aObjects = myWorkshop->selectedObjects();
151   if (aObjects.size() > 0) {
152     ObjectPtr aObject = aObjects.first();
153     if ((!mySelectedObject) && (!aObject))
154       return;
155     if (mySelectedObject && aObject && mySelectedObject->isSame(aObject))
156       return;
157
158     // Check that the selection corresponds to selection type
159     if (!isAccepted(aObject)) return;
160
161     mySelectedObject = aObject;
162     if (mySelectedObject) {
163       updateSelectionName();
164       myActivateBtn->setChecked(false);
165       raisePanel();
166     } else {
167       myTextLine->setText("");
168     }
169     emit valuesChanged();
170   }
171 }
172
173 //********************************************************************
174 bool ModuleBase_WidgetSelector::isAccepted(const ObjectPtr theResult) const
175 {
176   ResultPtr aResult = boost::dynamic_pointer_cast<ModelAPI_Result>(theResult);
177   boost::shared_ptr<GeomAPI_Shape> aShapePtr = ModuleBase_Tools::shape(aResult);
178   if (!aShapePtr) return false;
179   TopoDS_Shape aShape = aShapePtr->impl<TopoDS_Shape>();
180   if (aShape.IsNull()) return false;
181
182   TopAbs_ShapeEnum aShapeType = aShape.ShapeType();
183   if (aShapeType == TopAbs_COMPOUND) {
184     foreach (QString aType, myShapeTypes) {
185       TopExp_Explorer aEx(aShape, shapeType(aType));
186       if (aEx.More())
187         return true;
188     }
189   } else {
190     foreach (QString aType, myShapeTypes) {
191       if (shapeType(aType) == aShapeType)
192         return true;
193     }
194   }
195   return false;
196 }
197
198 //********************************************************************
199 void ModuleBase_WidgetSelector::updateSelectionName()
200 {
201   if (mySelectedObject) {
202     std::string aName = mySelectedObject->data()->name();
203  
204     myTextLine->setText(QString::fromStdString(aName));
205   } else 
206     myTextLine->setText("");
207 }
208
209 //********************************************************************
210 bool ModuleBase_WidgetSelector::eventFilter(QObject* theObj, QEvent* theEvent)
211 {
212   if (theObj == myTextLine) {
213     if (theEvent->type() == QEvent::Polish) {
214       myActivateBtn->setChecked(myActivateOnStart);
215       onSelectionChanged();
216     }
217   }
218   return ModuleBase_ModelWidget::eventFilter(theObj, theEvent);
219 }
220
221 //********************************************************************
222 void ModuleBase_WidgetSelector::enableOthersControls(bool toEnable) const
223 {
224   QWidget* aParent = myContainer->parentWidget();
225   QList<QWidget*> aChldList = aParent->findChildren<QWidget*>();
226   foreach(QWidget* aWgt, aChldList) {
227     if ((aWgt != myLabel) && (aWgt != myActivateBtn) && (aWgt != myTextLine) && (aWgt != myContainer))
228       aWgt->setEnabled(toEnable);
229   }
230 }
231
232 //********************************************************************
233 void ModuleBase_WidgetSelector::activateSelection(bool toActivate)
234 {
235   enableOthersControls(!toActivate);
236   myTextLine->setEnabled(toActivate);
237
238   if (toActivate)
239     connect(myWorkshop, SIGNAL(selectionChanged()), this, SLOT(onSelectionChanged()));
240   else
241     disconnect(myWorkshop, SIGNAL(selectionChanged()), this, SLOT(onSelectionChanged()));
242
243   myActivateBtn->setDown(toActivate);
244 }
245
246 //********************************************************************
247 void ModuleBase_WidgetSelector::raisePanel() const
248 {
249   QWidget* aParent = myContainer->parentWidget();
250   QWidget* aLastPanel = 0;
251   while (!aParent->inherits("QDockWidget")) {
252     aLastPanel = aParent;
253     aParent = aParent->parentWidget();
254     if (!aParent) return;
255   }
256   if (aParent->inherits("QDockWidget")) {
257     QDockWidget* aTabWgt = (QDockWidget*) aParent;
258     aTabWgt->raise();
259   }
260 }