1 // File: ModuleBase_WidgetSelector.h
2 // Created: 2 June 2014
3 // Author: Vitaly Smetannikov
6 #include "ModuleBase_WidgetSelector.h"
7 #include "ModuleBase_IWorkshop.h"
9 #include <Events_Loop.h>
10 #include <Model_Events.h>
12 #include <ModelAPI_Data.h>
13 #include <ModelAPI_Object.h>
14 #include <ModelAPI_AttributeReference.h>
15 #include <Config_WidgetAPI.h>
17 #include <GeomAPI_Shape.h>
19 #include <TopoDS_Shape.hxx>
20 #include <TopExp_Explorer.hxx>
26 #include <QToolButton>
29 #include <QDockWidget>
32 typedef QMap<QString, TopAbs_ShapeEnum> ShapeTypes;
33 static ShapeTypes MyShapeTypes;
35 TopAbs_ShapeEnum ModuleBase_WidgetSelector::shapeType(const QString& theType)
37 if (MyShapeTypes.count() == 0) {
38 MyShapeTypes["face"] = TopAbs_FACE;
39 MyShapeTypes["vertex"] = TopAbs_VERTEX;
40 MyShapeTypes["wire"] = TopAbs_WIRE;
41 MyShapeTypes["edge"] = TopAbs_EDGE;
42 MyShapeTypes["shell"] = TopAbs_SHELL;
43 MyShapeTypes["solid"] = TopAbs_SOLID;
45 if (MyShapeTypes.contains(theType))
46 return MyShapeTypes[theType];
47 throw std::invalid_argument("Shape type defined in XML is not implemented!");
53 ModuleBase_WidgetSelector::ModuleBase_WidgetSelector(QWidget* theParent,
54 ModuleBase_IWorkshop* theWorkshop,
55 const Config_WidgetAPI* theData)
56 : ModuleBase_ModelWidget(theParent, theData), myWorkshop(theWorkshop), myActivateOnStart(false)
58 myContainer = new QWidget(theParent);
59 QHBoxLayout* aLayout = new QHBoxLayout(myContainer);
61 aLayout->setContentsMargins(0, 0, 0, 0);
62 QString aLabelText = QString::fromStdString(theData->widgetLabel());
63 QString aLabelIcon = QString::fromStdString(theData->widgetIcon());
64 myLabel = new QLabel(aLabelText, myContainer);
65 myLabel->setPixmap(QPixmap(aLabelIcon));
67 aLayout->addWidget(myLabel);
69 QString aToolTip = QString::fromStdString(theData->widgetTooltip());
70 myTextLine = new QLineEdit(myContainer);
71 myTextLine->setReadOnly(true);
72 myTextLine->setToolTip(aToolTip);
73 myTextLine->installEventFilter(this);
75 aLayout->addWidget(myTextLine);
77 myActivateBtn = new QToolButton(myContainer);
78 myActivateBtn->setIcon(QIcon(":icons/hand_point.png"));
79 myActivateBtn->setCheckable(true);
80 myActivateBtn->setToolTip(tr("Activate/Deactivate selection"));
81 connect(myActivateBtn, SIGNAL(toggled(bool)), this, SLOT(activateSelection(bool)));
83 aLayout->addWidget(myActivateBtn);
85 QString aActivateTxt = QString::fromStdString(theData->getProperty("activate"));
86 if (!aActivateTxt.isNull()) {
87 myActivateOnStart = (aActivateTxt == "true");
90 std::string aTypes = theData->getProperty("shape_types");
91 myShapeTypes = QString(aTypes.c_str()).split(',');
94 //********************************************************************
95 ModuleBase_WidgetSelector::~ModuleBase_WidgetSelector()
99 //********************************************************************
100 bool ModuleBase_WidgetSelector::storeValue(FeaturePtr theFeature) const
102 DataPtr aData = theFeature->data();
103 boost::shared_ptr<ModelAPI_AttributeReference> aRef =
104 boost::dynamic_pointer_cast<ModelAPI_AttributeReference>(aData->attribute(attributeID()));
106 FeaturePtr aFeature = aRef->value();
107 if (!(aFeature && aFeature->isSame(mySelectedFeature))) {
108 aRef->setValue(mySelectedFeature);
109 Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_FEATURE_UPDATED));
114 //********************************************************************
115 bool ModuleBase_WidgetSelector::restoreValue(FeaturePtr theFeature)
117 DataPtr aData = theFeature->data();
118 boost::shared_ptr<ModelAPI_AttributeReference> aRef = aData->reference(attributeID());
120 bool isBlocked = this->blockSignals(true);
121 mySelectedFeature = aRef->value();
122 updateSelectionName();
124 this->blockSignals(isBlocked);
128 //********************************************************************
129 QList<QWidget*> ModuleBase_WidgetSelector::getControls() const
131 QList<QWidget*> aControls;
132 aControls.append(myLabel);
133 aControls.append(myTextLine);
134 aControls.append(myActivateBtn);
138 //********************************************************************
139 void ModuleBase_WidgetSelector::onSelectionChanged()
141 QList<FeaturePtr> aFeatures = myWorkshop->selectedFeatures();
142 if (aFeatures.size() > 0) {
143 FeaturePtr aFeature = aFeatures.first();
144 if ((!mySelectedFeature) && (!aFeature))
146 if (mySelectedFeature && aFeature && mySelectedFeature->isSame(aFeature))
149 // Check that the selection corresponds to selection type
150 if (!isAccepted(aFeature)) return;
152 mySelectedFeature = aFeature;
153 if (mySelectedFeature) {
154 updateSelectionName();
155 activateSelection(false);
158 myTextLine->setText("");
160 emit valuesChanged();
164 //********************************************************************
165 bool ModuleBase_WidgetSelector::isAccepted(const FeaturePtr theFeature) const
167 boost::shared_ptr<GeomAPI_Shape> aShapePtr = theFeature->data()->shape();
168 if (!aShapePtr) return false;
169 TopoDS_Shape aShape = aShapePtr->impl<TopoDS_Shape>();
170 if (aShape.IsNull()) return false;
172 TopAbs_ShapeEnum aShapeType = aShape.ShapeType();
173 if (aShapeType == TopAbs_COMPOUND) {
174 foreach (QString aType, myShapeTypes) {
175 TopExp_Explorer aEx(aShape, shapeType(aType));
180 foreach (QString aType, myShapeTypes) {
181 if (shapeType(aType) == aShapeType)
188 //********************************************************************
189 void ModuleBase_WidgetSelector::updateSelectionName()
191 if (mySelectedFeature) {
193 if (mySelectedFeature->data())
194 aName = mySelectedFeature->data()->getName();
196 aName = boost::dynamic_pointer_cast<ModelAPI_Object>(mySelectedFeature)->getName();
198 myTextLine->setText(QString::fromStdString(aName));
200 myTextLine->setText("");
203 //********************************************************************
204 bool ModuleBase_WidgetSelector::eventFilter(QObject* theObj, QEvent* theEvent)
206 if (theObj == myTextLine) {
207 if (theEvent->type() == QEvent::Polish) {
208 activateSelection(myActivateOnStart);
209 onSelectionChanged();
212 return ModuleBase_ModelWidget::eventFilter(theObj, theEvent);
215 //********************************************************************
216 void ModuleBase_WidgetSelector::enableOthersControls(bool toEnable) const
218 QWidget* aParent = myContainer->parentWidget();
219 QList<QWidget*> aChldList = aParent->findChildren<QWidget*>();
220 foreach(QWidget* aWgt, aChldList) {
221 if ((aWgt != myLabel) && (aWgt != myActivateBtn) && (aWgt != myTextLine) && (aWgt != myContainer))
222 aWgt->setEnabled(toEnable);
226 //********************************************************************
227 void ModuleBase_WidgetSelector::activateSelection(bool toActivate)
229 enableOthersControls(!toActivate);
230 myTextLine->setEnabled(toActivate);
233 connect(myWorkshop, SIGNAL(selectionChanged()), this, SLOT(onSelectionChanged()));
235 disconnect(myWorkshop, SIGNAL(selectionChanged()), this, SLOT(onSelectionChanged()));
237 myActivateBtn->setDown(toActivate);
240 //********************************************************************
241 void ModuleBase_WidgetSelector::raisePanel() const
243 QWidget* aParent = myContainer->parentWidget();
244 QWidget* aLastPanel = 0;
245 while (!aParent->inherits("QDockWidget")) {
246 aLastPanel = aParent;
247 aParent = aParent->parentWidget();
248 if (!aParent) return;
250 if (aParent->inherits("QDockWidget")) {
251 QDockWidget* aTabWgt = (QDockWidget*) aParent;