1 // File: ModuleBase_WidgetSelector.h
2 // Created: 2 June 2014
3 // Author: Vitaly Smetannikov
6 #include "ModuleBase_WidgetSelector.h"
7 #include "ModuleBase_IWorkshop.h"
8 #include "ModuleBase_Tools.h"
10 #include <Events_Loop.h>
11 #include <ModelAPI_Events.h>
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>
19 #include <GeomAPI_Shape.h>
21 #include <TopoDS_Shape.hxx>
22 #include <TopExp_Explorer.hxx>
28 #include <QToolButton>
31 #include <QDockWidget>
36 typedef QMap<QString, TopAbs_ShapeEnum> ShapeTypes;
37 static ShapeTypes MyShapeTypes;
39 TopAbs_ShapeEnum ModuleBase_WidgetSelector::shapeType(const QString& theType)
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;
49 if (MyShapeTypes.contains(theType))
50 return MyShapeTypes[theType];
51 throw std::invalid_argument("Shape type defined in XML is not implemented!");
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)
63 myContainer = new QWidget(theParent);
64 QHBoxLayout* aLayout = new QHBoxLayout(myContainer);
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));
72 aLayout->addWidget(myLabel);
74 QString aToolTip = QString::fromStdString(theData->widgetTooltip());
75 myTextLine = new QLineEdit(myContainer);
76 myTextLine->setReadOnly(true);
77 myTextLine->setToolTip(aToolTip);
78 myTextLine->installEventFilter(this);
80 aLayout->addWidget(myTextLine);
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)));
88 aLayout->addWidget(myActivateBtn);
90 QString aActivateTxt = QString::fromStdString(theData->getProperty("activate"));
91 if (!aActivateTxt.isNull()) {
92 myActivateOnStart = (aActivateTxt == "true");
95 std::string aTypes = theData->getProperty("shape_types");
96 myShapeTypes = QString(aTypes.c_str()).split(',');
99 //********************************************************************
100 ModuleBase_WidgetSelector::~ModuleBase_WidgetSelector()
104 //********************************************************************
105 bool ModuleBase_WidgetSelector::storeValue(ObjectPtr theObject) const
107 FeaturePtr aSelectedFeature = ModuleBase_Tools::feature(mySelectedObject);
108 if (aSelectedFeature == theObject) // In order to avoid selection of the same object
111 DataPtr aData = theObject->data();
112 boost::shared_ptr<ModelAPI_AttributeReference> aRef =
113 boost::dynamic_pointer_cast<ModelAPI_AttributeReference>(aData->attribute(attributeID()));
115 ObjectPtr aObject = aRef->value();
116 if (!(aObject && aObject->isSame(mySelectedObject))) {
117 aRef->setValue(mySelectedObject);
118 updateObject(theObject);
123 //********************************************************************
124 bool ModuleBase_WidgetSelector::restoreValue(ObjectPtr theObject)
126 DataPtr aData = theObject->data();
127 boost::shared_ptr<ModelAPI_AttributeReference> aRef = aData->reference(attributeID());
129 bool isBlocked = this->blockSignals(true);
130 mySelectedObject = aRef->value();
131 updateSelectionName();
133 this->blockSignals(isBlocked);
137 //********************************************************************
138 QList<QWidget*> ModuleBase_WidgetSelector::getControls() const
140 QList<QWidget*> aControls;
141 aControls.append(myLabel);
142 aControls.append(myTextLine);
143 aControls.append(myActivateBtn);
147 //********************************************************************
148 void ModuleBase_WidgetSelector::onSelectionChanged()
150 QList<ObjectPtr> aObjects = myWorkshop->selectedObjects();
151 if (aObjects.size() > 0) {
152 ObjectPtr aObject = aObjects.first();
153 if ((!mySelectedObject) && (!aObject))
155 if (mySelectedObject && aObject && mySelectedObject->isSame(aObject))
158 // Check that the selection corresponds to selection type
159 if (!isAccepted(aObject)) return;
161 mySelectedObject = aObject;
162 if (mySelectedObject) {
163 updateSelectionName();
164 myActivateBtn->setChecked(false);
167 myTextLine->setText("");
169 emit valuesChanged();
173 //********************************************************************
174 bool ModuleBase_WidgetSelector::isAccepted(const ObjectPtr theResult) const
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;
182 TopAbs_ShapeEnum aShapeType = aShape.ShapeType();
183 if (aShapeType == TopAbs_COMPOUND) {
184 foreach (QString aType, myShapeTypes) {
185 TopExp_Explorer aEx(aShape, shapeType(aType));
190 foreach (QString aType, myShapeTypes) {
191 if (shapeType(aType) == aShapeType)
198 //********************************************************************
199 void ModuleBase_WidgetSelector::updateSelectionName()
201 if (mySelectedObject) {
202 std::string aName = mySelectedObject->data()->name();
204 myTextLine->setText(QString::fromStdString(aName));
206 myTextLine->setText("");
209 //********************************************************************
210 bool ModuleBase_WidgetSelector::eventFilter(QObject* theObj, QEvent* theEvent)
212 if (theObj == myTextLine) {
213 if (theEvent->type() == QEvent::Polish) {
214 myActivateBtn->setChecked(myActivateOnStart);
215 onSelectionChanged();
218 return ModuleBase_ModelWidget::eventFilter(theObj, theEvent);
221 //********************************************************************
222 void ModuleBase_WidgetSelector::enableOthersControls(bool toEnable) const
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);
232 //********************************************************************
233 void ModuleBase_WidgetSelector::activateSelection(bool toActivate)
235 enableOthersControls(!toActivate);
236 myTextLine->setEnabled(toActivate);
239 connect(myWorkshop, SIGNAL(selectionChanged()), this, SLOT(onSelectionChanged()));
241 disconnect(myWorkshop, SIGNAL(selectionChanged()), this, SLOT(onSelectionChanged()));
243 myActivateBtn->setDown(toActivate);
246 //********************************************************************
247 void ModuleBase_WidgetSelector::raisePanel() const
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;
256 if (aParent->inherits("QDockWidget")) {
257 QDockWidget* aTabWgt = (QDockWidget*) aParent;