X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FModuleBase%2FModuleBase_WidgetSelector.cpp;h=6f4a021d8686d1a24a442dd9bbf1aee29ce051c2;hb=a50d298cf3f55609f4a143a243a66ba140f89683;hp=5e0cd3e9837fce05a1d1cca2d2c49c42cc2bb396;hpb=db1bdf5481826c868b2c92c6cbc9afe8c5ad337c;p=modules%2Fshaper.git diff --git a/src/ModuleBase/ModuleBase_WidgetSelector.cpp b/src/ModuleBase/ModuleBase_WidgetSelector.cpp old mode 100644 new mode 100755 index 5e0cd3e98..6f4a021d8 --- a/src/ModuleBase/ModuleBase_WidgetSelector.cpp +++ b/src/ModuleBase/ModuleBase_WidgetSelector.cpp @@ -1,255 +1,267 @@ -// File: ModuleBase_WidgetSelector.h -// Created: 2 June 2014 -// Author: Vitaly Smetannikov - - -#include "ModuleBase_WidgetSelector.h" -#include "ModuleBase_IWorkshop.h" -#include "ModuleBase_Tools.h" - -#include +// Copyright (C) 2014-2017 CEA/DEN, EDF R&D +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.salome-platform.org/ or +// email : webmaster.salome@opencascade.com +// + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include #include +#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include +#include - -typedef QMap ShapeTypes; -static ShapeTypes MyShapeTypes; - -TopAbs_ShapeEnum ModuleBase_WidgetSelector::shapeType(const QString& theType) +ModuleBase_WidgetSelector::ModuleBase_WidgetSelector(QWidget* theParent, + ModuleBase_IWorkshop* theWorkshop, + const Config_WidgetAPI* theData) +: ModuleBase_WidgetValidated(theParent, theWorkshop, theData) { - if (MyShapeTypes.count() == 0) { - MyShapeTypes["face"] = TopAbs_FACE; - MyShapeTypes["vertex"] = TopAbs_VERTEX; - MyShapeTypes["wire"] = TopAbs_WIRE; - MyShapeTypes["edge"] = TopAbs_EDGE; - MyShapeTypes["shell"] = TopAbs_SHELL; - MyShapeTypes["solid"] = TopAbs_SOLID; - } - if (MyShapeTypes.contains(theType)) - return MyShapeTypes[theType]; - throw std::invalid_argument("Shape type defined in XML is not implemented!"); } - - - -ModuleBase_WidgetSelector::ModuleBase_WidgetSelector(QWidget* theParent, - ModuleBase_IWorkshop* theWorkshop, - const Config_WidgetAPI* theData) -: ModuleBase_ModelWidget(theParent, theData), myWorkshop(theWorkshop), myActivateOnStart(false) +//******************************************************************** +ModuleBase_WidgetSelector::~ModuleBase_WidgetSelector() { - myContainer = new QWidget(theParent); - QHBoxLayout* aLayout = new QHBoxLayout(myContainer); - - aLayout->setContentsMargins(0, 0, 0, 0); - QString aLabelText = QString::fromStdString(theData->widgetLabel()); - QString aLabelIcon = QString::fromStdString(theData->widgetIcon()); - myLabel = new QLabel(aLabelText, myContainer); - myLabel->setPixmap(QPixmap(aLabelIcon)); - - aLayout->addWidget(myLabel); - - QString aToolTip = QString::fromStdString(theData->widgetTooltip()); - myTextLine = new QLineEdit(myContainer); - myTextLine->setReadOnly(true); - myTextLine->setToolTip(aToolTip); - myTextLine->installEventFilter(this); - - aLayout->addWidget(myTextLine); +} - myActivateBtn = new QToolButton(myContainer); - myActivateBtn->setIcon(QIcon(":icons/hand_point.png")); - myActivateBtn->setCheckable(true); - myActivateBtn->setToolTip(tr("Activate/Deactivate selection")); - connect(myActivateBtn, SIGNAL(toggled(bool)), this, SLOT(activateSelection(bool))); +//******************************************************************** +void ModuleBase_WidgetSelector::getGeomSelection(const ModuleBase_ViewerPrsPtr& thePrs, + ObjectPtr& theObject, + GeomShapePtr& theShape) +{ + ModuleBase_ISelection* aSelection = myWorkshop->selection(); + theObject = aSelection->getResult(thePrs); + theShape = aSelection->getShape(thePrs); +} - aLayout->addWidget(myActivateBtn); +//******************************************************************** +bool ModuleBase_WidgetSelector::processSelection() +{ + QList aSelected = getFilteredSelected(); + // equal vertices should not be used here + ModuleBase_ISelection::filterSelectionOnEqualPoints(aSelected); - QString aActivateTxt = QString::fromStdString(theData->getProperty("activate")); - if (!aActivateTxt.isNull()) { - myActivateOnStart = (aActivateTxt == "true"); - } + bool isDone = setSelection(aSelected, true/*false*/); + updateOnSelectionChanged(isDone); - std::string aTypes = theData->getProperty("shape_types"); - myShapeTypes = QString(aTypes.c_str()).split(','); + return isDone; } //******************************************************************** -ModuleBase_WidgetSelector::~ModuleBase_WidgetSelector() +void ModuleBase_WidgetSelector::updateOnSelectionChanged(const bool theDone) { + // "false" flag should be used here, it connects to the #26658 OCC bug, when the user click in + // the same place repeatedly without mouse moved. In the case validation by filters is not + // perfromed, so an invalid object is selected. E.g. distance constraint, selection of a point. + // the 3rd click in the same point allow using this point. + emit valuesChanged(); + // the updateObject method should be called to flush the updated sigal. The workshop listens it, + // calls validators for the feature and, as a result, updates the Apply button state. + updateObject(myFeature); + + // we need to forget about previous validation result as the current selection can influence on it + clearValidatedCash(); + + if (theDone) + updateFocus(); } //******************************************************************** -bool ModuleBase_WidgetSelector::storeValue(ObjectPtr theObject) const +QIntList ModuleBase_WidgetSelector::getShapeTypes() const { - DataPtr aData = theObject->data(); - boost::shared_ptr aRef = - boost::dynamic_pointer_cast(aData->attribute(attributeID())); - - ObjectPtr aObject = aRef->value(); - if (!(aObject && aObject->isSame(mySelectedObject))) { - aRef->setValue(mySelectedObject); - Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED)); + QIntList aShapeTypes = shapeTypes(); + // this type should be mentioned in XML, poor selection otherwise + if (/*aShapeTypes.contains(TopAbs_SOLID) ||*/ + aShapeTypes.contains(ModuleBase_ResultPrs::Sel_Result/*TopAbs_SHAPE*/)) { + // it should be selectable for both, "solids" and "objects" types + aShapeTypes.append(TopAbs_COMPSOLID); } - return true; + return aShapeTypes; } //******************************************************************** -bool ModuleBase_WidgetSelector::restoreValue(ObjectPtr theObject) +QList ModuleBase_WidgetSelector::getAttributeSelection() const { - DataPtr aData = theObject->data(); - boost::shared_ptr aRef = aData->reference(attributeID()); - - bool isBlocked = this->blockSignals(true); - mySelectedObject = aRef->value(); - updateSelectionName(); - - this->blockSignals(isBlocked); - return true; + return QList(); } //******************************************************************** -QList ModuleBase_WidgetSelector::getControls() const +bool ModuleBase_WidgetSelector::acceptSubShape(const GeomShapePtr& theShape, + const ResultPtr& theResult) const { - QList aControls; - aControls.append(myLabel); - aControls.append(myTextLine); - aControls.append(myActivateBtn); - return aControls; -} + bool aValid = false; -//******************************************************************** -void ModuleBase_WidgetSelector::onSelectionChanged() -{ - QList aObjects = myWorkshop->selectedObjects(); - if (aObjects.size() > 0) { - ObjectPtr aObject = aObjects.first(); - if ((!mySelectedObject) && (!aObject)) - return; - if (mySelectedObject && aObject && mySelectedObject->isSame(aObject)) - return; + GeomShapePtr aShape = theShape; + + QIntList aShapeTypes = getShapeTypes(); + if (aShapeTypes.empty()) { + aValid = true; + return aValid; + } + // when the SHAPE type is provided by XML as Object, the whole result shape should be selected. + if (!aShape.get() && aShapeTypes.contains(ModuleBase_ResultPrs::Sel_Result)) { + aValid = true; + return aValid; + } + if (!aShape.get() && theResult.get()) { + if (theResult.get()) + aShape = theResult->shape(); + } + TopAbs_ShapeEnum aShapeType = TopAbs_SHAPE; + if (aShape.get()) { // Check that the selection corresponds to selection type - if (!isAccepted(aObject)) return; - - mySelectedObject = aObject; - if (mySelectedObject) { - updateSelectionName(); - activateSelection(false); - raisePanel(); - } else { - myTextLine->setText(""); + TopoDS_Shape aTopoShape = aShape->impl(); + aShapeType = aTopoShape.ShapeType(); + // for compounds check sub-shapes: it may be compound of needed type: + // Booleans may produce compounds of Solids + if (aShapeType == TopAbs_COMPOUND) { + aShapeType = ModuleBase_Tools::getCompoundSubType(aTopoShape); } - emit valuesChanged(); } + + QIntList::const_iterator anIt = aShapeTypes.begin(), aLast = aShapeTypes.end(); + for (; anIt != aLast && !aValid; anIt++) { + TopAbs_ShapeEnum aCurrentShapeType = (TopAbs_ShapeEnum)*anIt; + if (aShapeType == aCurrentShapeType) + aValid = true; + else if (aCurrentShapeType == TopAbs_FACE) { + // try to process the construction shape only if there is no a selected shape in the viewer + if (!theShape.get() && theResult.get()) { + ResultConstructionPtr aCResult = + std::dynamic_pointer_cast(theResult); + aValid = aCResult.get() && aCResult->facesNum() > 0; + } + } + } + return aValid; } //******************************************************************** -bool ModuleBase_WidgetSelector::isAccepted(const ObjectPtr theResult) const +void ModuleBase_WidgetSelector::selectionModes(QIntList& theModes, bool& isAdditional) { - ResultPtr aResult = boost::dynamic_pointer_cast(theResult); - boost::shared_ptr aShapePtr = ModuleBase_Tools::shape(aResult); - if (!aShapePtr) return false; - TopoDS_Shape aShape = aShapePtr->impl(); - if (aShape.IsNull()) return false; - - TopAbs_ShapeEnum aShapeType = aShape.ShapeType(); - if (aShapeType == TopAbs_COMPOUND) { - foreach (QString aType, myShapeTypes) { - TopExp_Explorer aEx(aShape, shapeType(aType)); - if (aEx.More()) - return true; - } - } else { - foreach (QString aType, myShapeTypes) { - if (shapeType(aType) == aShapeType) - return true; - } - } - return false; + theModes.append(getShapeTypes()); + isAdditional = true; } //******************************************************************** -void ModuleBase_WidgetSelector::updateSelectionName() +void ModuleBase_WidgetSelector::activateSelectionAndFilters(bool toActivate) { - if (mySelectedObject) { - std::string aName = mySelectedObject->data()->name(); - - myTextLine->setText(QString::fromStdString(aName)); - } else - myTextLine->setText(""); + updateSelectionName(); + + myWorkshop->selectionActivate()->updateSelectionFilters(); + myWorkshop->selectionActivate()->updateSelectionModes(); + + if (!toActivate) + clearValidatedCash(); } //******************************************************************** -bool ModuleBase_WidgetSelector::eventFilter(QObject* theObj, QEvent* theEvent) +void ModuleBase_WidgetSelector::activateCustom() { - if (theObj == myTextLine) { - if (theEvent->type() == QEvent::Polish) { - activateSelection(myActivateOnStart); - onSelectionChanged(); - } - } - return ModuleBase_ModelWidget::eventFilter(theObj, theEvent); + // Restore selection in the viewer by the attribute selection list + // it should be postponed to have current widget as active to validate restored selection + static Events_ID anEvent = Events_Loop::eventByName(EVENT_UPDATE_BY_WIDGET_SELECTION); + ModelAPI_EventCreator::get()->sendUpdated(myFeature, anEvent); } //******************************************************************** -void ModuleBase_WidgetSelector::enableOthersControls(bool toEnable) const +bool ModuleBase_WidgetSelector::isValidSelectionCustom(const ModuleBase_ViewerPrsPtr& thePrs) { - QWidget* aParent = myContainer->parentWidget(); - QList aChldList = aParent->findChildren(); - foreach(QWidget* aWgt, aChldList) { - if ((aWgt != myLabel) && (aWgt != myActivateBtn) && (aWgt != myTextLine) && (aWgt != myContainer)) - aWgt->setEnabled(toEnable); + GeomShapePtr aShape = myWorkshop->selection()->getShape(thePrs); + ResultPtr aResult = myWorkshop->selection()->getResult(thePrs); + bool aValid = acceptSubShape(aShape, aResult); + + if (aValid) { + // In order to avoid selection of the same object + ResultPtr aResult = myWorkshop->selection()->getResult(thePrs); + FeaturePtr aSelectedFeature = ModelAPI_Feature::feature(aResult); + aValid = aSelectedFeature != myFeature; } + return aValid; } //******************************************************************** -void ModuleBase_WidgetSelector::activateSelection(bool toActivate) +bool ModuleBase_WidgetSelector::setSelectionCustom(const ModuleBase_ViewerPrsPtr& thePrs) { - enableOthersControls(!toActivate); - myTextLine->setEnabled(toActivate); - - if (toActivate) - connect(myWorkshop, SIGNAL(selectionChanged()), this, SLOT(onSelectionChanged())); - else - disconnect(myWorkshop, SIGNAL(selectionChanged()), this, SLOT(onSelectionChanged())); + ObjectPtr anObject; + GeomShapePtr aShape; + getGeomSelection(thePrs, anObject, aShape); - myActivateBtn->setDown(toActivate); + // the last flag is to be depending on hasObject is called before. To be corrected later + return ModuleBase_Tools::setObject(attribute(), anObject, aShape, + myWorkshop, myIsInValidate, true); } //******************************************************************** -void ModuleBase_WidgetSelector::raisePanel() const +void ModuleBase_WidgetSelector::deactivate() { - QWidget* aParent = myContainer->parentWidget(); - QWidget* aLastPanel = 0; - while (!aParent->inherits("QDockWidget")) { - aLastPanel = aParent; - aParent = aParent->parentWidget(); - if (!aParent) return; + ModuleBase_WidgetValidated::deactivate(); + /// clear temporary cash + AttributePtr anAttribute = attribute(); + if (!anAttribute.get()) + return; + std::string aType = anAttribute->attributeType(); + if (anAttribute->attributeType() == ModelAPI_AttributeSelection::typeId()) { + AttributeSelectionPtr aSelectAttr = + std::dynamic_pointer_cast(anAttribute); + aSelectAttr->removeTemporaryValues(); } - if (aParent->inherits("QDockWidget")) { - QDockWidget* aTabWgt = (QDockWidget*) aParent; - aTabWgt->raise(); + else if (anAttribute->attributeType() == ModelAPI_AttributeSelectionList::typeId()) { + AttributeSelectionListPtr aSelectAttr = + std::dynamic_pointer_cast(anAttribute); + aSelectAttr->removeTemporaryValues(); + } +} + +//******************************************************************** +std::string ModuleBase_WidgetSelector::generateName(const AttributePtr& theAttribute, + ModuleBase_IWorkshop* theWorkshop) +{ + std::string aName; + if (theAttribute.get() != NULL) { + ModuleBase_Operation* anOperation = theWorkshop->currentOperation(); + + FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner()); + if (aFeature.get()) { + std::string aXmlCfg, aDescription; + theWorkshop->module()->getXMLRepresentation(aFeature->getKind(), aXmlCfg, aDescription); + + ModuleBase_WidgetFactory aFactory(aXmlCfg, theWorkshop); + std::string anAttributeTitle; + aFactory.getAttributeTitle(theAttribute->id(), anAttributeTitle); + + std::stringstream aStreamName; + aStreamName << theAttribute->owner()->data()->name() << "/"<< anAttributeTitle.c_str(); + aName = aStreamName.str(); + } } + return aName; }