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 DataPtr aData = theObject->data();
108 boost::shared_ptr<ModelAPI_AttributeReference> aRef =
109 boost::dynamic_pointer_cast<ModelAPI_AttributeReference>(aData->attribute(attributeID()));
111 ObjectPtr aObject = aRef->value();
112 if (!(aObject && aObject->isSame(mySelectedObject))) {
113 aRef->setValue(mySelectedObject);
114 Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
119 //********************************************************************
120 bool ModuleBase_WidgetSelector::restoreValue(ObjectPtr theObject)
122 DataPtr aData = theObject->data();
123 boost::shared_ptr<ModelAPI_AttributeReference> aRef = aData->reference(attributeID());
125 bool isBlocked = this->blockSignals(true);
126 mySelectedObject = aRef->value();
127 updateSelectionName();
129 this->blockSignals(isBlocked);
133 //********************************************************************
134 QList<QWidget*> ModuleBase_WidgetSelector::getControls() const
136 QList<QWidget*> aControls;
137 aControls.append(myLabel);
138 aControls.append(myTextLine);
139 aControls.append(myActivateBtn);
143 //********************************************************************
144 void ModuleBase_WidgetSelector::onSelectionChanged()
146 QList<ObjectPtr> aObjects = myWorkshop->selectedObjects();
147 if (aObjects.size() > 0) {
148 ObjectPtr aObject = aObjects.first();
149 if ((!mySelectedObject) && (!aObject))
151 if (mySelectedObject && aObject && mySelectedObject->isSame(aObject))
154 // Check that the selection corresponds to selection type
155 if (!isAccepted(aObject)) return;
157 mySelectedObject = aObject;
158 if (mySelectedObject) {
159 updateSelectionName();
160 activateSelection(false);
163 myTextLine->setText("");
165 emit valuesChanged();
169 //********************************************************************
170 bool ModuleBase_WidgetSelector::isAccepted(const ObjectPtr theResult) const
172 ResultPtr aResult = boost::dynamic_pointer_cast<ModelAPI_Result>(theResult);
173 boost::shared_ptr<GeomAPI_Shape> aShapePtr = ModuleBase_Tools::shape(aResult);
174 if (!aShapePtr) return false;
175 TopoDS_Shape aShape = aShapePtr->impl<TopoDS_Shape>();
176 if (aShape.IsNull()) return false;
178 TopAbs_ShapeEnum aShapeType = aShape.ShapeType();
179 if (aShapeType == TopAbs_COMPOUND) {
180 foreach (QString aType, myShapeTypes) {
181 TopExp_Explorer aEx(aShape, shapeType(aType));
186 foreach (QString aType, myShapeTypes) {
187 if (shapeType(aType) == aShapeType)
194 //********************************************************************
195 void ModuleBase_WidgetSelector::updateSelectionName()
197 if (mySelectedObject) {
198 std::string aName = mySelectedObject->data()->name();
200 myTextLine->setText(QString::fromStdString(aName));
202 myTextLine->setText("");
205 //********************************************************************
206 bool ModuleBase_WidgetSelector::eventFilter(QObject* theObj, QEvent* theEvent)
208 if (theObj == myTextLine) {
209 if (theEvent->type() == QEvent::Polish) {
210 activateSelection(myActivateOnStart);
211 onSelectionChanged();
214 return ModuleBase_ModelWidget::eventFilter(theObj, theEvent);
217 //********************************************************************
218 void ModuleBase_WidgetSelector::enableOthersControls(bool toEnable) const
220 QWidget* aParent = myContainer->parentWidget();
221 QList<QWidget*> aChldList = aParent->findChildren<QWidget*>();
222 foreach(QWidget* aWgt, aChldList) {
223 if ((aWgt != myLabel) && (aWgt != myActivateBtn) && (aWgt != myTextLine) && (aWgt != myContainer))
224 aWgt->setEnabled(toEnable);
228 //********************************************************************
229 void ModuleBase_WidgetSelector::activateSelection(bool toActivate)
231 enableOthersControls(!toActivate);
232 myTextLine->setEnabled(toActivate);
235 connect(myWorkshop, SIGNAL(selectionChanged()), this, SLOT(onSelectionChanged()));
237 disconnect(myWorkshop, SIGNAL(selectionChanged()), this, SLOT(onSelectionChanged()));
239 myActivateBtn->setDown(toActivate);
242 //********************************************************************
243 void ModuleBase_WidgetSelector::raisePanel() const
245 QWidget* aParent = myContainer->parentWidget();
246 QWidget* aLastPanel = 0;
247 while (!aParent->inherits("QDockWidget")) {
248 aLastPanel = aParent;
249 aParent = aParent->parentWidget();
250 if (!aParent) return;
252 if (aParent->inherits("QDockWidget")) {
253 QDockWidget* aTabWgt = (QDockWidget*) aParent;