Salome HOME
67d2b349a63673374dd92e45312bb794ffac7951
[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     if (aSelectAttr.get() != NULL) {
683       aSelectAttr->setValue(theObject, theShape, theTemporarily);
684     }
685   }
686   if (aType == ModelAPI_AttributeSelectionList::typeId()) {
687     AttributeSelectionListPtr aSelectionListAttr =
688                          std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
689     if (!theCheckIfAttributeHasObject ||
690       !aSelectionListAttr->isInList(theObject, theShape, theTemporarily))
691       aSelectionListAttr->append(theObject, theShape, theTemporarily);
692   }
693   else if (aType == ModelAPI_AttributeRefList::typeId()) {
694     AttributeRefListPtr aRefListAttr =
695       std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(theAttribute);
696     if (!theCheckIfAttributeHasObject || !aRefListAttr->isInList(theObject)) {
697       if (theObject.get())
698         aRefListAttr->append(theObject);
699       else
700         isDone = false;
701     }
702   }
703   else if (aType == ModelAPI_AttributeRefAttrList::typeId()) {
704     AttributeRefAttrListPtr aRefAttrListAttr =
705       std::dynamic_pointer_cast<ModelAPI_AttributeRefAttrList>(theAttribute);
706     AttributePtr anAttribute = theWorkshop->module()->findAttribute(theObject, theShape);
707
708     if (anAttribute.get()) {
709       if (!theCheckIfAttributeHasObject || !aRefAttrListAttr->isInList(anAttribute))
710         aRefAttrListAttr->append(anAttribute);
711     }
712     else {
713       if (!theCheckIfAttributeHasObject || !aRefAttrListAttr->isInList(theObject)) {
714         if (theObject.get())
715           aRefAttrListAttr->append(theObject);
716         else
717           isDone = false;
718       }
719     }
720   }
721   return isDone;
722 }
723
724 GeomShapePtr getShape(const AttributePtr& theAttribute, ModuleBase_IWorkshop* theWorkshop)
725 {
726   GeomShapePtr aShape;
727   if (!theAttribute.get())
728     return aShape;
729
730   std::string aType = theAttribute->attributeType();
731   if (aType == ModelAPI_AttributeReference::typeId()) {
732   } else if (aType == ModelAPI_AttributeRefAttr::typeId()) {
733     AttributeRefAttrPtr aRefAttr =
734       std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
735     if (aRefAttr.get() && !aRefAttr->isObject()) {
736       AttributePtr anAttribute = aRefAttr->attr();
737       aShape = theWorkshop->module()->findShape(anAttribute);
738     }
739   } else if (aType == ModelAPI_AttributeSelection::typeId()) {
740     AttributeSelectionPtr aSelectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelection>
741                                                                                  (theAttribute);
742     aShape = aSelectAttr->value();
743   }
744   else // Geom2D point processing
745     aShape = theWorkshop->module()->findShape(theAttribute);
746   return aShape;
747 }
748
749 void flushUpdated(ObjectPtr theObject)
750 {
751   blockUpdateViewer(true);
752
753   // Fix the problem of not previewed results of constraints applied. Flush Create/Delete
754   // (for the sketch result) to start processing of the sketch in the solver.
755   // TODO: these flushes should be moved in a separate method provided by Model
756   Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_CREATED));
757   Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
758   Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_DELETED));
759
760   blockUpdateViewer(false);
761 }
762
763 void blockUpdateViewer(const bool theValue)
764 {
765   // the viewer update should be blocked in order to avoid the temporary feature content
766   // when the solver processes the feature, the redisplay message can be flushed
767   // what caused the display in the viewer preliminary states of object
768   // e.g. fillet feature, angle value change
769   std::shared_ptr<Events_Message> aMsg;
770   if (theValue) {
771     aMsg = std::shared_ptr<Events_Message>(
772         new Events_Message(Events_Loop::eventByName(EVENT_UPDATE_VIEWER_BLOCKED)));
773   }
774   else {
775     // the viewer update should be unblocked
776     aMsg = std::shared_ptr<Events_Message>(
777         new Events_Message(Events_Loop::eventByName(EVENT_UPDATE_VIEWER_UNBLOCKED)));
778   }
779   Events_Loop::loop()->send(aMsg);
780 }
781
782 QString wrapTextByWords(const QString& theValue, QWidget* theWidget,
783                                           int theMaxLineInPixels)
784 {
785   static QFontMetrics tfm(theWidget ? theWidget->font() : QApplication::font());
786   static qreal phi = 2.618;
787
788   QRect aBounds = tfm.boundingRect(theValue);
789   if(aBounds.width() <= theMaxLineInPixels)
790     return theValue;
791
792   qreal s = aBounds.width() * aBounds.height();
793   qreal aGoldWidth = sqrt(s*phi);
794
795   QStringList aWords = theValue.split(" ", QString::SkipEmptyParts);
796   QStringList aLines;
797   int n = aWords.count();
798   QString aLine;
799   for (int i = 0; i < n; i++) {
800     QString aLineExt = aLine + " " + aWords[i];
801     qreal anWidthNonExt = tfm.boundingRect(aLine).width();
802     qreal anWidthExt = tfm.boundingRect(aLineExt).width();
803     qreal aDeltaNonExt = fabs(anWidthNonExt-aGoldWidth);
804     qreal aDeltaExt    = fabs(anWidthExt-aGoldWidth);
805     if(aDeltaNonExt < aDeltaExt) {
806       // new line
807       aLines.append(aLine);
808       aLine = aWords[i];
809     }
810     else
811       aLine = aLineExt;
812   }
813
814   if(!aLine.isEmpty())
815     aLines.append(aLine);
816
817   QString aResult = aLines.join("\n");
818   return aResult;
819 }
820
821 //**************************************************************
822 QLocale doubleLocale()
823 {
824   // VSR 01/07/2010: Disable thousands separator for spin box
825   // (to avoid inconsistency of double-2-string and string-2-double conversion)
826   QLocale aLocale;
827   aLocale.setNumberOptions(aLocale.numberOptions() |
828                            QLocale::OmitGroupSeparator |
829                            QLocale::RejectGroupSeparator);
830   return aLocale;
831 }
832
833 //**************************************************************
834 void refsToFeatureInFeatureDocument(const ObjectPtr& theObject,
835                                     std::set<FeaturePtr>& theRefFeatures)
836 {
837   FeaturePtr aFeature = ModelAPI_Feature::feature(theObject);
838   if (aFeature.get()) {
839     DocumentPtr aFeatureDoc = aFeature->document();
840     // 1. find references in the current document
841     aFeatureDoc->refsToFeature(aFeature, theRefFeatures, false);
842   }
843 }
844
845
846 //**************************************************************
847 /*bool isSubOfComposite(const ObjectPtr& theObject)
848 {
849   bool isSub = false;
850   std::set<FeaturePtr> aRefFeatures;
851   refsToFeatureInFeatureDocument(theObject, aRefFeatures);
852   std::set<FeaturePtr>::const_iterator anIt = aRefFeatures.begin(),
853                                        aLast = aRefFeatures.end();
854   for (; anIt != aLast && !isSub; anIt++) {
855     isSub = isSubOfComposite(theObject, *anIt);
856   }
857   return isSub;
858 }*/
859
860 //**************************************************************
861 /*bool isSubOfComposite(const ObjectPtr& theObject, const FeaturePtr& theFeature)
862 {
863   bool isSub = false;
864   CompositeFeaturePtr aComposite = std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(theFeature);
865   if (aComposite.get()) {
866     isSub = aComposite->isSub(theObject);
867     // the recursive is possible, the parameters are sketch circle and extrusion cut. They are
868     // separated by composite sketch feature
869     if (!isSub) {
870       int aNbSubs = aComposite->numberOfSubs();
871       for (int aSub = 0; aSub < aNbSubs && !isSub; aSub++) {
872         isSub = isSubOfComposite(theObject, aComposite->subFeature(aSub));
873       }
874     }
875   }
876   return isSub;
877 }*/
878
879 //**************************************************************
880 ResultPtr firstResult(const ObjectPtr& theObject)
881 {
882   ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(theObject);
883   if (!aResult.get()) {
884     FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theObject);
885     if (aFeature.get())
886       aResult = aFeature->firstResult();
887   }
888   return aResult;
889 }
890
891 //**************************************************************
892 bool isFeatureOfResult(const FeaturePtr& theFeature, const std::string& theGroupOfResult)
893 {
894   bool isResult = false;
895
896   if (!theFeature->data()->isValid())
897     return isResult;
898
899   ResultPtr aFirstResult = theFeature->firstResult();
900   if (!aFirstResult.get())
901     return isResult;
902
903   return aFirstResult->groupName() == theGroupOfResult;
904 }
905
906 //**************************************************************
907 bool hasModuleDocumentFeature(const std::set<FeaturePtr>& theFeatures)
908 {
909   bool aFoundModuleDocumentObject = false;
910   DocumentPtr aModuleDoc = ModelAPI_Session::get()->moduleDocument();
911
912   std::set<FeaturePtr>::const_iterator anIt = theFeatures.begin(), aLast = theFeatures.end();
913   for (; anIt != aLast && !aFoundModuleDocumentObject; anIt++) {
914     FeaturePtr aFeature = *anIt;
915     ResultPtr aResult = ModuleBase_Tools::firstResult(aFeature);
916     if (aResult.get() && aResult->groupName() == ModelAPI_ResultPart::group())
917       continue;
918     aFoundModuleDocumentObject = aFeature->document() == aModuleDoc;
919   }
920
921   return aFoundModuleDocumentObject;
922 }
923
924 //**************************************************************
925 bool askToDelete(const std::set<FeaturePtr> theFeatures,
926                  const std::map<FeaturePtr, std::set<FeaturePtr> >& theReferences,
927                  QWidget* theParent,
928                  std::set<FeaturePtr>& theReferencesToDelete,
929                  const std::string& thePrefixInfo)
930 {
931   QString aNotActivatedDocWrn;
932   std::string aNotActivatedNames;
933   if (!ModelAPI_Tools::allDocumentsActivated(aNotActivatedNames)) {
934     if (ModuleBase_Tools::hasModuleDocumentFeature(theFeatures))
935       aNotActivatedDocWrn =
936         QObject::tr("Selected objects can be used in Part documents which are not loaded:%1.\n")
937                             .arg(aNotActivatedNames.c_str());
938   }
939
940   std::set<FeaturePtr> aFeaturesRefsTo;
941   std::set<FeaturePtr> aFeaturesRefsToParameter;
942   std::set<FeaturePtr> aParameterFeatures;
943   QStringList aPartFeatureNames;
944   std::set<FeaturePtr>::const_iterator anIt = theFeatures.begin(),
945                                        aLast = theFeatures.end();
946   // separate features to references to parameter features and references to others
947   for (; anIt != aLast; anIt++) {
948     FeaturePtr aFeature = *anIt;
949     if (theReferences.find(aFeature) == theReferences.end())
950       continue;
951
952     if (isFeatureOfResult(aFeature, ModelAPI_ResultPart::group()))
953       aPartFeatureNames.append(aFeature->name().c_str());
954
955     std::set<FeaturePtr> aRefFeatures;
956     std::set<FeaturePtr> aRefList = theReferences.at(aFeature);
957     std::set<FeaturePtr>::const_iterator aRefIt = aRefList.begin(), aRefLast = aRefList.end();
958     for (; aRefIt != aRefLast; aRefIt++) {
959       FeaturePtr aRefFeature = *aRefIt;
960       if (theFeatures.find(aRefFeature) == theFeatures.end() && // it is not selected
961           aRefFeatures.find(aRefFeature) == aRefFeatures.end()) // it is not added
962         aRefFeatures.insert(aRefFeature);
963     }
964
965     if (isFeatureOfResult(aFeature, ModelAPI_ResultParameter::group())) {
966       aFeaturesRefsToParameter.insert(aRefFeatures.begin(), aRefFeatures.end());
967       aParameterFeatures.insert(aFeature);
968     }
969     else {
970       theReferencesToDelete.insert(aRefFeatures.begin(), aRefFeatures.end());
971     }
972   }
973
974   std::set<FeaturePtr> aFeaturesRefsToParameterOnly;
975   anIt = aFeaturesRefsToParameter.begin();
976   aLast = aFeaturesRefsToParameter.end();
977   // separate features to references to parameter features and references to others
978   QStringList aParamFeatureNames;
979   for (; anIt != aLast; anIt++) {
980     FeaturePtr aFeature = *anIt;
981     if (theReferencesToDelete.find(aFeature) == theReferencesToDelete.end()) {
982       aFeaturesRefsToParameterOnly.insert(aFeature);
983       aParamFeatureNames.append(aFeature->name().c_str());
984     }
985   }
986   aParamFeatureNames.sort();
987   QStringList anOtherFeatureNames;
988   anIt = theReferencesToDelete.begin();
989   aLast = theReferencesToDelete.end();
990   for (; anIt != aLast; anIt++) {
991     FeaturePtr aFeature = *anIt;
992     if (isFeatureOfResult(aFeature, ModelAPI_ResultPart::group()))
993       aPartFeatureNames.append(aFeature->name().c_str());
994     else
995       anOtherFeatureNames.append(aFeature->name().c_str());
996   }
997   aPartFeatureNames.sort();
998   anOtherFeatureNames.sort();
999
1000   bool aCanReplaceParameters = !aFeaturesRefsToParameterOnly.empty();
1001
1002   QMessageBox aMessageBox(theParent);
1003   aMessageBox.setWindowTitle(QObject::tr("Delete features"));
1004   aMessageBox.setIcon(QMessageBox::Warning);
1005   aMessageBox.setStandardButtons(QMessageBox::No | QMessageBox::Yes);
1006   aMessageBox.setDefaultButton(QMessageBox::No);
1007
1008   QString aText;
1009   if (!thePrefixInfo.empty())
1010     aText = thePrefixInfo.c_str();
1011   QString aSep = ", ";
1012   if (!aPartFeatureNames.empty()) {
1013     aText += QString(QObject::tr("The following parts will be deleted: %1.\n"))
1014              .arg(aPartFeatureNames.join(aSep));
1015   }
1016   if (!aNotActivatedDocWrn.isEmpty())
1017     aText += aNotActivatedDocWrn;
1018   if (!anOtherFeatureNames.empty()) {
1019     const char* aMsg = "Features are used in the following features: %1.\nThese "
1020                        "features will be deleted.\n";
1021     aText += QString(QObject::tr(aMsg))
1022                      .arg(anOtherFeatureNames.join(aSep));
1023   }
1024   if (!aParamFeatureNames.empty()) {
1025     const char* aMsg = "Parameters are used directly and through a sequence "
1026                        "of dependencies in the following features: %1.\nThese features will "
1027                        "be deleted.\nOr parameters could be replaced by their values.\n";
1028     aText += QString(QObject::tr(aMsg))
1029                      .arg(aParamFeatureNames.join(aSep));
1030     QPushButton *aReplaceButton =
1031       aMessageBox.addButton(QObject::tr("Replace"), QMessageBox::ActionRole);
1032   }
1033
1034   if (!aText.isEmpty()) {
1035     aText += "Would you like to continue?";
1036     aMessageBox.setText(aText);
1037     aMessageBox.exec();
1038     QMessageBox::ButtonRole aButtonRole = aMessageBox.buttonRole(aMessageBox.clickedButton());
1039
1040     if (aButtonRole == QMessageBox::NoRole)
1041       return false;
1042
1043     if (aButtonRole == QMessageBox::ActionRole) {
1044       foreach (FeaturePtr aObj, aParameterFeatures)
1045         ModelAPI_ReplaceParameterMessage::send(aObj, 0);
1046     }
1047     else
1048       theReferencesToDelete.insert(aFeaturesRefsToParameterOnly.begin(),
1049                                    aFeaturesRefsToParameterOnly.end());
1050   }
1051   return true;
1052 }
1053
1054 //**************************************************************
1055 void convertToFeatures(const QObjectPtrList& theObjects, std::set<FeaturePtr>& theFeatures)
1056 {
1057   QObjectPtrList::const_iterator anIt = theObjects.begin(), aLast = theObjects.end();
1058   for(; anIt != aLast; anIt++) {
1059     ObjectPtr anObject = *anIt;
1060     FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(anObject);
1061     // for parameter result, use the corresponded reature to be removed
1062     if (!aFeature.get() && anObject->groupName() == ModelAPI_ResultParameter::group()) {
1063       aFeature = ModelAPI_Feature::feature(anObject);
1064     }
1065     if (aFeature.get())
1066       theFeatures.insert(aFeature);
1067   }
1068 }
1069
1070 //**************************************************************
1071 void convertToFolders(const QObjectPtrList& theObjects,
1072                                          std::set<FolderPtr>& theFolders)
1073 {
1074   QObjectPtrList::const_iterator anIt = theObjects.begin(), aLast = theObjects.end();
1075   for(; anIt != aLast; anIt++) {
1076     ObjectPtr anObject = *anIt;
1077     FolderPtr aFeature = std::dynamic_pointer_cast<ModelAPI_Folder>(anObject);
1078     if (aFeature.get())
1079       theFolders.insert(aFeature);
1080   }
1081 }
1082
1083
1084 //**************************************************************
1085 QString translate(const Events_InfoMessage& theMessage)
1086 {
1087   QString aMessage;
1088
1089   if (!theMessage.empty()) {
1090     std::string aStr = Config_Translator::translate(theMessage);
1091     if (!aStr.empty()) {
1092       std::string aCodec = Config_Translator::codec(theMessage);
1093       aMessage = QTextCodec::codecForName(aCodec.c_str())->toUnicode(aStr.c_str());
1094     }
1095   }
1096
1097   return aMessage;
1098 }
1099
1100 QString translate(const std::string& theContext, const std::string& theMessage)
1101 {
1102   QString aMessage;
1103
1104   if (!theMessage.empty()) {
1105     std::string aStr = Config_Translator::translate(theContext, theMessage);
1106     if (!aStr.empty()) {
1107       std::string aCodec = Config_Translator::codec(theContext);
1108       aMessage = QTextCodec::codecForName(aCodec.c_str())->toUnicode(aStr.c_str());
1109     }
1110   }
1111
1112   return aMessage;
1113 }
1114
1115 void setPointBallHighlighting(AIS_Shape* theAIS)
1116 {
1117   static Handle(Image_AlienPixMap) aPixMap;
1118   if(aPixMap.IsNull()) {
1119     // Load icon for the presentation
1120     std::string aFile;
1121     char* anEnv = getenv("SHAPER_ROOT_DIR");
1122     if(anEnv) {
1123       aFile = std::string(anEnv) +
1124         FSEP + "share" + FSEP + "salome" + FSEP + "resources" + FSEP + "shaper";
1125     } else {
1126       anEnv = getenv("OPENPARTS_ROOT_DIR");
1127       if (anEnv)
1128         aFile = std::string(anEnv) + FSEP + "resources";
1129     }
1130
1131     aFile += FSEP;
1132     static const std::string aMarkerName = "marker_dot.png";
1133     aFile += aMarkerName;
1134     aPixMap = new Image_AlienPixMap();
1135     if(!aPixMap->Load(aFile.c_str())) {
1136       // The icon for constraint is not found
1137       static const std::string aMsg =
1138         "Error: Point market not found by path: \"" + aFile + "\". Falling back.";
1139       //Events_InfoMessage("ModuleBase_Tools::setPointBallHighlighting", aMsg).send();
1140     }
1141   }
1142
1143   Handle(Graphic3d_AspectMarker3d) anAspect;
1144   Handle(Prs3d_Drawer) aDrawer = theAIS->DynamicHilightAttributes();
1145   if (aDrawer.IsNull()) {
1146     if (ModuleBase_IViewer::DefaultHighlightDrawer.IsNull())
1147       return;
1148     aDrawer = new Prs3d_Drawer(*ModuleBase_IViewer::DefaultHighlightDrawer);
1149     if (!aDrawer->HasOwnPointAspect()) {
1150       aDrawer->SetPointAspect(new Prs3d_PointAspect(Aspect_TOM_BALL, Quantity_NOC_BLACK, 2.0));
1151     }
1152   }
1153   if(aDrawer->HasOwnPointAspect()) {
1154     Handle(Prs3d_PointAspect) aPntAspect = aDrawer->PointAspect();
1155     if(aPixMap->IsEmpty()) {
1156       anAspect = aPntAspect->Aspect();
1157       anAspect->SetType(Aspect_TOM_BALL);
1158     } else {
1159       if(aPixMap->Format() == Image_PixMap::ImgGray) {
1160         aPixMap->SetFormat (Image_PixMap::ImgAlpha);
1161       } else if(aPixMap->Format() == Image_PixMap::ImgGrayF) {
1162         aPixMap->SetFormat (Image_PixMap::ImgAlphaF);
1163       }
1164       anAspect = new Graphic3d_AspectMarker3d(aPixMap);
1165       aPntAspect->SetAspect(anAspect);
1166     }
1167     aDrawer->SetPointAspect(aPntAspect);
1168           theAIS->SetDynamicHilightAttributes(aDrawer);
1169   }
1170 }
1171
1172 FeaturePtr createParameter(const QString& theText)
1173 {
1174   FeaturePtr aParameter;
1175   QStringList aList = theText.split("=");
1176   if (aList.count() != 2) {
1177     return aParameter;
1178   }
1179   QString aParamName = aList.at(0).trimmed();
1180
1181   if (isNameExist(aParamName, FeaturePtr())) {
1182     return aParameter;
1183   }
1184
1185   if (!ModelAPI_Expression::isVariable(aParamName.toStdString())) {
1186     return aParameter;
1187   }
1188
1189   QString aExpression = aList.at(1).trimmed();
1190   if (aExpression.isEmpty()) {
1191     return aParameter;
1192   }
1193
1194   SessionPtr aMgr = ModelAPI_Session::get();
1195   std::shared_ptr<ModelAPI_Document> aDoc = aMgr->activeDocument();
1196
1197   aParameter = aDoc->addFeature("Parameter");
1198   if (aParameter.get()) {
1199     AttributeStringPtr aNameAttr = aParameter->string("variable");
1200     aNameAttr->setValue(aParamName.toStdString());
1201
1202     AttributeStringPtr aExprAttr = aParameter->string("expression");
1203     aExprAttr->setValue(aExpression.toStdString());
1204     aParameter->execute();
1205
1206     Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_CREATED));
1207     Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
1208   }
1209   return aParameter;
1210 }
1211
1212 void editParameter(FeaturePtr theParam, const QString& theText)
1213 {
1214   QStringList aList = theText.split("=");
1215   QString aParamName = aList.at(0).trimmed();
1216
1217   QString aExpression = aList.at(1).trimmed();
1218   if (aExpression.isEmpty()) {
1219     return;
1220   }
1221
1222   if (isNameExist(aParamName, theParam)) {
1223     return;
1224   }
1225   AttributeStringPtr aNameAttr = theParam->string("variable");
1226   aNameAttr->setValue(aParamName.toStdString());
1227
1228   AttributeStringPtr aExprAttr = theParam->string("expression");
1229   aExprAttr->setValue(aExpression.toStdString());
1230   theParam->execute();
1231
1232   Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
1233 }
1234
1235 bool isNameExist(const QString& theName, FeaturePtr theIgnoreParameter)
1236 {
1237   SessionPtr aMgr = ModelAPI_Session::get();
1238   std::shared_ptr<ModelAPI_Document> aDoc = aMgr->activeDocument();
1239   FeaturePtr aParamFeature;
1240   int aNbFeatures = aDoc->numInternalFeatures();
1241   std::string aName = theName.toStdString();
1242   for (int i = 0; i < aNbFeatures; i++) {
1243     aParamFeature = aDoc->internalFeature(i);
1244     if (aParamFeature && aParamFeature->getKind() == "Parameter") {
1245       if ((theIgnoreParameter != aParamFeature) && (aParamFeature->name() == aName))
1246         return true;
1247     }
1248   }
1249   return false;
1250 }
1251
1252 FeaturePtr findParameter(const QString& theName)
1253 {
1254   SessionPtr aMgr = ModelAPI_Session::get();
1255   std::shared_ptr<ModelAPI_Document> aDoc = aMgr->activeDocument();
1256   FeaturePtr aParamFeature;
1257   int aNbFeatures = aDoc->numInternalFeatures();
1258   std::string aName = theName.toStdString();
1259   for (int i = 0; i < aNbFeatures; i++) {
1260     aParamFeature = aDoc->internalFeature(i);
1261     if (aParamFeature && aParamFeature->getKind() == "Parameter") {
1262       if (aParamFeature->name() == aName)
1263         return aParamFeature;
1264     }
1265   }
1266   return FeaturePtr();
1267 }
1268
1269
1270 //********************************************************************
1271 std::string generateName(const AttributePtr& theAttribute,
1272   ModuleBase_IWorkshop* theWorkshop)
1273 {
1274   std::string aName;
1275   if (theAttribute.get() != NULL) {
1276     ModuleBase_Operation* anOperation = theWorkshop->currentOperation();
1277
1278     FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner());
1279     if (aFeature.get()) {
1280       std::string aXmlCfg, aDescription;
1281       theWorkshop->module()->getXMLRepresentation(aFeature->getKind(), aXmlCfg, aDescription);
1282
1283       ModuleBase_WidgetFactory aFactory(aXmlCfg, theWorkshop);
1284       std::string anAttributeTitle;
1285       aFactory.getAttributeTitle(theAttribute->id(), anAttributeTitle);
1286
1287       std::stringstream aStreamName;
1288       aStreamName << theAttribute->owner()->data()->name() << "/" << anAttributeTitle.c_str();
1289       aName = aStreamName.str();
1290     }
1291   }
1292   return aName;
1293 }
1294
1295 } // namespace ModuleBase_Tools
1296
1297