X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;ds=sidebyside;f=src%2FModuleBase%2FModuleBase_Tools.cpp;h=1d8e9d36b046d7027ac8e837ba6f7b33ae802c32;hb=fc72d43b677baa05ae7fd317346fd8b723b799ed;hp=cdbd9202bdaa57fa9ac16ad4c33833e8a906fde6;hpb=b9636a8e25411b3c89aa64801b659bb363278661;p=modules%2Fshaper.git diff --git a/src/ModuleBase/ModuleBase_Tools.cpp b/src/ModuleBase/ModuleBase_Tools.cpp index cdbd9202b..1d8e9d36b 100644 --- a/src/ModuleBase/ModuleBase_Tools.cpp +++ b/src/ModuleBase/ModuleBase_Tools.cpp @@ -1,4 +1,4 @@ -// Copyright (C) 2014-2019 CEA/DEN, EDF R&D +// Copyright (C) 2014-2023 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 @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -36,10 +37,12 @@ #include #include #include +#include #include #include #include #include +#include #include #include @@ -51,6 +54,14 @@ #include #include +#include + +#include + +#ifdef HAVE_SALOME +#include +#include +#endif #include #include @@ -81,6 +92,9 @@ #include #include #include +#include +#include +#include #include #include @@ -105,6 +119,56 @@ namespace ModuleBase_Tools { //****************************************************************** + //! Waits for REDISPLAY message and set the Visible flag to the entities + //! according to Preferences choice. + class ModuleBase_RedisplayListener : public Events_Listener + { + public: + static std::shared_ptr instance() + { + static std::shared_ptr + anInstance(new ModuleBase_RedisplayListener); + return anInstance; + } + + void processEvent(const std::shared_ptr& theMessage) + { + if (theMessage->eventID() == Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY)) + { +#if HAVE_SALOME + // If the python script is being loaded now, the preferences should be used + // to display the required object + SUIT_Session* aSession = SUIT_Session::session(); + if (!aSession) + return; + SUIT_Application * anApp = aSession->activeApplication(); + if (!anApp) + return; + QVariant aVar = anApp->property("IsLoadedScript"); + if (!aVar.isNull() && aVar.toBool()) { + DocumentPtr aRootDoc = ModelAPI_Session::get()->moduleDocument(); + int aSize = aRootDoc->size(ModelAPI_ResultPart::group()); + if (aSize > 0) { + ObjectPtr anPartObject = aRootDoc->object(ModelAPI_ResultPart::group(), aSize - 1); + ResultPartPtr aPart = std::dynamic_pointer_cast(anPartObject); + ModuleBase_Tools::setDisplaying(aPart, true); + } + } +#endif + } + } + + private: + ModuleBase_RedisplayListener() + { + Events_Loop::loop()->registerListener(this, + Events_Loop::eventByName(EVENT_OBJECT_TO_REDISPLAY)); + } + }; + + static std::shared_ptr + RL = ModuleBase_RedisplayListener::instance(); + //****************************************************************** void adjustMargins(QWidget* theWidget) @@ -154,7 +218,7 @@ void setFocus(QWidget* theWidget, const QString& theInfo) activateWindow(theWidget); theWidget->setFocus(); // rectangle of focus is not visible on tool button widgets - theWidget->repaint(); + theWidget->update(); #ifdef DEBUG_SET_FOCUS qDebug(QString("setFocus: %1").arg(theInfo).toStdString().c_str()); #endif @@ -254,7 +318,7 @@ void setSpinValue(QDoubleSpinBox* theSpin, double theValue) void setSpinValue(ModuleBase_ParamSpinBox* theSpin, double theValue) { - if (fabs(theSpin->value() - theValue) < tolerance) + if (!theSpin->text().isEmpty() && fabs(theSpin->value() - theValue) < tolerance) return; bool isBlocked = theSpin->blockSignals(true); theSpin->setValue(theValue); @@ -302,7 +366,7 @@ QString objectName(const ObjectPtr& theObj) if (!theObj.get()) return ""; - return theObj->data()->name().c_str(); + return QString::fromStdWString(theObj->data()->name()); } QString objectInfo(const ObjectPtr& theObj, const bool isUseAttributesInfo) @@ -333,8 +397,8 @@ QString objectInfo(const ObjectPtr& theObj, const bool isUseAttributesInfo) if (aFeature.get()) { aFeatureStr.append(QString(": %1").arg(aFeature->getKind().c_str()).toStdString().c_str()); if (aFeature->data()->isValid()) { - aFeatureStr.append(QString(", name=%1").arg(theObj->data()->name().c_str()).toStdString() - .c_str()); + aFeatureStr.append(QString(", name=%1") + .arg(QString::fromStdWString(theObj->data()->name())).toStdString().c_str()); } if (isUseAttributesInfo) { std::set > anAttributes; @@ -384,7 +448,7 @@ int shapeType(const QString& theType) void checkObjects(const QObjectPtrList& theObjects, bool& hasResult, bool& hasFeature, bool& hasParameter, bool& hasCompositeOwner, bool& hasResultInHistory, - bool& hasFolder) + bool& hasFolder, bool &hasGroupsOnly) { hasResult = false; hasFeature = false; @@ -392,64 +456,43 @@ void checkObjects(const QObjectPtrList& theObjects, bool& hasResult, bool& hasFe hasCompositeOwner = false; hasResultInHistory = false; hasFolder = false; + bool hasNonGroup = false; foreach(ObjectPtr aObj, theObjects) { FeaturePtr aFeature = std::dynamic_pointer_cast(aObj); ResultPtr aResult = std::dynamic_pointer_cast(aObj); + ResultGroupPtr aGroup = std::dynamic_pointer_cast(aObj); FolderPtr aFolder = std::dynamic_pointer_cast(aObj); ResultParameterPtr aConstruction = std::dynamic_pointer_cast(aResult); + FieldStepPtr aStep = std::dynamic_pointer_cast(aObj); - hasResult |= (aResult.get() != NULL); + hasResult |= ((aResult.get() != NULL) || (aStep.get() != NULL)); hasFeature |= (aFeature.get() != NULL); hasFolder |= (aFolder.get() != NULL); hasParameter |= (aConstruction.get() != NULL); + hasNonGroup |= (aGroup.get() == NULL); if (hasFeature) hasCompositeOwner |= (ModelAPI_Tools::compositeOwner(aFeature) != NULL); + else if (aResult.get()) + hasCompositeOwner |= (ModelAPI_Tools::bodyOwner(aResult) != NULL); if (!hasResultInHistory && aResult.get()) { - FeaturePtr aFeature = ModelAPI_Feature::feature(aResult); + aFeature = ModelAPI_Feature::feature(aResult); hasResultInHistory = aFeature.get() && aFeature->isInHistory(); } - if (hasFeature && hasResult && hasParameter && hasCompositeOwner && hasFeature) + if (hasFeature && hasResult && hasParameter && hasCompositeOwner && hasNonGroup) break; } + hasGroupsOnly = !hasNonGroup; } -/*bool setDefaultDeviationCoefficient(std::shared_ptr theGeomShape) -{ - if (!theGeomShape.get()) - return false; - // if the shape could not be exploded on faces, it contains only wires, edges, and vertices - // correction of deviation for them should not influence to the application performance - GeomAPI_ShapeExplorer anExp(theGeomShape, GeomAPI_Shape::FACE); - bool anEmpty = anExp.empty(); - return !anExp.more(); -}*/ - -/*void setDefaultDeviationCoefficient(const std::shared_ptr& theResult, - const Handle(Prs3d_Drawer)& theDrawer) -{ - if (!theResult.get()) - return; - bool aUseDeviation = false; - - std::string aResultGroup = theResult->groupName(); - if (aResultGroup == ModelAPI_ResultConstruction::group()) - aUseDeviation = true; - else if (aResultGroup == ModelAPI_ResultBody::group()) { - GeomShapePtr aGeomShape = theResult->shape(); - if (aGeomShape.get()) - aUseDeviation = setDefaultDeviationCoefficient(aGeomShape); - } - if (aUseDeviation) - theDrawer->SetDeviationCoefficient(DEFAULT_DEVIATION_COEFFICIENT); -} -*/ void setDefaultDeviationCoefficient(const TopoDS_Shape& theShape, const Handle(Prs3d_Drawer)& theDrawer) { if (theShape.IsNull()) return; + if (theDrawer.IsNull()) + return; std::shared_ptr aGeomShape(new GeomAPI_Shape()); aGeomShape->setImpl(new TopoDS_Shape(theShape)); @@ -556,8 +599,8 @@ void getParameters(QStringList& theParameters) int aSize = aDocument->size(aGroupId); for (int i = 0; i < aSize; i++) { ObjectPtr anObject = aDocument->object(aGroupId, i); - std::string aParameterName = anObject->data()->name(); - theParameters.append(aParameterName.c_str()); + std::wstring aParameterName = anObject->data()->name(); + theParameters.append(QString::fromStdWString(aParameterName)); } } } @@ -621,8 +664,7 @@ bool hasObject(const AttributePtr& theAttribute, const ObjectPtr& theObject, if (aType == ModelAPI_AttributeSelectionList::typeId()) { AttributeSelectionListPtr aSelectionListAttr = std::dynamic_pointer_cast(theAttribute); - ResultPtr aResult = std::dynamic_pointer_cast(theObject); - aHasObject = aSelectionListAttr->isInList(aResult, theShape, theTemporarily); + aHasObject = aSelectionListAttr->isInList(theObject, theShape, theTemporarily); } else if (aType == ModelAPI_AttributeRefList::typeId()) { AttributeRefListPtr aRefListAttr = @@ -757,7 +799,9 @@ void flushUpdated(ObjectPtr theObject) // (for the sketch result) to start processing of the sketch in the solver. // TODO: these flushes should be moved in a separate method provided by Model Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_CREATED)); + Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_VISUAL_ATTRIBUTES)); Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED)); + Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_UPDATE_SELECTION)); Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_DELETED)); blockUpdateViewer(false); @@ -932,12 +976,12 @@ bool askToDelete(const std::set theFeatures, const std::string& thePrefixInfo) { QString aNotActivatedDocWrn; - std::string aNotActivatedNames; + std::wstring aNotActivatedNames; if (!ModelAPI_Tools::allDocumentsActivated(aNotActivatedNames)) { if (ModuleBase_Tools::hasModuleDocumentFeature(theFeatures)) aNotActivatedDocWrn = - QObject::tr("Selected objects can be used in Part documents which are not loaded:%1.\n") - .arg(aNotActivatedNames.c_str()); + QObject::tr("Selected objects can be used in Part documents which are not loaded: %1.\n") + .arg(QString::fromStdWString(aNotActivatedNames)); } std::set aFeaturesRefsTo; @@ -953,7 +997,7 @@ bool askToDelete(const std::set theFeatures, continue; if (isFeatureOfResult(aFeature, ModelAPI_ResultPart::group())) - aPartFeatureNames.append(aFeature->name().c_str()); + aPartFeatureNames.append(QString::fromStdWString(aFeature->name())); std::set aRefFeatures; std::set aRefList = theReferences.at(aFeature); @@ -983,7 +1027,7 @@ bool askToDelete(const std::set theFeatures, FeaturePtr aFeature = *anIt; if (theReferencesToDelete.find(aFeature) == theReferencesToDelete.end()) { aFeaturesRefsToParameterOnly.insert(aFeature); - aParamFeatureNames.append(aFeature->name().c_str()); + aParamFeatureNames.append(QString::fromStdWString(aFeature->name())); } } aParamFeatureNames.sort(); @@ -992,23 +1036,23 @@ bool askToDelete(const std::set theFeatures, aLast = theReferencesToDelete.end(); for (; anIt != aLast; anIt++) { FeaturePtr aFeature = *anIt; + if (aFeature->getKind() == "RemoveResults") + continue; // skip the remove results feature mentioning: result will be removed anyway if (isFeatureOfResult(aFeature, ModelAPI_ResultPart::group())) - aPartFeatureNames.append(aFeature->name().c_str()); + aPartFeatureNames.append(QString::fromStdWString(aFeature->name())); else - anOtherFeatureNames.append(aFeature->name().c_str()); + anOtherFeatureNames.append(QString::fromStdWString(aFeature->name())); } aPartFeatureNames.sort(); anOtherFeatureNames.sort(); - bool aCanReplaceParameters = !aFeaturesRefsToParameterOnly.empty(); - QMessageBox aMessageBox(theParent); aMessageBox.setWindowTitle(QObject::tr("Delete features")); aMessageBox.setIcon(QMessageBox::Warning); aMessageBox.setStandardButtons(QMessageBox::No | QMessageBox::Yes); aMessageBox.setDefaultButton(QMessageBox::No); - QString aText; + QString aText, aDetailedText; if (!thePrefixInfo.empty()) aText = thePrefixInfo.c_str(); QString aSep = ", "; @@ -1019,24 +1063,31 @@ bool askToDelete(const std::set theFeatures, if (!aNotActivatedDocWrn.isEmpty()) aText += aNotActivatedDocWrn; if (!anOtherFeatureNames.empty()) { - const char* aMsg = "Features are used in the following features: %1.\nThese " - "features will be deleted.\n"; - aText += QString(QObject::tr(aMsg)) + const char* aMsg = "The selected features are used in some\n" + "other features, which will also be deleted.\n"; + const char* aMsgDetails = "The selected features are used" + " in the following features: %1.\n"; + aText += QString(QObject::tr(aMsg)); + aDetailedText += QString(QObject::tr(aMsgDetails)) .arg(anOtherFeatureNames.join(aSep)); } if (!aParamFeatureNames.empty()) { - const char* aMsg = "Parameters are used directly and through a sequence " - "of dependencies in the following features: %1.\nThese features will " - "be deleted.\nOr parameters could be replaced by their values.\n"; - aText += QString(QObject::tr(aMsg)) + const char* aMsg = "The selected parameters are used directly or through\n" + "a sequence of dependencies in some features.\n" + "These features will be deleted.\n" + "Or parameters could be replaced by their values.\n"; + const char* aMsgDetails = "Parameters are used in the following features: %1.\n"; + aText += QString(QObject::tr(aMsg)); + aDetailedText += QString(QObject::tr(aMsgDetails)) .arg(aParamFeatureNames.join(aSep)); - QPushButton *aReplaceButton = - aMessageBox.addButton(QObject::tr("Replace"), QMessageBox::ActionRole); + aMessageBox.addButton(QObject::tr("Replace"), QMessageBox::ActionRole); } if (!aText.isEmpty()) { - aText += "Would you like to continue?"; aMessageBox.setText(aText); + aMessageBox.setInformativeText(QObject::tr("Would you like to continue?")); + if (!aDetailedText.isEmpty()) + aMessageBox.setDetailedText(aDetailedText); aMessageBox.exec(); QMessageBox::ButtonRole aButtonRole = aMessageBox.buttonRole(aMessageBox.clickedButton()); @@ -1054,6 +1105,33 @@ bool askToDelete(const std::set theFeatures, return true; } +//************************************************************** +bool warningAboutConflict(QWidget* theParent, const std::string& theWarningText) +{ + QMessageBox aMessageBox(theParent); + aMessageBox.setWindowTitle(QObject::tr("Conflicts in constraint")); + aMessageBox.setIcon(QMessageBox::Warning); + aMessageBox.setText((theWarningText + "\nConstraints will be removed or substituted").c_str()); + + QCheckBox* aCheckBox = new QCheckBox; + + aCheckBox->setTristate(false); + aCheckBox->setText("switch off the notifications."); + + aMessageBox.setCheckBox(aCheckBox); + aMessageBox.setStandardButtons(QMessageBox::Ok); + + aMessageBox.exec(); + + if (aCheckBox->isChecked()) + { + ModuleBase_Preferences::resourceMgr()->setValue(SKETCH_TAB_NAME, + "notify_change_constraint", false); + } + + return true; +} + //************************************************************** void convertToFeatures(const QObjectPtrList& theObjects, std::set& theFeatures) { @@ -1115,7 +1193,7 @@ QString translate(const std::string& theContext, const std::string& theMessage) return aMessage; } -void setPointBallHighlighting(AIS_Shape* theAIS) +void setPointBallHighlighting(AIS_InteractiveObject* theAIS) { static Handle(Image_AlienPixMap) aPixMap; if(aPixMap.IsNull()) { @@ -1126,7 +1204,7 @@ void setPointBallHighlighting(AIS_Shape* theAIS) aFile = std::string(anEnv) + FSEP + "share" + FSEP + "salome" + FSEP + "resources" + FSEP + "shaper"; } else { - anEnv = getenv("OPENPARTS_ROOT_DIR"); + anEnv = getenv("CADBUILDER_ROOT_DIR"); if (anEnv) aFile = std::string(anEnv) + FSEP + "resources"; } @@ -1159,11 +1237,19 @@ void setPointBallHighlighting(AIS_Shape* theAIS) anAspect = aPntAspect->Aspect(); anAspect->SetType(Aspect_TOM_BALL); } else { +#if OCC_VERSION_LARGE < 0x07070000 if(aPixMap->Format() == Image_PixMap::ImgGray) { aPixMap->SetFormat (Image_PixMap::ImgAlpha); } else if(aPixMap->Format() == Image_PixMap::ImgGrayF) { aPixMap->SetFormat (Image_PixMap::ImgAlphaF); } +#else + if(aPixMap->Format() == Image_Format_Gray) { + aPixMap->SetFormat (Image_Format_Alpha); + } else if(aPixMap->Format() == Image_Format_GrayF) { + aPixMap->SetFormat (Image_Format_AlphaF); + } +#endif anAspect = new Graphic3d_AspectMarker3d(aPixMap); aPntAspect->SetAspect(anAspect); } @@ -1197,7 +1283,7 @@ FeaturePtr createParameter(const QString& theText) SessionPtr aMgr = ModelAPI_Session::get(); std::shared_ptr aDoc = aMgr->activeDocument(); - aParameter = aDoc->addFeature("Parameter"); + aParameter = aDoc->addFeature("Parameter", false); if (aParameter.get()) { AttributeStringPtr aNameAttr = aParameter->string("variable"); aNameAttr->setValue(aParamName.toStdString()); @@ -1241,7 +1327,7 @@ bool isNameExist(const QString& theName, FeaturePtr theIgnoreParameter) std::shared_ptr aDoc = aMgr->activeDocument(); FeaturePtr aParamFeature; int aNbFeatures = aDoc->numInternalFeatures(); - std::string aName = theName.toStdString(); + std::wstring aName = theName.toStdWString(); for (int i = 0; i < aNbFeatures; i++) { aParamFeature = aDoc->internalFeature(i); if (aParamFeature && aParamFeature->getKind() == "Parameter") { @@ -1258,7 +1344,7 @@ FeaturePtr findParameter(const QString& theName) std::shared_ptr aDoc = aMgr->activeDocument(); FeaturePtr aParamFeature; int aNbFeatures = aDoc->numInternalFeatures(); - std::string aName = theName.toStdString(); + std::wstring aName = theName.toStdWString(); for (int i = 0; i < aNbFeatures; i++) { aParamFeature = aDoc->internalFeature(i); if (aParamFeature && aParamFeature->getKind() == "Parameter") { @@ -1271,13 +1357,11 @@ FeaturePtr findParameter(const QString& theName) //******************************************************************** -std::string generateName(const AttributePtr& theAttribute, +std::wstring generateName(const AttributePtr& theAttribute, ModuleBase_IWorkshop* theWorkshop) { - std::string aName; + std::wstring aName; if (theAttribute.get() != NULL) { - ModuleBase_Operation* anOperation = theWorkshop->currentOperation(); - FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner()); if (aFeature.get()) { std::string aXmlCfg, aDescription; @@ -1287,7 +1371,7 @@ std::string generateName(const AttributePtr& theAttribute, std::string anAttributeTitle; aFactory.getAttributeTitle(theAttribute->id(), anAttributeTitle); - std::stringstream aStreamName; + std::wstringstream aStreamName; aStreamName << theAttribute->owner()->data()->name() << "/" << anAttributeTitle.c_str(); aName = aStreamName.str(); } @@ -1295,6 +1379,88 @@ std::string generateName(const AttributePtr& theAttribute, return aName; } +bool isSameShape(const TopoDS_Shape& theShape1, const TopoDS_Shape& theShape2) +{ + // In case of compound we cannot rely on simple comparison method. + // If the compound is generated by Group feature then this compound is alwais new. + // So, we have to compare content of these compounds + if (theShape1.ShapeType() != theShape2.ShapeType()) + return false; + + if (theShape1.ShapeType() != TopAbs_COMPOUND) + return theShape1.IsSame(theShape2); + + TopoDS_Iterator aIt1(theShape1); + TopoDS_Iterator aIt2(theShape2); + + for (; aIt1.More() && aIt2.More(); aIt1.Next(), aIt2.Next()) { + if (!(aIt1.Value()).IsSame(aIt2.Value())) + return false; + } + return true; +} + +qreal currentPixelRatio() +{ + QWindowList aWnds = qApp->topLevelWindows(); + if (aWnds.size() > 0) + return aWnds.first()->devicePixelRatio(); + return qApp->primaryScreen()->devicePixelRatio(); +} + + +// Set displaying status to every element on group +static void setDisplayingByLoop(DocumentPtr theDoc, int theSize, + std::string theGroup, bool theDisplayFromScript, int theDisplayingId) +{ + for (int anIndex = theSize - 1; anIndex >= 0; --anIndex) { + ObjectPtr anObject = theDoc->object(theGroup, anIndex); + anObject->setDisplayed((theDisplayingId == 1 && anIndex == theSize - 1) || + theDisplayingId == 2); + } +} + +void setDisplaying(ResultPartPtr thePart, bool theDisplayFromScript) +{ + static bool isDoingDisplay = false; + + if (isDoingDisplay) + return; + + isDoingDisplay = true; + DocumentPtr aDoc = thePart->partDoc(); + int aConstructionSize = aDoc->size(ModelAPI_ResultConstruction::group()); + int aGroupSize = aDoc->size(ModelAPI_ResultGroup::group()); + int aFieldSize = aDoc->size(ModelAPI_ResultField::group()); + int aResultSize = aDoc->size(ModelAPI_ResultBody::group()); + + int aDisplayingId = -1; + if (theDisplayFromScript) { + aDisplayingId = ModuleBase_Preferences::resourceMgr()->integerValue("General", + "part_visualization_script", -1); + // Increase ID to prevert using "As stored in HDF" + ++aDisplayingId; + } + else { + aDisplayingId = ModuleBase_Preferences::resourceMgr()->integerValue("General", + "part_visualization_study", -1); + + // if chosen "As stored in HDF" then don't change displaying + if (aDisplayingId == 0) + return; + } + + setDisplayingByLoop(aDoc, aConstructionSize, ModelAPI_ResultConstruction::group(), + theDisplayFromScript, aDisplayingId); + setDisplayingByLoop(aDoc, aGroupSize, ModelAPI_ResultGroup::group(), + theDisplayFromScript, aDisplayingId); + setDisplayingByLoop(aDoc, aFieldSize, ModelAPI_ResultField::group(), + theDisplayFromScript, aDisplayingId); + setDisplayingByLoop(aDoc, aResultSize, ModelAPI_ResultBody::group(), + theDisplayFromScript, aDisplayingId); + isDoingDisplay = false; +} + } // namespace ModuleBase_Tools