X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FPartSet%2FPartSet_WidgetSketchCreator.cpp;h=14bfd60fa9aae8c043d831a3567219d51f086184;hb=ae42afe3e35f7d69b26ef66323c54eb9e2fe45fe;hp=1f00cc5a1c02a5650d3142d432e0ca517d013342;hpb=f4b66a0744e13778ab35f7e165d968c868dd6d9f;p=modules%2Fshaper.git diff --git a/src/PartSet/PartSet_WidgetSketchCreator.cpp b/src/PartSet/PartSet_WidgetSketchCreator.cpp index 1f00cc5a1..14bfd60fa 100644 --- a/src/PartSet/PartSet_WidgetSketchCreator.cpp +++ b/src/PartSet/PartSet_WidgetSketchCreator.cpp @@ -1,8 +1,21 @@ -// Copyright (C) 2014-20xx CEA/DEN, EDF R&D - -// File: PartSet_WidgetSketchCreator.cpp -// Created: 08 June 2015 -// Author: Vitaly SMETANNIKOV +// Copyright (C) 2014-2021 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 "PartSet_WidgetSketchCreator.h" #include "PartSet_Module.h" @@ -22,6 +35,8 @@ #include +#include + #include #include #include @@ -37,12 +52,18 @@ #include #include #include +#include +#include +#include +#include + #include #include #include #include +#include //#include #include #include @@ -50,7 +71,26 @@ #define DEBUG_UNDO_INVALID_SKETCH -PartSet_WidgetSketchCreator::PartSet_WidgetSketchCreator(QWidget* theParent, + + +QStringList getIconsList(const QStringList& theNames) +{ + QStringList aIcons; + foreach(QString aName, theNames) { + QString aUName = aName.toUpper(); + if ((aUName == "VERTICES") || (aUName == "VERTEX")) + aIcons << ":pictures/vertex32.png"; + else if ((aUName == "EDGES") || (aUName == "EDGE")) + aIcons << ":pictures/edge32.png"; + else if ((aUName == "FACES") || (aUName == "FACE")) + aIcons << ":pictures/face32.png"; + } + return aIcons; +} + + + +PartSet_WidgetSketchCreator::PartSet_WidgetSketchCreator(QWidget* theParent, PartSet_Module* theModule, const Config_WidgetAPI* theData) : ModuleBase_WidgetSelector(theParent, theModule->workshop(), theData), @@ -64,17 +104,65 @@ PartSet_WidgetSketchCreator::PartSet_WidgetSketchCreator(QWidget* theParent, ModuleBase_Tools::adjustMargins(aLayout); - QString aLabelText = QString::fromStdString(theData->widgetLabel()); + QString aLabelText = translate(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(tr("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); myLabel->setWordWrap(true); + + aLayout->addWidget(mySizeOfViewWidget); aLayout->addWidget(myLabel); - aLayout->addStretch(1); std::string aTypes = theData->getProperty("shape_types"); myShapeTypes = QString(aTypes.c_str()).split(' ', QString::SkipEmptyParts); + myIsUseChoice = theData->getBooleanAttribute("use_choice", false); + + QStringList aIconsList; + std::string aIcons = theData->getProperty("type_icons"); + if (aIcons.size() > 0) + aIconsList = QString(aIcons.c_str()).split(' ', QString::SkipEmptyParts); + + if (aIconsList.size() != myShapeTypes.size()) + aIconsList = getIconsList(myShapeTypes); + + myTypeCtrl = new ModuleBase_ChoiceCtrl(this, myShapeTypes, aIconsList); + myTypeCtrl->setLabel(tr("Type")); + if (!myShapeTypes.empty()) { + std::string aDefType = theData->getProperty("default_type"); + if (aDefType.size() > 0) { + bool aOk = false; + int aId = QString(aDefType.c_str()).toInt(&aOk); + if (aOk) { + myTypeCtrl->setValue(aId); + myDefMode = myShapeTypes.at(aId).toStdString(); + } + } + if (myDefMode.size() == 0) { + myTypeCtrl->setValue(0); + myDefMode = myShapeTypes.first().toStdString(); + } + } + aLayout->addWidget(myTypeCtrl); + // There is no sense to parameterize list of types while we can not parameterize selection mode + // if the xml definition contains one type, the controls to select a type should not be shown + if (myShapeTypes.size() <= 1 || !myIsUseChoice) { + myTypeCtrl->setVisible(false); + } + connect(myTypeCtrl, SIGNAL(valueChanged(int)), this, SLOT(onSelectionTypeChanged())); + aLayout->addStretch(1); myPreviewPlanes = new PartSet_PreviewPlanes(); } @@ -97,7 +185,7 @@ bool PartSet_WidgetSketchCreator::restoreValueCustom() return true; } -bool PartSet_WidgetSketchCreator::storeValueCustom() const +bool PartSet_WidgetSketchCreator::storeValueCustom() { return true; } @@ -125,7 +213,7 @@ void PartSet_WidgetSketchCreator::openExtrusionTransaction() } //******************************************************************** -bool PartSet_WidgetSketchCreator::isValidSelection(const ModuleBase_ViewerPrs& theValue) +bool PartSet_WidgetSketchCreator::isValidSelection(const ModuleBase_ViewerPrsPtr& theValue) { bool aValid = false; if (myIsCustomAttribute) { @@ -155,13 +243,17 @@ bool PartSet_WidgetSketchCreator::isValidSelection(const ModuleBase_ViewerPrs& t } //******************************************************************** -bool PartSet_WidgetSketchCreator::isValidSelectionCustom(const ModuleBase_ViewerPrs& theValue) +bool PartSet_WidgetSketchCreator::isValidSelectionCustom(const ModuleBase_ViewerPrsPtr& theValue) { return PartSet_WidgetSketchLabel::canFillSketch(theValue); } void PartSet_WidgetSketchCreator::activateSelectionControl() { + // reset previously set size of view needed on restart extrusion after Sketch + if (myModule->sketchMgr()->previewSketchPlane()->isUseSizeOfView()) + myModule->sketchMgr()->previewSketchPlane()->setSizeOfView(0, false); + // 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()); @@ -193,10 +285,16 @@ void PartSet_WidgetSketchCreator::setVisibleSelectionControl(const bool theSelec if (theSelectionControl) { bool aBodyIsVisualized = myPreviewPlanes->hasVisualizedBodies(myWorkshop); - if (!aBodyIsVisualized) { + 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); } + } else { bool aHidePreview = myPreviewPlanes->isPreviewDisplayed(); myPreviewPlanes->erasePreviewPlanes(myWorkshop); @@ -205,11 +303,22 @@ void PartSet_WidgetSketchCreator::setVisibleSelectionControl(const bool theSelec } } -QIntList PartSet_WidgetSketchCreator::getShapeTypes() const +QIntList PartSet_WidgetSketchCreator::shapeTypes() const { QIntList aShapeTypes; - foreach(QString aType, myShapeTypes) { - aShapeTypes.append(ModuleBase_Tools::shapeType(aType)); + if (myShapeTypes.length() > 1 && myIsUseChoice) { + QStringList aTypes = myTypeCtrl->textValue().split("|", QString::SkipEmptyParts); + foreach(QString aType, aTypes) { + aShapeTypes.append(ModuleBase_Tools::shapeType(aType)); + } + } + else { + foreach(QString aType, myShapeTypes) { + QStringList aSubTypes = aType.split("|", QString::SkipEmptyParts); + foreach(QString asubType, aSubTypes) { + aShapeTypes.append(ModuleBase_Tools::shapeType(asubType)); + } + } } return aShapeTypes; } @@ -246,24 +355,23 @@ bool PartSet_WidgetSketchCreator::isSelectionMode() const 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, +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(); + QList::const_iterator + anIt = theValues.begin(), aLast = theValues.end(); bool aProcessed = false; for (; anIt != aLast; anIt++) { - ModuleBase_ViewerPrs aValue = *anIt; + ModuleBase_ViewerPrsPtr aValue = *anIt; if (!theToValidate || isValidInFilters(aValue)) aProcessed = setSelectionCustom(aValue) || aProcessed; } @@ -273,7 +381,8 @@ bool PartSet_WidgetSketchCreator::setSelection(QList& theV emit valuesChanged(); updateObject(myFeature); setVisibleSelectionControl(false); - // manually deactivation because the widget was not activated as has no focus acceptin controls + // manually deactivation because the widget was + // not activated as has no focus acceptin controls deactivate(); emit focusOutWidget(this); } @@ -282,10 +391,12 @@ bool PartSet_WidgetSketchCreator::setSelection(QList& theV } //******************************************************************** -void PartSet_WidgetSketchCreator::onSelectionChanged() +bool PartSet_WidgetSketchCreator::processSelection() { - QList aSelected = getFilteredSelected(); + QList aSelected = getFilteredSelected(); bool isDone = setSelection(aSelected, true/*false*/); + + return isDone; } //******************************************************************** @@ -293,36 +404,56 @@ void PartSet_WidgetSketchCreator::updateOnSelectionChanged(const bool theDone) { } -bool PartSet_WidgetSketchCreator::startSketchOperation(const QList& theValues) +bool PartSet_WidgetSketchCreator::startSketchOperation( + const QList& theValues) { bool aSketchStarted = false; if (theValues.size() != 1) return aSketchStarted; - ModuleBase_ViewerPrs aValue = theValues.front(); - if (!PartSet_WidgetSketchLabel::canFillSketch(aValue)) + 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())) { + // set default plane size + bool isSetSizeOfView = false; + double aSizeOfView = 0; + QString aSizeOfViewStr = mySizeOfView->text(); + if (!aSizeOfViewStr.isEmpty()) { + aSizeOfView = aSizeOfViewStr.toDouble(&isSetSizeOfView); + if (isSetSizeOfView && aSizeOfView <= 0) { + isSetSizeOfView = false; + } + } + if (isSetSizeOfView) + myModule->sketchMgr()->previewSketchPlane()->setSizeOfView(aSizeOfView, true); + } // 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); - // start edit operation for the sketch ModuleBase_OperationFeature* aFOperation = dynamic_cast (myModule->createOperation("Sketch")); - QList aValues; + QList aValues; aValues.push_back(aValue); aFOperation->setPreselection(aValues); - myModule->sendOperation(aFOperation); + myWorkshop->processLaunchOperation(aFOperation); return aSketchStarted; } @@ -337,7 +468,8 @@ bool PartSet_WidgetSketchCreator::focusTo() return true; } else - connect(myModule, SIGNAL(resumed(ModuleBase_Operation*)), SLOT(onResumed(ModuleBase_Operation*))); + connect(myModule, SIGNAL(resumed(ModuleBase_Operation*)), + SLOT(onResumed(ModuleBase_Operation*))); return true; } @@ -368,12 +500,11 @@ void PartSet_WidgetSketchCreator::onResumed(ModuleBase_Operation* theOp) // Validate the created sketch. If it is valid, it is set into the composite feature selection // list, otherwise it is removed - CompositeFeaturePtr aCompFeature = + CompositeFeaturePtr aCompFeature = std::dynamic_pointer_cast(myFeature); 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(); 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); @@ -387,13 +518,13 @@ void PartSet_WidgetSketchCreator::onResumed(ModuleBase_Operation* theOp) aMgr->startOperation("Delete invalid Sketch feature", false); // delete invalid sketch - CompositeFeaturePtr aSketchFeature = + 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, std::set()); + aWorkshop->deleteFeatures(anObjects); aMgr->finishOperation(); #endif @@ -412,15 +543,22 @@ void PartSet_WidgetSketchCreator::onResumed(ModuleBase_Operation* theOp) // Update value in attribute selection list XGUI_Workshop* aWorkshop = XGUI_Tools::workshop(myModule->workshop()); - XGUI_PropertyPanel* aPanel = aWorkshop->propertyPanel(); - const QList& aWidgets = aPanel->modelWidgets(); + XGUI_PropertyPanel* aPropertyPanel = aWorkshop->propertyPanel(); + const QList& aWidgets = aPropertyPanel->modelWidgets(); + ModuleBase_ModelWidget* aListWidget = 0; foreach(ModuleBase_ModelWidget* aWidget, aWidgets) { - if (aWidget->attributeID() == myAttributeListID) - aWidget->restoreValue(); + if (aWidget->attributeID() == myAttributeListID) { + aListWidget = aWidget; + break; + } + } + if (aListWidget) { + aListWidget->restoreValue(); + aPropertyPanel->activateNextWidget(aListWidget); } // Hide sketcher result - CompositeFeaturePtr aSketchFeature = + CompositeFeaturePtr aSketchFeature = std::dynamic_pointer_cast(aCompFeature->subFeature(0)); std::list aResults = aSketchFeature->results(); std::list::const_iterator aIt; @@ -440,10 +578,10 @@ void PartSet_WidgetSketchCreator::onResumed(ModuleBase_Operation* theOp) (aData->attribute(SketchPlugin_SketchEntity::EXTERNAL_ID())); ResultPtr aRes = aSelAttr.get() ? aSelAttr->context() : ResultPtr(); if (aRes.get()) { - SessionPtr aMgr = ModelAPI_Session::get(); ModelAPI_ValidatorsFactory* aFactory = aMgr->validators(); AttributePtr anAttribute = myFeature->attribute(anObjectsAttribute); - std::string aValidatorID, anError; + std::string aValidatorID; + Events_InfoMessage anError; aSelList->append(aRes, GeomShapePtr()); if (aFactory->validate(anAttribute, aValidatorID, anError)) updateObject(aCompFeature); @@ -461,19 +599,23 @@ bool PartSet_WidgetSketchCreator::validateSelectionList() const SessionPtr aMgr = ModelAPI_Session::get(); ModelAPI_ValidatorsFactory* aFactory = aMgr->validators(); - std::string aValidatorID, anError; + 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.c_str()), + 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) +void PartSet_WidgetSketchCreator::setSketchObjectToList( + const CompositeFeaturePtr& theCompositeFeature, + const AttributePtr& theAttribute) { if (!theCompositeFeature.get() || theCompositeFeature->numberOfSubs() != 1) return; @@ -490,7 +632,8 @@ void PartSet_WidgetSketchCreator::setSketchObjectToList(const CompositeFeaturePt } ResultPtr aSketchRes = aSketchFeature->results().front(); - ResultConstructionPtr aConstruction = std::dynamic_pointer_cast(aSketchRes); + ResultConstructionPtr aConstruction = + std::dynamic_pointer_cast(aSketchRes); if(!aConstruction.get()) { return; } @@ -508,3 +651,38 @@ void PartSet_WidgetSketchCreator::setEnabledModelWidget(ModuleBase_ModelWidget* eachControl->setEnabled(theEnabled); } } + +void PartSet_WidgetSketchCreator::onSelectionTypeChanged() +{ + // Clear current selection in order to avoid updating of object browser with obsolete indexes + // which can appear because of results deletetion after changing a type of selection + QString aSelectionType = myTypeCtrl->textValue(); + QList aEmptyList; + myWorkshop->setSelected(aEmptyList); + + updateSelectionModesAndFilters(true); + myWorkshop->selectionActivate()->updateSelectionModes(); + + if (!myFeature) + return; + + if (aSelectionType != "Faces") { + setVisibleSelectionControl(false); + myWorkshop->propertyPanel()->activateNextWidget(); + } + + /// store the selected type + AttributeSelectionListPtr anAttrList = myFeature->data()->selectionList(myAttributeListID); + anAttrList->setSelectionType(aSelectionType.toStdString()); + anAttrList->clear(); + + // update object is necessary to flush update signal. It leads to objects references map update + // and the operation presentation will not contain deleted items visualized as parameters of + // the feature. + updateObject(myFeature); + myWorkshop->propertyPanel()->activeWidget()->restoreValue(); + myWorkshop->setSelected(getAttributeSelection()); + // may be the feature's result is not displayed, but attributes should be + // hope that something is redisplayed by object updated + myWorkshop->module()->customizeFeature(myFeature, ModuleBase_IModule::CustomizeArguments, true); +} \ No newline at end of file