]> SALOME platform Git repositories - modules/shaper.git/blob - src/ModuleBase/ModuleBase_Tools.cpp
Salome HOME
Initial implementation of support of any level of hierarchy in Result Bodies.
[modules/shaper.git] / src / ModuleBase / ModuleBase_Tools.cpp
1 // Copyright (C) 2014-2017  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or
18 // email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
19 //
20
21 #include "ModuleBase_Tools.h"
22
23 #include <ModuleBase_ParamIntSpinBox.h>
24 #include <ModuleBase_ParamSpinBox.h>
25 #include <ModuleBase_WidgetFactory.h>
26 #include <ModuleBase_IWorkshop.h>
27 #include <ModuleBase_IModule.h>
28 #include <ModuleBase_IViewer.h>
29 #include <ModuleBase_IconFactory.h>
30 #include <ModuleBase_ResultPrs.h>
31 #include <ModuleBase_ViewerPrs.h>
32
33 #include <ModelAPI_Attribute.h>
34 #include <ModelAPI_AttributeRefAttr.h>
35 #include <ModelAPI_AttributeReference.h>
36 #include <ModelAPI_AttributeSelection.h>
37 #include <ModelAPI_AttributeSelectionList.h>
38 #include <ModelAPI_AttributeRefList.h>
39 #include <ModelAPI_AttributeRefAttrList.h>
40 #include <ModelAPI_ResultPart.h>
41 #include <ModelAPI_ResultConstruction.h>
42 #include <ModelAPI_AttributeString.h>
43 #include <ModelAPI_Expression.h>
44 #include <Events_Loop.h>
45
46 #include <ModelAPI_Data.h>
47 #include <ModelAPI_Result.h>
48 #include <ModelAPI_ResultParameter.h>
49 #include <ModelAPI_Tools.h>
50 #include <ModelAPI_Session.h>
51 #include <ModelAPI_Events.h>
52 #include <ModelAPI_Folder.h>
53
54 #include <ModelGeomAlgo_Point2D.h>
55
56 #include <StdSelect_BRepOwner.hxx>
57 #include <TopoDS_Iterator.hxx>
58 #include <AIS_InteractiveContext.hxx>
59 #include <Prs3d_LineAspect.hxx>
60 #include <Prs3d_PlaneAspect.hxx>
61
62 #include <GeomDataAPI_Point2D.h>
63 #include <Events_InfoMessage.h>
64 #include <GeomAPI_ShapeExplorer.h>
65
66 #include <Config_PropManager.h>
67 #include <Config_Translator.h>
68
69 #include <Prs3d_PointAspect.hxx>
70 #include <Graphic3d_AspectMarker3d.hxx>
71
72 #include <Image_AlienPixMap.hxx>
73
74 #include <QWidget>
75 #include <QLayout>
76 #include <QPainter>
77 #include <QBitmap>
78 #include <QDoubleSpinBox>
79 #include <QGraphicsDropShadowEffect>
80 #include <QColor>
81 #include <QApplication>
82 #include <QMessageBox>
83 #include <QAction>
84 #include <QTextCodec>
85
86 #include <sstream>
87 #include <string>
88
89 #ifdef WIN32
90 #pragma warning(disable : 4996) // for getenv
91 #endif
92
93 const double tolerance = 1e-7;
94 const double DEFAULT_DEVIATION_COEFFICIENT = 1.e-4;
95
96 //#define DEBUG_ACTIVATE_WINDOW
97 //#define DEBUG_SET_FOCUS
98
99 #ifdef WIN32
100 # define FSEP "\\"
101 #else
102 # define FSEP "/"
103 #endif
104
105 namespace ModuleBase_Tools {
106
107 //******************************************************************
108
109 //******************************************************************
110
111 void adjustMargins(QWidget* theWidget)
112 {
113   if(!theWidget)
114     return;
115   adjustMargins(theWidget->layout());
116 }
117
118 void adjustMargins(QLayout* theLayout)
119 {
120   if(!theLayout)
121     return;
122   theLayout->setContentsMargins(2, 5, 2, 5);
123   theLayout->setSpacing(4);
124 }
125
126 void zeroMargins(QWidget* theWidget)
127 {
128   if(!theWidget)
129     return;
130   zeroMargins(theWidget->layout());
131 }
132
133 void zeroMargins(QLayout* theLayout)
134 {
135   if(!theLayout)
136     return;
137   theLayout->setContentsMargins(0, 0, 0, 0);
138   theLayout->setSpacing(5);
139 }
140
141 void activateWindow(QWidget* theWidget, const QString& theInfo)
142 {
143   if (theWidget) {
144     theWidget->activateWindow();
145     theWidget->raise();
146   }
147
148 #ifdef DEBUG_ACTIVATE_WINDOW
149   qDebug(QString("activateWindow: %1").arg(theInfo).toStdString().c_str());
150 #endif
151 }
152
153 void setFocus(QWidget* theWidget, const QString& theInfo)
154 {
155   activateWindow(theWidget);
156   theWidget->setFocus();
157   // rectangle of focus is not visible on tool button widgets
158   theWidget->repaint();
159 #ifdef DEBUG_SET_FOCUS
160   qDebug(QString("setFocus: %1").arg(theInfo).toStdString().c_str());
161 #endif
162 }
163
164 void setShadowEffect(QWidget* theWidget, const bool isSetEffect)
165 {
166   if (isSetEffect) {
167     QGraphicsDropShadowEffect* aGlowEffect = new QGraphicsDropShadowEffect();
168     aGlowEffect->setOffset(.0);
169     aGlowEffect->setBlurRadius(10.0);
170     aGlowEffect->setColor(QColor(0, 170, 255)); // Light-blue color, #00AAFF
171     theWidget->setGraphicsEffect(aGlowEffect);
172   }
173   else {
174     QGraphicsEffect* anEffect = theWidget->graphicsEffect();
175     if(anEffect)
176       anEffect->deleteLater();
177     theWidget->setGraphicsEffect(NULL);
178   }
179 }
180
181 QPixmap composite(const QString& theAdditionalIcon, const QString& theIcon)
182 {
183   QImage anIcon = ModuleBase_IconFactory::loadImage(theIcon);
184   QImage anAditional(theAdditionalIcon);
185
186   if (anIcon.isNull())
187     return QPixmap();
188
189   int anAddWidth = anAditional.width();
190   int anAddHeight = anAditional.height();
191
192   int aWidth = anIcon.width();
193   int aHeight = anIcon.height();
194
195   int aStartWidthPos = aWidth - anAddWidth - 1;
196   int aStartHeightPos = aHeight - anAddHeight - 1;
197
198   for (int i = 0; i < anAddWidth && i + aStartWidthPos < aWidth; i++)
199   {
200     for (int j = 0; j < anAddHeight && j + aStartHeightPos < aHeight; j++)
201     {
202       if (qAlpha(anAditional.pixel(i, j)) > 0)
203         anIcon.setPixel(i + aStartWidthPos, j + aStartHeightPos, anAditional.pixel(i, j));
204     }
205   }
206   return QPixmap::fromImage(anIcon);
207 }
208
209 QPixmap lighter(const QString& theIcon, const int theLighterValue)
210 {
211   QImage anIcon = ModuleBase_IconFactory::loadImage(theIcon);
212   if (anIcon.isNull())
213     return QPixmap();
214
215   QImage aResult = ModuleBase_IconFactory::loadImage(theIcon);
216   for (int i = 0; i < anIcon.width(); i++)
217   {
218     for (int j = 0; j < anIcon.height(); j++)
219     {
220       QRgb anRgb = anIcon.pixel(i, j);
221       QColor aPixelColor(qRed(anRgb), qGreen(anRgb), qBlue(anRgb),
222                          qAlpha(aResult.pixel(i, j)));
223
224       QColor aLighterColor = aPixelColor.lighter(theLighterValue);
225       aResult.setPixel(i, j, qRgba(aLighterColor.red(), aLighterColor.green(),
226                                     aLighterColor.blue(), aLighterColor.alpha()));
227     }
228   }
229   return QPixmap::fromImage(aResult);
230 }
231
232 void setSpinText(ModuleBase_ParamSpinBox* theSpin, const QString& theText)
233 {
234   if (theSpin->text() == theText)
235     return;
236   // In order to avoid extra text setting because it will
237   // reset cursor position in control
238   bool isBlocked = theSpin->blockSignals(true);
239   theSpin->setText(theText);
240   theSpin->blockSignals(isBlocked);
241 }
242
243 void setSpinValue(QDoubleSpinBox* theSpin, double theValue)
244 {
245   if (fabs(theSpin->value() - theValue) < tolerance)
246     return;
247   bool isBlocked = theSpin->blockSignals(true);
248   theSpin->setValue(theValue);
249   theSpin->blockSignals(isBlocked);
250 }
251
252 void setSpinValue(ModuleBase_ParamSpinBox* theSpin, double theValue)
253 {
254   if (fabs(theSpin->value() - theValue) < tolerance)
255     return;
256   bool isBlocked = theSpin->blockSignals(true);
257   theSpin->setValue(theValue);
258   theSpin->blockSignals(isBlocked);
259 }
260
261 void setSpinText(ModuleBase_ParamIntSpinBox* theSpin, const QString& theText)
262 {
263   // In order to avoid extra text setting because it will
264   // reset cursor position in control
265   if (theSpin->text() == theText)
266     return;
267   bool isBlocked = theSpin->blockSignals(true);
268   theSpin->setText(theText);
269   theSpin->blockSignals(isBlocked);
270 }
271
272 void setSpinValue(ModuleBase_ParamIntSpinBox* theSpin, int theValue)
273 {
274   if (theSpin->value() == theValue)
275     return;
276   bool isBlocked = theSpin->blockSignals(true);
277   theSpin->setValue(theValue);
278   theSpin->blockSignals(isBlocked);
279 }
280
281 QAction* createAction(const QIcon& theIcon, const QString& theText,
282                       QObject* theParent, const QObject* theReceiver,
283                       const char* theMember, const QString& theToolTip,
284                       const QString& theStatusTip)
285 {
286   QAction* anAction = new QAction(theIcon, theText, theParent);
287   anAction->setToolTip(theToolTip.isEmpty() ? theText : theToolTip);
288   anAction->setStatusTip(!theStatusTip.isEmpty() ? theStatusTip :
289                                                    (!theToolTip.isEmpty() ? theToolTip : theText));
290   if (theReceiver)
291     QObject::connect(anAction, SIGNAL(triggered(bool)), theReceiver, theMember);
292
293   return anAction;
294 }
295
296 #ifdef _DEBUG
297 QString objectName(const ObjectPtr& theObj)
298 {
299   if (!theObj.get())
300     return "";
301
302   return theObj->data()->name().c_str();
303 }
304
305 QString objectInfo(const ObjectPtr& theObj, const bool isUseAttributesInfo)
306 {
307   QString aFeatureStr = "feature";
308   if (!theObj.get())
309     return aFeatureStr;
310
311   std::ostringstream aPtrStr;
312   aPtrStr << "[" << theObj.get() << "]";
313
314   ResultPtr aRes = std::dynamic_pointer_cast<ModelAPI_Result>(theObj);
315   FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theObj);
316   if(aRes.get()) {
317     aFeatureStr.append(QString("(result%1)").arg(aPtrStr.str().c_str()).toStdString() .c_str());
318     if (aRes->isDisabled())
319       aFeatureStr.append("[disabled]");
320     if (aRes->isConcealed())
321       aFeatureStr.append("[concealed]");
322     if (ModelAPI_Tools::hasSubResults(aRes))
323       aFeatureStr.append("[hasSubResults]");
324
325     aFeature = ModelAPI_Feature::feature(aRes);
326   }
327   else
328     aFeatureStr.append(aPtrStr.str().c_str());
329
330   if (aFeature.get()) {
331     aFeatureStr.append(QString(": %1").arg(aFeature->getKind().c_str()).toStdString().c_str());
332     if (aFeature->data()->isValid()) {
333       aFeatureStr.append(QString(", name=%1").arg(theObj->data()->name().c_str()).toStdString()
334                                                                                        .c_str());
335     }
336     if (isUseAttributesInfo) {
337       std::set<std::shared_ptr<ModelAPI_Attribute> > anAttributes;
338       std::string aPointsInfo = ModelGeomAlgo_Point2D::getPontAttributesInfo(aFeature,
339                                                                           anAttributes).c_str();
340       if (!aPointsInfo.empty())
341         aFeatureStr.append(QString(", attributes: %1")
342           .arg(aPointsInfo.c_str()).toStdString().c_str());
343     }
344   }
345
346   return aFeatureStr;
347 }
348 #endif
349
350 typedef QMap<QString, int> ShapeTypes;
351 static ShapeTypes myShapeTypes;
352
353 int shapeType(const QString& theType)
354 {
355   if (myShapeTypes.count() == 0) {
356     myShapeTypes["compound"]   = TopAbs_COMPOUND;
357     myShapeTypes["compounds"]  = TopAbs_COMPOUND;
358     myShapeTypes["compsolid"]  = TopAbs_COMPSOLID;
359     myShapeTypes["compsolids"] = TopAbs_COMPSOLID;
360     myShapeTypes["solid"]      = TopAbs_SOLID;
361     myShapeTypes["solids"]     = TopAbs_SOLID;
362     myShapeTypes["shell"]      = TopAbs_SHELL;
363     myShapeTypes["shells"]     = TopAbs_SHELL;
364     myShapeTypes["face"]       = TopAbs_FACE;
365     myShapeTypes["faces"]      = TopAbs_FACE;
366     myShapeTypes["wire"]       = TopAbs_WIRE;
367     myShapeTypes["wires"]      = TopAbs_WIRE;
368     myShapeTypes["edge"]       = TopAbs_EDGE;
369     myShapeTypes["edges"]      = TopAbs_EDGE;
370     myShapeTypes["vertex"]     = TopAbs_VERTEX;
371     myShapeTypes["vertices"]   = TopAbs_VERTEX;
372     myShapeTypes["object"]     = ModuleBase_ResultPrs::Sel_Result;
373     myShapeTypes["objects"]    = ModuleBase_ResultPrs::Sel_Result;
374   }
375   QString aType = theType.toLower();
376   if(myShapeTypes.contains(aType))
377     return myShapeTypes[aType];
378   Events_InfoMessage("ModuleBase_Tools", "Shape type defined in XML is not implemented!").send();
379   return TopAbs_SHAPE;
380 }
381
382 void checkObjects(const QObjectPtrList& theObjects, bool& hasResult, bool& hasFeature,
383                   bool& hasParameter, bool& hasCompositeOwner, bool& hasResultInHistory,
384                   bool& hasFolder)
385 {
386   hasResult = false;
387   hasFeature = false;
388   hasParameter = false;
389   hasCompositeOwner = false;
390   hasResultInHistory = false;
391   hasFolder = false;
392   foreach(ObjectPtr aObj, theObjects) {
393     FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aObj);
394     ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(aObj);
395     FolderPtr aFolder = std::dynamic_pointer_cast<ModelAPI_Folder>(aObj);
396     ResultParameterPtr aConstruction = std::dynamic_pointer_cast<ModelAPI_ResultParameter>(aResult);
397
398     hasResult |= (aResult.get() != NULL);
399     hasFeature |= (aFeature.get() != NULL);
400     hasFolder |= (aFolder.get() != NULL);
401     hasParameter |= (aConstruction.get() != NULL);
402     if (hasFeature)
403       hasCompositeOwner |= (ModelAPI_Tools::compositeOwner(aFeature) != NULL);
404
405     if (!hasResultInHistory && aResult.get()) {
406       FeaturePtr aFeature = ModelAPI_Feature::feature(aResult);
407       hasResultInHistory = aFeature.get() && aFeature->isInHistory();
408     }
409
410     if (hasFeature && hasResult  && hasParameter && hasCompositeOwner && hasFeature)
411       break;
412   }
413 }
414
415 /*bool setDefaultDeviationCoefficient(std::shared_ptr<GeomAPI_Shape> theGeomShape)
416 {
417   if (!theGeomShape.get())
418     return false;
419   // if the shape could not be exploded on faces, it contains only wires, edges, and vertices
420   // correction of deviation for them should not influence to the application performance
421   GeomAPI_ShapeExplorer anExp(theGeomShape, GeomAPI_Shape::FACE);
422   bool anEmpty = anExp.empty();
423   return !anExp.more();
424 }*/
425
426 /*void setDefaultDeviationCoefficient(const std::shared_ptr<ModelAPI_Result>& theResult,
427                                     const Handle(Prs3d_Drawer)& theDrawer)
428 {
429   if (!theResult.get())
430     return;
431   bool aUseDeviation = false;
432
433   std::string aResultGroup = theResult->groupName();
434   if (aResultGroup == ModelAPI_ResultConstruction::group())
435     aUseDeviation = true;
436   else if (aResultGroup == ModelAPI_ResultBody::group()) {
437     GeomShapePtr aGeomShape = theResult->shape();
438     if (aGeomShape.get())
439       aUseDeviation = setDefaultDeviationCoefficient(aGeomShape);
440   }
441   if (aUseDeviation)
442     theDrawer->SetDeviationCoefficient(DEFAULT_DEVIATION_COEFFICIENT);
443 }
444 */
445 void setDefaultDeviationCoefficient(const TopoDS_Shape& theShape,
446                                     const Handle(Prs3d_Drawer)& theDrawer)
447 {
448   if (theShape.IsNull())
449     return;
450
451   std::shared_ptr<GeomAPI_Shape> aGeomShape(new GeomAPI_Shape());
452   aGeomShape->setImpl(new TopoDS_Shape(theShape));
453
454   // if the shape could not be exploded on faces, it contains only wires, edges, and vertices
455   // correction of deviation for them should not influence to the application performance
456   GeomAPI_ShapeExplorer anExp(aGeomShape, GeomAPI_Shape::FACE);
457   bool isConstruction = !anExp.more();
458
459   double aDeflection;
460   if (isConstruction)
461     aDeflection = Config_PropManager::real("Visualization", "construction_deflection");
462   else
463     aDeflection = Config_PropManager::real("Visualization", "body_deflection");
464
465   theDrawer->SetDeviationCoefficient(aDeflection);
466 }
467
468 Quantity_Color color(const std::string& theSection,
469                      const std::string& theName)
470 {
471   std::vector<int> aColor = Config_PropManager::color(theSection, theName);
472   return Quantity_Color(aColor[0] / 255., aColor[1] / 255., aColor[2] / 255., Quantity_TOC_RGB);
473 }
474
475 ObjectPtr getObject(const AttributePtr& theAttribute)
476 {
477   ObjectPtr anObject;
478   std::string anAttrType = theAttribute->attributeType();
479   if (anAttrType == ModelAPI_AttributeRefAttr::typeId()) {
480     AttributeRefAttrPtr anAttr =
481       std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
482     if (anAttr != NULL && anAttr->isObject())
483       anObject = anAttr->object();
484   }
485   if (anAttrType == ModelAPI_AttributeSelection::typeId()) {
486     AttributeSelectionPtr anAttr =
487       std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
488     if (anAttr != NULL)
489       anObject = anAttr->context();
490   }
491   if (anAttrType == ModelAPI_AttributeReference::typeId()) {
492     AttributeReferencePtr anAttr =
493       std::dynamic_pointer_cast<ModelAPI_AttributeReference>(theAttribute);
494     if (anAttr.get() != NULL)
495       anObject = anAttr->value();
496   }
497   return anObject;
498 }
499
500 TopAbs_ShapeEnum getCompoundSubType(const TopoDS_Shape& theShape)
501 {
502   TopAbs_ShapeEnum aShapeType = theShape.ShapeType();
503
504   // for compounds check sub-shapes: it may be compound of needed type:
505   // Booleans may produce compounds of Solids
506   if (aShapeType == TopAbs_COMPOUND) {
507     for(TopoDS_Iterator aSubs(theShape); aSubs.More(); aSubs.Next()) {
508       if (!aSubs.Value().IsNull()) {
509         TopAbs_ShapeEnum aSubType = aSubs.Value().ShapeType();
510         if (aSubType == TopAbs_COMPOUND) { // compound of compound(s)
511           aShapeType = TopAbs_COMPOUND;
512           break;
513         }
514         if (aShapeType == TopAbs_COMPOUND) {
515           aShapeType = aSubType;
516         } else if (aShapeType != aSubType) { // compound of shapes of different types
517           aShapeType = TopAbs_COMPOUND;
518           break;
519         }
520       }
521     }
522   }
523   return aShapeType;
524 }
525
526 TopoDS_Shape getSelectedShape(const std::shared_ptr<ModuleBase_ViewerPrs>& thePrs)
527 {
528   if (thePrs->shape().get())
529     return thePrs->shape()->impl<TopoDS_Shape>();
530
531   Handle(StdSelect_BRepOwner) anOwner = Handle(StdSelect_BRepOwner)::DownCast(thePrs->owner());
532   if (!anOwner.IsNull())
533     return anOwner->Shape();
534
535   return TopoDS_Shape();
536 }
537
538 void getParameters(QStringList& theParameters)
539 {
540   theParameters.clear();
541
542   SessionPtr aSession = ModelAPI_Session::get();
543   std::list<DocumentPtr> aDocList;
544   DocumentPtr anActiveDocument = aSession->activeDocument();
545   DocumentPtr aRootDocument = aSession->moduleDocument();
546   aDocList.push_back(anActiveDocument);
547   if (anActiveDocument != aRootDocument) {
548     aDocList.push_back(aRootDocument);
549   }
550   std::string aGroupId = ModelAPI_ResultParameter::group();
551   for(std::list<DocumentPtr>::const_iterator it = aDocList.begin(); it != aDocList.end(); ++it) {
552     DocumentPtr aDocument = *it;
553     int aSize = aDocument->size(aGroupId);
554     for (int i = 0; i < aSize; i++) {
555       ObjectPtr anObject = aDocument->object(aGroupId, i);
556       std::string aParameterName = anObject->data()->name();
557       theParameters.append(aParameterName.c_str());
558     }
559   }
560 }
561
562 std::string findGreedAttribute(ModuleBase_IWorkshop* theWorkshop,
563                                const FeaturePtr& theFeature)
564 {
565   std::string anAttributeId;
566
567   std::string aXmlCfg, aDescription;
568   theWorkshop->module()->getXMLRepresentation(theFeature->getKind(), aXmlCfg, aDescription);
569
570   ModuleBase_WidgetFactory aFactory(aXmlCfg, theWorkshop);
571   std::string anAttributeTitle;
572   aFactory.getGreedAttribute(anAttributeId);
573
574   return anAttributeId;
575 }
576
577 bool hasObject(const AttributePtr& theAttribute, const ObjectPtr& theObject,
578                const std::shared_ptr<GeomAPI_Shape>& theShape,
579                ModuleBase_IWorkshop* theWorkshop,
580                const bool theTemporarily)
581 {
582   bool aHasObject = false;
583   if (!theAttribute.get())
584     return aHasObject;
585
586   std::string aType = theAttribute->attributeType();
587   if (aType == ModelAPI_AttributeReference::typeId()) {
588     AttributeReferencePtr aRef =
589       std::dynamic_pointer_cast<ModelAPI_AttributeReference>(theAttribute);
590     ObjectPtr aObject = aRef->value();
591     aHasObject = aObject && aObject->isSame(theObject);
592     //if (!(aObject && aObject->isSame(theObject))) {
593     //  aRef->setValue(theObject);
594     //}
595   } else if (aType == ModelAPI_AttributeRefAttr::typeId()) {
596     AttributeRefAttrPtr aRefAttr =
597       std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
598
599     AttributePtr anAttribute = theWorkshop->module()->findAttribute(theObject, theShape);
600     if (anAttribute.get()) {
601       //aRefAttr->setAttr(anAttribute);
602     }
603     else {
604       ObjectPtr aObject = aRefAttr->object();
605       aHasObject = aObject && aObject->isSame(theObject);
606       //if (!(aObject && aObject->isSame(theObject))) {
607       //  aRefAttr->setObject(theObject);
608       //}
609     }
610   } else if (aType == ModelAPI_AttributeSelection::typeId()) {
611     /*AttributeSelectionPtr aSelectAttr =
612                              std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
613     ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(theObject);
614     if (aSelectAttr.get() != NULL) {
615       aSelectAttr->setValue(aResult, theShape, theTemporarily);
616     }*/
617   }
618   if (aType == ModelAPI_AttributeSelectionList::typeId()) {
619     AttributeSelectionListPtr aSelectionListAttr =
620                          std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
621     ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(theObject);
622     aHasObject = aSelectionListAttr->isInList(aResult, theShape, theTemporarily);
623   }
624   else if (aType == ModelAPI_AttributeRefList::typeId()) {
625     AttributeRefListPtr aRefListAttr =
626       std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(theAttribute);
627     aHasObject = aRefListAttr->isInList(theObject);
628     //if (!theCheckIfAttributeHasObject || !aRefListAttr->isInList(theObject))
629     //  aRefListAttr->append(theObject);
630   }
631   else if (aType == ModelAPI_AttributeRefAttrList::typeId()) {
632     AttributeRefAttrListPtr aRefAttrListAttr =
633       std::dynamic_pointer_cast<ModelAPI_AttributeRefAttrList>(theAttribute);
634     AttributePtr anAttribute = theWorkshop->module()->findAttribute(theObject, theShape);
635
636     if (anAttribute.get()) {
637       aHasObject = aRefAttrListAttr->isInList(anAttribute);
638       //if (!theCheckIfAttributeHasObject || !aRefAttrListAttr->isInList(anAttribute))
639       //  aRefAttrListAttr->append(anAttribute);
640     }
641     else {
642       aHasObject = aRefAttrListAttr->isInList(theObject);
643       //if (!theCheckIfAttributeHasObject || !aRefAttrListAttr->isInList(theObject))
644       //  aRefAttrListAttr->append(theObject);
645     }
646   }
647   return aHasObject;
648 }
649
650 bool setObject(const AttributePtr& theAttribute, const ObjectPtr& theObject,
651                const GeomShapePtr& theShape, ModuleBase_IWorkshop* theWorkshop,
652                const bool theTemporarily, const bool theCheckIfAttributeHasObject)
653 {
654   if (!theAttribute.get())
655     return false;
656
657   bool isDone = true;
658   std::string aType = theAttribute->attributeType();
659   if (aType == ModelAPI_AttributeReference::typeId()) {
660     AttributeReferencePtr aRef =
661       std::dynamic_pointer_cast<ModelAPI_AttributeReference>(theAttribute);
662     ObjectPtr aObject = aRef->value();
663     if (!(aObject && aObject->isSame(theObject))) {
664       aRef->setValue(theObject);
665     }
666   } else if (aType == ModelAPI_AttributeRefAttr::typeId()) {
667     AttributeRefAttrPtr aRefAttr =
668       std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
669
670     AttributePtr anAttribute = theWorkshop->module()->findAttribute(theObject, theShape);
671     if (anAttribute.get())
672       aRefAttr->setAttr(anAttribute);
673     else {
674       ObjectPtr aObject = aRefAttr->object();
675       if (!(aObject && aObject->isSame(theObject))) {
676         aRefAttr->setObject(theObject);
677       }
678     }
679   } else if (aType == ModelAPI_AttributeSelection::typeId()) {
680     AttributeSelectionPtr aSelectAttr =
681                              std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
682     ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(theObject);
683     if (aSelectAttr.get() != NULL) {
684       aSelectAttr->setValue(aResult, theShape, theTemporarily);
685     }
686   }
687   if (aType == ModelAPI_AttributeSelectionList::typeId()) {
688     AttributeSelectionListPtr aSelectionListAttr =
689                          std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
690     ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(theObject);
691     if (!theCheckIfAttributeHasObject ||
692         !aSelectionListAttr->isInList(aResult, theShape, theTemporarily))
693       aSelectionListAttr->append(aResult, theShape, theTemporarily);
694   }
695   else if (aType == ModelAPI_AttributeRefList::typeId()) {
696     AttributeRefListPtr aRefListAttr =
697       std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(theAttribute);
698     if (!theCheckIfAttributeHasObject || !aRefListAttr->isInList(theObject)) {
699       if (theObject.get())
700         aRefListAttr->append(theObject);
701       else
702         isDone = false;
703     }
704   }
705   else if (aType == ModelAPI_AttributeRefAttrList::typeId()) {
706     AttributeRefAttrListPtr aRefAttrListAttr =
707       std::dynamic_pointer_cast<ModelAPI_AttributeRefAttrList>(theAttribute);
708     AttributePtr anAttribute = theWorkshop->module()->findAttribute(theObject, theShape);
709
710     if (anAttribute.get()) {
711       if (!theCheckIfAttributeHasObject || !aRefAttrListAttr->isInList(anAttribute))
712         aRefAttrListAttr->append(anAttribute);
713     }
714     else {
715       if (!theCheckIfAttributeHasObject || !aRefAttrListAttr->isInList(theObject)) {
716         if (theObject.get())
717           aRefAttrListAttr->append(theObject);
718         else
719           isDone = false;
720       }
721     }
722   }
723   return isDone;
724 }
725
726 GeomShapePtr getShape(const AttributePtr& theAttribute, ModuleBase_IWorkshop* theWorkshop)
727 {
728   GeomShapePtr aShape;
729   if (!theAttribute.get())
730     return aShape;
731
732   std::string aType = theAttribute->attributeType();
733   if (aType == ModelAPI_AttributeReference::typeId()) {
734   } else if (aType == ModelAPI_AttributeRefAttr::typeId()) {
735     AttributeRefAttrPtr aRefAttr =
736       std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
737     if (aRefAttr.get() && !aRefAttr->isObject()) {
738       AttributePtr anAttribute = aRefAttr->attr();
739       aShape = theWorkshop->module()->findShape(anAttribute);
740     }
741   } else if (aType == ModelAPI_AttributeSelection::typeId()) {
742     AttributeSelectionPtr aSelectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelection>
743                                                                                  (theAttribute);
744     aShape = aSelectAttr->value();
745   }
746   else // Geom2D point processing
747     aShape = theWorkshop->module()->findShape(theAttribute);
748   return aShape;
749 }
750
751 void flushUpdated(ObjectPtr theObject)
752 {
753   blockUpdateViewer(true);
754
755   // Fix the problem of not previewed results of constraints applied. Flush Create/Delete
756   // (for the sketch result) to start processing of the sketch in the solver.
757   // TODO: these flushes should be moved in a separate method provided by Model
758   Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_CREATED));
759   Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
760   Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_DELETED));
761
762   blockUpdateViewer(false);
763 }
764
765 void blockUpdateViewer(const bool theValue)
766 {
767   // the viewer update should be blocked in order to avoid the temporary feature content
768   // when the solver processes the feature, the redisplay message can be flushed
769   // what caused the display in the viewer preliminary states of object
770   // e.g. fillet feature, angle value change
771   std::shared_ptr<Events_Message> aMsg;
772   if (theValue) {
773     aMsg = std::shared_ptr<Events_Message>(
774         new Events_Message(Events_Loop::eventByName(EVENT_UPDATE_VIEWER_BLOCKED)));
775   }
776   else {
777     // the viewer update should be unblocked
778     aMsg = std::shared_ptr<Events_Message>(
779         new Events_Message(Events_Loop::eventByName(EVENT_UPDATE_VIEWER_UNBLOCKED)));
780   }
781   Events_Loop::loop()->send(aMsg);
782 }
783
784 QString wrapTextByWords(const QString& theValue, QWidget* theWidget,
785                                           int theMaxLineInPixels)
786 {
787   static QFontMetrics tfm(theWidget ? theWidget->font() : QApplication::font());
788   static qreal phi = 2.618;
789
790   QRect aBounds = tfm.boundingRect(theValue);
791   if(aBounds.width() <= theMaxLineInPixels)
792     return theValue;
793
794   qreal s = aBounds.width() * aBounds.height();
795   qreal aGoldWidth = sqrt(s*phi);
796
797   QStringList aWords = theValue.split(" ", QString::SkipEmptyParts);
798   QStringList aLines;
799   int n = aWords.count();
800   QString aLine;
801   for (int i = 0; i < n; i++) {
802     QString aLineExt = aLine + " " + aWords[i];
803     qreal anWidthNonExt = tfm.boundingRect(aLine).width();
804     qreal anWidthExt = tfm.boundingRect(aLineExt).width();
805     qreal aDeltaNonExt = fabs(anWidthNonExt-aGoldWidth);
806     qreal aDeltaExt    = fabs(anWidthExt-aGoldWidth);
807     if(aDeltaNonExt < aDeltaExt) {
808       // new line
809       aLines.append(aLine);
810       aLine = aWords[i];
811     }
812     else
813       aLine = aLineExt;
814   }
815
816   if(!aLine.isEmpty())
817     aLines.append(aLine);
818
819   QString aResult = aLines.join("\n");
820   return aResult;
821 }
822
823 //**************************************************************
824 QLocale doubleLocale()
825 {
826   // VSR 01/07/2010: Disable thousands separator for spin box
827   // (to avoid inconsistency of double-2-string and string-2-double conversion)
828   QLocale aLocale;
829   aLocale.setNumberOptions(aLocale.numberOptions() |
830                            QLocale::OmitGroupSeparator |
831                            QLocale::RejectGroupSeparator);
832   return aLocale;
833 }
834
835 //**************************************************************
836 void refsToFeatureInFeatureDocument(const ObjectPtr& theObject,
837                                     std::set<FeaturePtr>& theRefFeatures)
838 {
839   FeaturePtr aFeature = ModelAPI_Feature::feature(theObject);
840   if (aFeature.get()) {
841     DocumentPtr aFeatureDoc = aFeature->document();
842     // 1. find references in the current document
843     aFeatureDoc->refsToFeature(aFeature, theRefFeatures, false);
844   }
845 }
846
847
848 //**************************************************************
849 /*bool isSubOfComposite(const ObjectPtr& theObject)
850 {
851   bool isSub = false;
852   std::set<FeaturePtr> aRefFeatures;
853   refsToFeatureInFeatureDocument(theObject, aRefFeatures);
854   std::set<FeaturePtr>::const_iterator anIt = aRefFeatures.begin(),
855                                        aLast = aRefFeatures.end();
856   for (; anIt != aLast && !isSub; anIt++) {
857     isSub = isSubOfComposite(theObject, *anIt);
858   }
859   return isSub;
860 }*/
861
862 //**************************************************************
863 /*bool isSubOfComposite(const ObjectPtr& theObject, const FeaturePtr& theFeature)
864 {
865   bool isSub = false;
866   CompositeFeaturePtr aComposite = std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(theFeature);
867   if (aComposite.get()) {
868     isSub = aComposite->isSub(theObject);
869     // the recursive is possible, the parameters are sketch circle and extrusion cut. They are
870     // separated by composite sketch feature
871     if (!isSub) {
872       int aNbSubs = aComposite->numberOfSubs();
873       for (int aSub = 0; aSub < aNbSubs && !isSub; aSub++) {
874         isSub = isSubOfComposite(theObject, aComposite->subFeature(aSub));
875       }
876     }
877   }
878   return isSub;
879 }*/
880
881 //**************************************************************
882 ResultPtr firstResult(const ObjectPtr& theObject)
883 {
884   ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(theObject);
885   if (!aResult.get()) {
886     FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theObject);
887     if (aFeature.get())
888       aResult = aFeature->firstResult();
889   }
890   return aResult;
891 }
892
893 //**************************************************************
894 bool isFeatureOfResult(const FeaturePtr& theFeature, const std::string& theGroupOfResult)
895 {
896   bool isResult = false;
897
898   if (!theFeature->data()->isValid())
899     return isResult;
900
901   ResultPtr aFirstResult = theFeature->firstResult();
902   if (!aFirstResult.get())
903     return isResult;
904
905   return aFirstResult->groupName() == theGroupOfResult;
906 }
907
908 //**************************************************************
909 bool hasModuleDocumentFeature(const std::set<FeaturePtr>& theFeatures)
910 {
911   bool aFoundModuleDocumentObject = false;
912   DocumentPtr aModuleDoc = ModelAPI_Session::get()->moduleDocument();
913
914   std::set<FeaturePtr>::const_iterator anIt = theFeatures.begin(), aLast = theFeatures.end();
915   for (; anIt != aLast && !aFoundModuleDocumentObject; anIt++) {
916     FeaturePtr aFeature = *anIt;
917     ResultPtr aResult = ModuleBase_Tools::firstResult(aFeature);
918     if (aResult.get() && aResult->groupName() == ModelAPI_ResultPart::group())
919       continue;
920     aFoundModuleDocumentObject = aFeature->document() == aModuleDoc;
921   }
922
923   return aFoundModuleDocumentObject;
924 }
925
926 //**************************************************************
927 bool askToDelete(const std::set<FeaturePtr> theFeatures,
928                  const std::map<FeaturePtr, std::set<FeaturePtr> >& theReferences,
929                  QWidget* theParent,
930                  std::set<FeaturePtr>& theReferencesToDelete,
931                  const std::string& thePrefixInfo)
932 {
933   QString aNotActivatedDocWrn;
934   std::string aNotActivatedNames;
935   if (!ModelAPI_Tools::allDocumentsActivated(aNotActivatedNames)) {
936     if (ModuleBase_Tools::hasModuleDocumentFeature(theFeatures))
937       aNotActivatedDocWrn =
938         QObject::tr("Selected objects can be used in Part documents which are not loaded:%1.\n")
939                             .arg(aNotActivatedNames.c_str());
940   }
941
942   std::set<FeaturePtr> aFeaturesRefsTo;
943   std::set<FeaturePtr> aFeaturesRefsToParameter;
944   std::set<FeaturePtr> aParameterFeatures;
945   QStringList aPartFeatureNames;
946   std::set<FeaturePtr>::const_iterator anIt = theFeatures.begin(),
947                                        aLast = theFeatures.end();
948   // separate features to references to parameter features and references to others
949   for (; anIt != aLast; anIt++) {
950     FeaturePtr aFeature = *anIt;
951     if (theReferences.find(aFeature) == theReferences.end())
952       continue;
953
954     if (isFeatureOfResult(aFeature, ModelAPI_ResultPart::group()))
955       aPartFeatureNames.append(aFeature->name().c_str());
956
957     std::set<FeaturePtr> aRefFeatures;
958     std::set<FeaturePtr> aRefList = theReferences.at(aFeature);
959     std::set<FeaturePtr>::const_iterator aRefIt = aRefList.begin(), aRefLast = aRefList.end();
960     for (; aRefIt != aRefLast; aRefIt++) {
961       FeaturePtr aRefFeature = *aRefIt;
962       if (theFeatures.find(aRefFeature) == theFeatures.end() && // it is not selected
963           aRefFeatures.find(aRefFeature) == aRefFeatures.end()) // it is not added
964         aRefFeatures.insert(aRefFeature);
965     }
966
967     if (isFeatureOfResult(aFeature, ModelAPI_ResultParameter::group())) {
968       aFeaturesRefsToParameter.insert(aRefFeatures.begin(), aRefFeatures.end());
969       aParameterFeatures.insert(aFeature);
970     }
971     else {
972       theReferencesToDelete.insert(aRefFeatures.begin(), aRefFeatures.end());
973     }
974   }
975
976   std::set<FeaturePtr> aFeaturesRefsToParameterOnly;
977   anIt = aFeaturesRefsToParameter.begin();
978   aLast = aFeaturesRefsToParameter.end();
979   // separate features to references to parameter features and references to others
980   QStringList aParamFeatureNames;
981   for (; anIt != aLast; anIt++) {
982     FeaturePtr aFeature = *anIt;
983     if (theReferencesToDelete.find(aFeature) == theReferencesToDelete.end()) {
984       aFeaturesRefsToParameterOnly.insert(aFeature);
985       aParamFeatureNames.append(aFeature->name().c_str());
986     }
987   }
988   aParamFeatureNames.sort();
989   QStringList anOtherFeatureNames;
990   anIt = theReferencesToDelete.begin();
991   aLast = theReferencesToDelete.end();
992   for (; anIt != aLast; anIt++) {
993     FeaturePtr aFeature = *anIt;
994     if (isFeatureOfResult(aFeature, ModelAPI_ResultPart::group()))
995       aPartFeatureNames.append(aFeature->name().c_str());
996     else
997       anOtherFeatureNames.append(aFeature->name().c_str());
998   }
999   aPartFeatureNames.sort();
1000   anOtherFeatureNames.sort();
1001
1002   bool aCanReplaceParameters = !aFeaturesRefsToParameterOnly.empty();
1003
1004   QMessageBox aMessageBox(theParent);
1005   aMessageBox.setWindowTitle(QObject::tr("Delete features"));
1006   aMessageBox.setIcon(QMessageBox::Warning);
1007   aMessageBox.setStandardButtons(QMessageBox::No | QMessageBox::Yes);
1008   aMessageBox.setDefaultButton(QMessageBox::No);
1009
1010   QString aText;
1011   if (!thePrefixInfo.empty())
1012     aText = thePrefixInfo.c_str();
1013   QString aSep = ", ";
1014   if (!aPartFeatureNames.empty()) {
1015     aText += QString(QObject::tr("The following parts will be deleted: %1.\n"))
1016              .arg(aPartFeatureNames.join(aSep));
1017   }
1018   if (!aNotActivatedDocWrn.isEmpty())
1019     aText += aNotActivatedDocWrn;
1020   if (!anOtherFeatureNames.empty()) {
1021     const char* aMsg = "Features are used in the following features: %1.\nThese "
1022                        "features will be deleted.\n";
1023     aText += QString(QObject::tr(aMsg))
1024                      .arg(anOtherFeatureNames.join(aSep));
1025   }
1026   if (!aParamFeatureNames.empty()) {
1027     const char* aMsg = "Parameters are used directly and through a sequence "
1028                        "of dependencies in the following features: %1.\nThese features will "
1029                        "be deleted.\nOr parameters could be replaced by their values.\n";
1030     aText += QString(QObject::tr(aMsg))
1031                      .arg(aParamFeatureNames.join(aSep));
1032     QPushButton *aReplaceButton =
1033       aMessageBox.addButton(QObject::tr("Replace"), QMessageBox::ActionRole);
1034   }
1035
1036   if (!aText.isEmpty()) {
1037     aText += "Would you like to continue?";
1038     aMessageBox.setText(aText);
1039     aMessageBox.exec();
1040     QMessageBox::ButtonRole aButtonRole = aMessageBox.buttonRole(aMessageBox.clickedButton());
1041
1042     if (aButtonRole == QMessageBox::NoRole)
1043       return false;
1044
1045     if (aButtonRole == QMessageBox::ActionRole) {
1046       foreach (FeaturePtr aObj, aParameterFeatures)
1047         ModelAPI_ReplaceParameterMessage::send(aObj, 0);
1048     }
1049     else
1050       theReferencesToDelete.insert(aFeaturesRefsToParameterOnly.begin(),
1051                                    aFeaturesRefsToParameterOnly.end());
1052   }
1053   return true;
1054 }
1055
1056 //**************************************************************
1057 void convertToFeatures(const QObjectPtrList& theObjects, std::set<FeaturePtr>& theFeatures)
1058 {
1059   QObjectPtrList::const_iterator anIt = theObjects.begin(), aLast = theObjects.end();
1060   for(; anIt != aLast; anIt++) {
1061     ObjectPtr anObject = *anIt;
1062     FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(anObject);
1063     // for parameter result, use the corresponded reature to be removed
1064     if (!aFeature.get() && anObject->groupName() == ModelAPI_ResultParameter::group()) {
1065       aFeature = ModelAPI_Feature::feature(anObject);
1066     }
1067     if (aFeature.get())
1068       theFeatures.insert(aFeature);
1069   }
1070 }
1071
1072 //**************************************************************
1073 void convertToFolders(const QObjectPtrList& theObjects,
1074                                          std::set<FolderPtr>& theFolders)
1075 {
1076   QObjectPtrList::const_iterator anIt = theObjects.begin(), aLast = theObjects.end();
1077   for(; anIt != aLast; anIt++) {
1078     ObjectPtr anObject = *anIt;
1079     FolderPtr aFeature = std::dynamic_pointer_cast<ModelAPI_Folder>(anObject);
1080     if (aFeature.get())
1081       theFolders.insert(aFeature);
1082   }
1083 }
1084
1085
1086 //**************************************************************
1087 QString translate(const Events_InfoMessage& theMessage)
1088 {
1089   QString aMessage;
1090
1091   if (!theMessage.empty()) {
1092     std::string aStr = Config_Translator::translate(theMessage);
1093     if (!aStr.empty()) {
1094       std::string aCodec = Config_Translator::codec(theMessage);
1095       aMessage = QTextCodec::codecForName(aCodec.c_str())->toUnicode(aStr.c_str());
1096     }
1097   }
1098
1099   return aMessage;
1100 }
1101
1102 QString translate(const std::string& theContext, const std::string& theMessage)
1103 {
1104   QString aMessage;
1105
1106   if (!theMessage.empty()) {
1107     std::string aStr = Config_Translator::translate(theContext, theMessage);
1108     if (!aStr.empty()) {
1109       std::string aCodec = Config_Translator::codec(theContext);
1110       aMessage = QTextCodec::codecForName(aCodec.c_str())->toUnicode(aStr.c_str());
1111     }
1112   }
1113
1114   return aMessage;
1115 }
1116
1117 void setPointBallHighlighting(AIS_Shape* theAIS)
1118 {
1119   static Handle(Image_AlienPixMap) aPixMap;
1120   if(aPixMap.IsNull()) {
1121     // Load icon for the presentation
1122     std::string aFile;
1123     char* anEnv = getenv("SHAPER_ROOT_DIR");
1124     if(anEnv) {
1125       aFile = std::string(anEnv) +
1126         FSEP + "share" + FSEP + "salome" + FSEP + "resources" + FSEP + "shaper";
1127     } else {
1128       anEnv = getenv("OPENPARTS_ROOT_DIR");
1129       if (anEnv)
1130         aFile = std::string(anEnv) + FSEP + "resources";
1131     }
1132
1133     aFile += FSEP;
1134     static const std::string aMarkerName = "marker_dot.png";
1135     aFile += aMarkerName;
1136     aPixMap = new Image_AlienPixMap();
1137     if(!aPixMap->Load(aFile.c_str())) {
1138       // The icon for constraint is not found
1139       static const std::string aMsg =
1140         "Error: Point market not found by path: \"" + aFile + "\". Falling back.";
1141       //Events_InfoMessage("ModuleBase_Tools::setPointBallHighlighting", aMsg).send();
1142     }
1143   }
1144
1145   Handle(Graphic3d_AspectMarker3d) anAspect;
1146   Handle(Prs3d_Drawer) aDrawer = theAIS->DynamicHilightAttributes();
1147   if (aDrawer.IsNull()) {
1148     if (ModuleBase_IViewer::DefaultHighlightDrawer.IsNull())
1149       return;
1150     aDrawer = new Prs3d_Drawer(*ModuleBase_IViewer::DefaultHighlightDrawer);
1151     if (!aDrawer->HasOwnPointAspect()) {
1152       aDrawer->SetPointAspect(new Prs3d_PointAspect(Aspect_TOM_BALL, Quantity_NOC_BLACK, 2.0));
1153     }
1154   }
1155   if(aDrawer->HasOwnPointAspect()) {
1156     Handle(Prs3d_PointAspect) aPntAspect = aDrawer->PointAspect();
1157     if(aPixMap->IsEmpty()) {
1158       anAspect = aPntAspect->Aspect();
1159       anAspect->SetType(Aspect_TOM_BALL);
1160     } else {
1161       if(aPixMap->Format() == Image_PixMap::ImgGray) {
1162         aPixMap->SetFormat (Image_PixMap::ImgAlpha);
1163       } else if(aPixMap->Format() == Image_PixMap::ImgGrayF) {
1164         aPixMap->SetFormat (Image_PixMap::ImgAlphaF);
1165       }
1166       anAspect = new Graphic3d_AspectMarker3d(aPixMap);
1167       aPntAspect->SetAspect(anAspect);
1168     }
1169     aDrawer->SetPointAspect(aPntAspect);
1170           theAIS->SetDynamicHilightAttributes(aDrawer);
1171   }
1172 }
1173
1174 FeaturePtr createParameter(const QString& theText)
1175 {
1176   FeaturePtr aParameter;
1177   QStringList aList = theText.split("=");
1178   if (aList.count() != 2) {
1179     return aParameter;
1180   }
1181   QString aParamName = aList.at(0).trimmed();
1182
1183   if (isNameExist(aParamName, FeaturePtr())) {
1184     return aParameter;
1185   }
1186
1187   if (!ModelAPI_Expression::isVariable(aParamName.toStdString())) {
1188     return aParameter;
1189   }
1190
1191   QString aExpression = aList.at(1).trimmed();
1192   if (aExpression.isEmpty()) {
1193     return aParameter;
1194   }
1195
1196   SessionPtr aMgr = ModelAPI_Session::get();
1197   std::shared_ptr<ModelAPI_Document> aDoc = aMgr->activeDocument();
1198
1199   aParameter = aDoc->addFeature("Parameter");
1200   if (aParameter.get()) {
1201     AttributeStringPtr aNameAttr = aParameter->string("variable");
1202     aNameAttr->setValue(aParamName.toStdString());
1203
1204     AttributeStringPtr aExprAttr = aParameter->string("expression");
1205     aExprAttr->setValue(aExpression.toStdString());
1206     aParameter->execute();
1207
1208     Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_CREATED));
1209     Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
1210   }
1211   return aParameter;
1212 }
1213
1214 void editParameter(FeaturePtr theParam, const QString& theText)
1215 {
1216   QStringList aList = theText.split("=");
1217   QString aParamName = aList.at(0).trimmed();
1218
1219   QString aExpression = aList.at(1).trimmed();
1220   if (aExpression.isEmpty()) {
1221     return;
1222   }
1223
1224   if (isNameExist(aParamName, theParam)) {
1225     return;
1226   }
1227   AttributeStringPtr aNameAttr = theParam->string("variable");
1228   aNameAttr->setValue(aParamName.toStdString());
1229
1230   AttributeStringPtr aExprAttr = theParam->string("expression");
1231   aExprAttr->setValue(aExpression.toStdString());
1232   theParam->execute();
1233
1234   Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
1235 }
1236
1237 bool isNameExist(const QString& theName, FeaturePtr theIgnoreParameter)
1238 {
1239   SessionPtr aMgr = ModelAPI_Session::get();
1240   std::shared_ptr<ModelAPI_Document> aDoc = aMgr->activeDocument();
1241   FeaturePtr aParamFeature;
1242   int aNbFeatures = aDoc->numInternalFeatures();
1243   std::string aName = theName.toStdString();
1244   for (int i = 0; i < aNbFeatures; i++) {
1245     aParamFeature = aDoc->internalFeature(i);
1246     if (aParamFeature && aParamFeature->getKind() == "Parameter") {
1247       if ((theIgnoreParameter != aParamFeature) && (aParamFeature->name() == aName))
1248         return true;
1249     }
1250   }
1251   return false;
1252 }
1253
1254 FeaturePtr findParameter(const QString& theName)
1255 {
1256   SessionPtr aMgr = ModelAPI_Session::get();
1257   std::shared_ptr<ModelAPI_Document> aDoc = aMgr->activeDocument();
1258   FeaturePtr aParamFeature;
1259   int aNbFeatures = aDoc->numInternalFeatures();
1260   std::string aName = theName.toStdString();
1261   for (int i = 0; i < aNbFeatures; i++) {
1262     aParamFeature = aDoc->internalFeature(i);
1263     if (aParamFeature && aParamFeature->getKind() == "Parameter") {
1264       if (aParamFeature->name() == aName)
1265         return aParamFeature;
1266     }
1267   }
1268   return FeaturePtr();
1269 }
1270
1271
1272 //********************************************************************
1273 std::string generateName(const AttributePtr& theAttribute,
1274   ModuleBase_IWorkshop* theWorkshop)
1275 {
1276   std::string aName;
1277   if (theAttribute.get() != NULL) {
1278     ModuleBase_Operation* anOperation = theWorkshop->currentOperation();
1279
1280     FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner());
1281     if (aFeature.get()) {
1282       std::string aXmlCfg, aDescription;
1283       theWorkshop->module()->getXMLRepresentation(aFeature->getKind(), aXmlCfg, aDescription);
1284
1285       ModuleBase_WidgetFactory aFactory(aXmlCfg, theWorkshop);
1286       std::string anAttributeTitle;
1287       aFactory.getAttributeTitle(theAttribute->id(), anAttributeTitle);
1288
1289       std::stringstream aStreamName;
1290       aStreamName << theAttribute->owner()->data()->name() << "/" << anAttributeTitle.c_str();
1291       aName = aStreamName.str();
1292     }
1293   }
1294   return aName;
1295 }
1296
1297 } // namespace ModuleBase_Tools
1298
1299