X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FPartSet%2FPartSet_WidgetSketchCreator.cpp;h=6397b3caefd7f54a00169ecd1e292b882f1209d1;hb=5320c0c8deb3e7a5a53dbc422207cc711b4726d1;hp=1c4fbeddf1b5d11a6418a6e900cc403f9b152fbd;hpb=475b04ed2e28f1e6983cf54eaefece14e68f4aac;p=modules%2Fshaper.git diff --git a/src/PartSet/PartSet_WidgetSketchCreator.cpp b/src/PartSet/PartSet_WidgetSketchCreator.cpp index 1c4fbeddf..6397b3cae 100644 --- a/src/PartSet/PartSet_WidgetSketchCreator.cpp +++ b/src/PartSet/PartSet_WidgetSketchCreator.cpp @@ -6,19 +6,31 @@ #include "PartSet_WidgetSketchCreator.h" #include "PartSet_Module.h" +#include "PartSet_WidgetSketchLabel.h" +#include "PartSet_PreviewPlanes.h" + +#include #include #include #include #include #include +#include +#include +#include #include +#include + #include #include #include #include +#include +#include +#include #include #include @@ -26,157 +38,541 @@ #include #include #include +#include +#include + #include +#include + #include #include -#include +#include +//#include +#include #include +#include + +#define DEBUG_UNDO_INVALID_SKETCH -PartSet_WidgetSketchCreator::PartSet_WidgetSketchCreator(QWidget* theParent, +PartSet_WidgetSketchCreator::PartSet_WidgetSketchCreator(QWidget* theParent, PartSet_Module* theModule, - const Config_WidgetAPI* theData, - const std::string& theParentId) -: ModuleBase_ModelWidget(theParent, theData, theParentId), myModule(theModule) + const Config_WidgetAPI* theData) +: ModuleBase_WidgetSelector(theParent, theModule->workshop(), theData), + myModule(theModule), myIsCustomAttribute(false) { - QFormLayout* aLayout = new QFormLayout(this); + myAttributeListID = theData->getProperty("attribute_list_id"); + + //QFormLayout* aLayout = new QFormLayout(this); + QVBoxLayout* aLayout = new QVBoxLayout(this); + ModuleBase_Tools::zeroMargins(aLayout); + ModuleBase_Tools::adjustMargins(aLayout); QString aLabelText = QString::fromStdString(theData->widgetLabel()); QString aLabelIcon = QString::fromStdString(theData->widgetIcon()); + + // Size of the View control + mySizeOfViewWidget = new QWidget(this); + QHBoxLayout* aSizeLayout = new QHBoxLayout(mySizeOfViewWidget); + aSizeLayout->addWidget(new QLabel("Size of the view", mySizeOfViewWidget)); + mySizeOfView = new QLineEdit(mySizeOfViewWidget); + + QDoubleValidator* aValidator = new QDoubleValidator(0, DBL_MAX, 12, mySizeOfView); + aValidator->setLocale(ModuleBase_Tools::doubleLocale()); + aValidator->setNotation(QDoubleValidator::StandardNotation); + mySizeOfView->setValidator(aValidator); + aSizeLayout->addWidget(mySizeOfView); + myLabel = new QLabel(aLabelText, this); - if (!aLabelIcon.isEmpty()) - myLabel->setPixmap(QPixmap(aLabelIcon)); + myLabel->setWordWrap(true); + aLayout->addWidget(mySizeOfViewWidget); + aLayout->addWidget(myLabel); + aLayout->addStretch(1); - QString aToolTip = QString::fromStdString(theData->widgetTooltip()); - myTextLine = new QLineEdit(this); - myTextLine->setReadOnly(true); - myTextLine->setToolTip(aToolTip); - myTextLine->installEventFilter(this); + std::string aTypes = theData->getProperty("shape_types"); + myShapeTypes = QString(aTypes.c_str()).split(' ', QString::SkipEmptyParts); - aLayout->addRow(myLabel, myTextLine); + myPreviewPlanes = new PartSet_PreviewPlanes(); } PartSet_WidgetSketchCreator::~PartSet_WidgetSketchCreator() { + // we need to deactivate here in order to hide preview planes if the selection mode is + // active + deactivate(); } QList PartSet_WidgetSketchCreator::getControls() const { QList aControls; - aControls.append(myTextLine); + aControls.append(myLabel); return aControls; } -bool PartSet_WidgetSketchCreator::restoreValue() +bool PartSet_WidgetSketchCreator::restoreValueCustom() { - CompositeFeaturePtr aCompFeature = - std::dynamic_pointer_cast(myFeature); - if (aCompFeature->numberOfSubs() > 0) { - FeaturePtr aSubFeature = aCompFeature->subFeature(0); - myTextLine->setText(QString::fromStdString(aSubFeature->data()->name())); - } return true; } -bool PartSet_WidgetSketchCreator::storeValueCustom() const +bool PartSet_WidgetSketchCreator::storeValueCustom() { return true; } -void PartSet_WidgetSketchCreator::activateCustom() +AttributePtr PartSet_WidgetSketchCreator::attribute() const { - CompositeFeaturePtr aCompFeature = - std::dynamic_pointer_cast(myFeature); - if (aCompFeature->numberOfSubs() == 0) - connect(myModule, SIGNAL(operationLaunched()), SLOT(onStarted())); -} - -void PartSet_WidgetSketchCreator::onStarted() -{ - disconnect(myModule, SIGNAL(operationLaunched()), this, SLOT(onStarted())); - - // Check that model already has bodies - XGUI_ModuleConnector* aConnector = dynamic_cast(myModule->workshop()); - XGUI_Workshop* aWorkshop = aConnector->workshop(); - XGUI_Displayer* aDisp = aWorkshop->displayer(); - QObjectPtrList aObjList = aDisp->displayedObjects(); - bool aHasBody = false; - ResultBodyPtr aBody; - foreach(ObjectPtr aObj, aObjList) { - aBody = std::dynamic_pointer_cast(aObj); - if (aBody.get() != NULL) { - aHasBody = true; - break; + AttributePtr anAttribute; + if (myIsCustomAttribute) + anAttribute = myFeature->attribute(myAttributeListID); + else + anAttribute = ModuleBase_WidgetSelector::attribute(); + + return anAttribute; +} + +//******************************************************************** +void PartSet_WidgetSketchCreator::openExtrusionTransaction() +{ + SessionPtr aMgr = ModelAPI_Session::get(); + bool aIsOp = aMgr->isOperation(); + if (!aIsOp) { + const static std::string aNestedOpID("Parameters modification"); + aMgr->startOperation(aNestedOpID, true); + } +} + +//******************************************************************** +bool PartSet_WidgetSketchCreator::isValidSelection(const ModuleBase_ViewerPrsPtr& theValue) +{ + bool aValid = false; + if (myIsCustomAttribute) { + // check only suiting of the value to custom attribute (myAttributeListID) + // do not cash of validation to avoid using states, stored for XML attribute + // there is an alternative is to call clearValidatedCash() in setSelection() + aValid = isValidSelectionForAttribute(theValue, attribute()); + } + else { /// if the validated attribute is already custom + if (getValidState(theValue, aValid)) { + return aValid; + } + aValid = isValidSelectionCustom(theValue); + if (!aValid) + // check selection to create new sketh (XML current attribute) + aValid = isValidSelectionForAttribute(theValue, attribute()); + if (!aValid) { + // check selection to fill list attribute (myAttributeListID) + bool isCustomAttribute = myIsCustomAttribute; + myIsCustomAttribute = true; + aValid = isValidSelectionForAttribute(theValue, attribute()); + myIsCustomAttribute = isCustomAttribute; + } + } + storeValidState(theValue, aValid); + return aValid; +} + +//******************************************************************** +bool PartSet_WidgetSketchCreator::isValidSelectionCustom(const ModuleBase_ViewerPrsPtr& theValue) +{ + return PartSet_WidgetSketchLabel::canFillSketch(theValue); +} + +void PartSet_WidgetSketchCreator::activateSelectionControl() +{ + // we need to call activate here as the widget has no focus accepted controls + // if these controls are added here, activate will happens automatically after focusIn() + XGUI_Workshop* aWorkshop = XGUI_Tools::workshop(myModule->workshop()); + XGUI_PropertyPanel* aPanel = aWorkshop->propertyPanel(); + aPanel->activateWidget(this, false); +} + +void PartSet_WidgetSketchCreator::setVisibleSelectionControl(const bool theSelectionControl) +{ + // hide current widget, activate the next widget + XGUI_Workshop* aWorkshop = XGUI_Tools::workshop(myModule->workshop()); + XGUI_PropertyPanel* aPanel = aWorkshop->propertyPanel(); + const QList& aWidgets = aPanel->modelWidgets(); + foreach(ModuleBase_ModelWidget* aWidget, aWidgets) { + if (theSelectionControl) { // hide other controls + if (aWidget != this) + aWidget->setVisible(false); + } + else { // hide current control + if (aWidget == this) + aWidget->setVisible(false); + else { + aWidget->setVisible(true); + if (aWidget->attributeID() == myAttributeListID) + setEnabledModelWidget(aWidget, !hasSubObjects()); + } } } - if (aHasBody) { - // Launch Sketch operation - CompositeFeaturePtr aCompFeature = - std::dynamic_pointer_cast(myFeature); - FeaturePtr aSketch = aCompFeature->addFeature("Sketch"); + if (theSelectionControl) { + bool aBodyIsVisualized = myPreviewPlanes->hasVisualizedBodies(myWorkshop); + bool aSketchIsVisualized = myPreviewPlanes->hasVisualizedSketch(myWorkshop); + if (!aBodyIsVisualized && !aSketchIsVisualized) { + // We have to select a plane before any operation + myPreviewPlanes->showPreviewPlanes(myWorkshop); + mySizeOfViewWidget->setVisible(true); + } + else { + mySizeOfViewWidget->setVisible(false); + } - ModuleBase_Operation* anOperation = myModule->createOperation("Sketch"); - anOperation->setFeature(aSketch); - myModule->sendOperation(anOperation); - //connect(anOperation, SIGNAL(aborted()), aWorkshop->operationMgr(), SLOT(abortAllOperations())); } else { - // Break current operation - QMessageBox::warning(this, tr("Extrusion Cut"), - tr("There are no bodies found. Operation aborted."), QMessageBox::Ok); - ModuleBase_Operation* aOp = myModule->workshop()->currentOperation(); - aOp->abort(); + bool aHidePreview = myPreviewPlanes->isPreviewDisplayed(); + myPreviewPlanes->erasePreviewPlanes(myWorkshop); + if (aHidePreview) + aWorkshop->viewer()->update(); } } -bool PartSet_WidgetSketchCreator::focusTo() +QIntList PartSet_WidgetSketchCreator::shapeTypes() const +{ + QIntList aShapeTypes; + foreach(QString aType, myShapeTypes) { + aShapeTypes.append(ModuleBase_Tools::shapeType(aType)); + } + return aShapeTypes; +} + +void PartSet_WidgetSketchCreator::setEditingMode(bool isEditing) +{ + ModuleBase_ModelWidget::setEditingMode(isEditing); + if (isEditing) { + setVisibleSelectionControl(false); + + ModuleBase_ModelWidget* anAttributeListWidget = 0; + XGUI_Workshop* aWorkshop = XGUI_Tools::workshop(myModule->workshop()); + XGUI_PropertyPanel* aPanel = aWorkshop->propertyPanel(); + const QList& aWidgets = aPanel->modelWidgets(); + foreach(ModuleBase_ModelWidget* aWidget, aWidgets) { + if (aWidget->attributeID() == myAttributeListID) { + anAttributeListWidget = aWidget; + break; + } + } + if (anAttributeListWidget) + setEnabledModelWidget(anAttributeListWidget, !hasSubObjects()); + } +} + +bool PartSet_WidgetSketchCreator::isSelectionMode() const +{ + AttributeSelectionListPtr anAttrList = myFeature->data()->selectionList(myAttributeListID); + bool aHasValueInList = anAttrList.get() && anAttrList->size() > 0; + + return !aHasValueInList; +} + +bool PartSet_WidgetSketchCreator::hasSubObjects() const +{ + bool aHasSubObjects = false; + + bool aCanSetFocus = true; + CompositeFeaturePtr aComposite = std::dynamic_pointer_cast(myFeature); + if (aComposite.get()) + aHasSubObjects = aComposite->numberOfSubs() > 0; + return aHasSubObjects; +} + +bool PartSet_WidgetSketchCreator::setSelection(QList& theValues, + const bool theToValidate) +{ + bool aDone = false; + if (!startSketchOperation(theValues)) { + myIsCustomAttribute = true; + QList::const_iterator + anIt = theValues.begin(), aLast = theValues.end(); + bool aProcessed = false; + for (; anIt != aLast; anIt++) { + ModuleBase_ViewerPrsPtr aValue = *anIt; + if (!theToValidate || isValidInFilters(aValue)) + aProcessed = setSelectionCustom(aValue) || aProcessed; + } + myIsCustomAttribute = false; + aDone = aProcessed; + if (aProcessed) { + emit valuesChanged(); + updateObject(myFeature); + setVisibleSelectionControl(false); + // manually deactivation because the widget was + // not activated as has no focus acceptin controls + deactivate(); + emit focusOutWidget(this); + } + } + return aDone; +} + +//******************************************************************** +void PartSet_WidgetSketchCreator::onSelectionChanged() +{ + QList aSelected = getFilteredSelected(); + bool isDone = setSelection(aSelected, true/*false*/); +} + +//******************************************************************** +void PartSet_WidgetSketchCreator::updateOnSelectionChanged(const bool theDone) { - CompositeFeaturePtr aCompFeature = +} + +bool PartSet_WidgetSketchCreator::startSketchOperation( + const QList& theValues) +{ + bool aSketchStarted = false; + + if (theValues.size() != 1) + return aSketchStarted; + + ModuleBase_ViewerPrsPtr aValue = theValues.front(); + if (!aValue.get() || !PartSet_WidgetSketchLabel::canFillSketch(aValue)) + return aSketchStarted; + + ResultPtr aResult = std::dynamic_pointer_cast(aValue->object()); + /// sketch should not started by object(face) selected as global. If Local face is selected, + /// sketch is started + if (aResult.get() && aValue->shape().get() && aResult->shape()->isEqual(aValue->shape())) { + ResultConstructionPtr aConstruction = + std::dynamic_pointer_cast(aResult); + if (!aConstruction.get() || !aConstruction->isInfinite()) + return aSketchStarted; + } + aSketchStarted = true; + // Set View size if a plane is selected + if (myPreviewPlanes->isPreviewDisplayed() && + myPreviewPlanes->isPreviewShape(aValue->shape())) { + QString aSizeOfViewStr = mySizeOfView->text(); + if (!aSizeOfViewStr.isEmpty()) { + bool isOk; + double aSizeOfView = aSizeOfViewStr.toDouble(&isOk); + if (isOk && aSizeOfView > 0) { + Handle(V3d_View) aView3d = myWorkshop->viewer()->activeView(); + if (!aView3d.IsNull()) { + Bnd_Box aBndBox; + double aHalfSize = aSizeOfView/2.0; + aBndBox.Update(-aHalfSize, -aHalfSize, -aHalfSize, aHalfSize, aHalfSize, aHalfSize); + aView3d->FitAll(aBndBox, 0.01, false); + } + } + } + } + // manually deactivation because the widget was not activated as has no focus acceptin controls + deactivate(); + bool aHidePreview = myPreviewPlanes->isPreviewDisplayed(); + myPreviewPlanes->erasePreviewPlanes(myWorkshop); + + // Launch Sketch operation + CompositeFeaturePtr aCompFeature = std::dynamic_pointer_cast(myFeature); - if (aCompFeature->numberOfSubs() == 0) - return ModuleBase_ModelWidget::focusTo(); - connect(myModule, SIGNAL(operationResumed(ModuleBase_Operation*)), SLOT(onResumed(ModuleBase_Operation*))); - SessionPtr aMgr = ModelAPI_Session::get(); - bool aIsOp = aMgr->isOperation(); - // Open transaction if it was closed before - if (!aIsOp) - aMgr->startOperation(); + // start edit operation for the sketch + ModuleBase_OperationFeature* aFOperation = dynamic_cast + (myModule->createOperation("Sketch")); + QList aValues; + aValues.push_back(aValue); + aFOperation->setPreselection(aValues); + + myWorkshop->processLaunchOperation(aFOperation); + + return aSketchStarted; +} + +bool PartSet_WidgetSketchCreator::focusTo() +{ + // this method is called only in creation mode. In Edition mode this widget is hidden + if (isSelectionMode() && !hasSubObjects()) { + setVisibleSelectionControl(true); + activateSelectionControl(); + openExtrusionTransaction(); + return true; + } + else + connect(myModule, SIGNAL(resumed(ModuleBase_Operation*)), + SLOT(onResumed(ModuleBase_Operation*))); + + return true; +} + +void PartSet_WidgetSketchCreator::deactivate() +{ + ModuleBase_WidgetSelector::deactivate(); + + bool aHidePreview = myPreviewPlanes->isPreviewDisplayed(); + myPreviewPlanes->erasePreviewPlanes(myWorkshop); + if (aHidePreview) + XGUI_Tools::workshop(myWorkshop)->viewer()->update(); - restoreValue(); - return false; } void PartSet_WidgetSketchCreator::onResumed(ModuleBase_Operation* theOp) { - CompositeFeaturePtr aCompFeature = + SessionPtr aMgr = ModelAPI_Session::get(); + bool aIsOp = aMgr->isOperation(); + if (aIsOp) { + // in current implementation, all transactions are closed when resume happens + // so, this is a wrong case, which is not checked. + // To provide it, make correction in later rows about abort/undo transactions + return; + } + // Set visible only selection control + setVisibleSelectionControl(true); + + // Validate the created sketch. If it is valid, it is set into the composite feature selection + // list, otherwise it is removed + CompositeFeaturePtr aCompFeature = std::dynamic_pointer_cast(myFeature); - CompositeFeaturePtr aSketchFeature = - std::dynamic_pointer_cast(aCompFeature->subFeature(0)); - if (aSketchFeature->numberOfSubs() == 0) { - // Abort operation + AttributeSelectionListPtr anAttrList = myFeature->data()->selectionList(myAttributeListID); + if (aCompFeature->numberOfSubs() > 0) { + // set the sub feature to attribute selection list and check whether sketch is valid SessionPtr aMgr = ModelAPI_Session::get(); - bool aIsOp = aMgr->isOperation(); - // Close transaction - if (aIsOp) - aMgr->abortOperation(); - theOp->abort(); - } else { - DataPtr aData = aSketchFeature->data(); - AttributeSelectionPtr aSelAttr = - std::dynamic_pointer_cast - (aData->attribute(SketchPlugin_SketchEntity::EXTERNAL_ID())); - if (aSelAttr.get()) { - ResultPtr aRes = aSelAttr->context(); - GeomShapePtr aShape = aSelAttr->value(); + const static std::string aNestedOpID("Set Sketch result into Selection list"); + aMgr->startOperation(aNestedOpID, false); // false to not attach to Extrusion operation + setSketchObjectToList(aCompFeature, anAttrList); + aMgr->finishOperation(); + + if (!validateSelectionList()) { +#ifdef DEBUG_UNDO_INVALID_SKETCH + aMgr->undo(); // Extrusion modification parameters: setSketchObjectToList() + aMgr->undo(); /// Sketch creation +#else + aMgr->startOperation("Delete invalid Sketch feature", false); + + // delete invalid sketch + CompositeFeaturePtr aSketchFeature = + std::dynamic_pointer_cast(aCompFeature->subFeature(0)); + QObjectPtrList anObjects; + anObjects.append(aSketchFeature); + + XGUI_Workshop* aWorkshop = XGUI_Tools::workshop(myModule->workshop()); + aWorkshop->deleteFeatures(anObjects); + + aMgr->finishOperation(); +#endif + } + } + openExtrusionTransaction(); + + if (aCompFeature->numberOfSubs() == 0) { + // call activateWidget() of the parent to connect to the viewer seleciton + activateSelectionControl(); + } + else { + // check if the created sketch is valid. If it is invalid, it will be deleted with warning else + /// the attribute selection list will be filled by result of this sketch. + setVisibleSelectionControl(false); + + // Update value in attribute selection list + XGUI_Workshop* aWorkshop = XGUI_Tools::workshop(myModule->workshop()); + XGUI_PropertyPanel* aPropertyPanel = aWorkshop->propertyPanel(); + const QList& aWidgets = aPropertyPanel->modelWidgets(); + ModuleBase_ModelWidget* aListWidget = 0; + foreach(ModuleBase_ModelWidget* aWidget, aWidgets) { + if (aWidget->attributeID() == myAttributeListID) { + aListWidget = aWidget; + break; + } + } + if (aListWidget) { + aListWidget->restoreValue(); + aPropertyPanel->activateNextWidget(aListWidget); + } + + // Hide sketcher result + CompositeFeaturePtr aSketchFeature = + std::dynamic_pointer_cast(aCompFeature->subFeature(0)); + std::list aResults = aSketchFeature->results(); + std::list::const_iterator aIt; + for (aIt = aResults.begin(); aIt != aResults.end(); ++aIt) { + (*aIt)->setDisplayed(false); + } + aSketchFeature->setDisplayed(false); + static Events_Loop* aLoop = Events_Loop::loop(); + aLoop->flush(aLoop->eventByName(EVENT_OBJECT_TO_REDISPLAY)); + + // Add Selected body were created the sketcher to list of selected objects + std::string anObjectsAttribute = FeaturesPlugin_CompositeBoolean::OBJECTS_ID(); + AttributeSelectionListPtr aSelList = aCompFeature->data()->selectionList(anObjectsAttribute); + if (aSelList.get()) { + DataPtr aData = aSketchFeature->data(); + AttributeSelectionPtr aSelAttr = std::dynamic_pointer_cast + (aData->attribute(SketchPlugin_SketchEntity::EXTERNAL_ID())); + ResultPtr aRes = aSelAttr.get() ? aSelAttr->context() : ResultPtr(); if (aRes.get()) { - AttributeSelectionListPtr aSelList = - aCompFeature->data()->selectionList(FeaturesPlugin_CompositeBoolean::BOOLEAN_OBJECTS_ID()); + SessionPtr aMgr = ModelAPI_Session::get(); + ModelAPI_ValidatorsFactory* aFactory = aMgr->validators(); + AttributePtr anAttribute = myFeature->attribute(anObjectsAttribute); + std::string aValidatorID; + Events_InfoMessage anError; aSelList->append(aRes, GeomShapePtr()); - updateObject(aCompFeature); + if (aFactory->validate(anAttribute, aValidatorID, anError)) + updateObject(aCompFeature); + else + aSelList->clear(); } } } + restoreValue(); +} + +bool PartSet_WidgetSketchCreator::validateSelectionList() const +{ + AttributeSelectionListPtr anAttrList = myFeature->data()->selectionList(myAttributeListID); + + SessionPtr aMgr = ModelAPI_Session::get(); + ModelAPI_ValidatorsFactory* aFactory = aMgr->validators(); + std::string aValidatorID; + Events_InfoMessage anError; + bool isValidPComposite = aFactory->validate(anAttrList, aValidatorID, anError); + if (!isValidPComposite) { + XGUI_Workshop* aWorkshop = XGUI_Tools::workshop(myModule->workshop()); + // TODO(spo): translate + QMessageBox::question(aWorkshop->desktop(), tr("Apply current feature"), + tr("Sketch is invalid and will be deleted.\nError: %1") + .arg(anError.messageString().c_str()), + QMessageBox::Ok); + } + return isValidPComposite; +} + +void PartSet_WidgetSketchCreator::setSketchObjectToList( + const CompositeFeaturePtr& theCompositeFeature, + const AttributePtr& theAttribute) +{ + if (!theCompositeFeature.get() || theCompositeFeature->numberOfSubs() != 1) + return; + + AttributeSelectionListPtr aBaseObjectsSelectionList = + std::dynamic_pointer_cast(theAttribute); + if(!aBaseObjectsSelectionList.get() || aBaseObjectsSelectionList->isInitialized()) { + return; + } + + FeaturePtr aSketchFeature = theCompositeFeature->subFeature(0); + if(!aSketchFeature.get() || aSketchFeature->results().empty()) { + return; + } + + ResultPtr aSketchRes = aSketchFeature->results().front(); + ResultConstructionPtr aConstruction = + std::dynamic_pointer_cast(aSketchRes); + if(!aConstruction.get()) { + return; + } + + if(aBaseObjectsSelectionList->size() == 0) { + aBaseObjectsSelectionList->append(aSketchRes, GeomShapePtr()); + } +} + +void PartSet_WidgetSketchCreator::setEnabledModelWidget(ModuleBase_ModelWidget* theModelWidget, + const bool theEnabled) +{ + QList aMyControls = theModelWidget->getControls(); + foreach(QWidget* eachControl, aMyControls) { + eachControl->setEnabled(theEnabled); + } }