Salome HOME
Check name of a new parameter defined by user
[modules/shaper.git] / src / ParametersPlugin / ParametersPlugin_WidgetParamsMgr.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
2
3 // File:        ParametersPlugin_WidgetParamsMgr.cpp
4 // Created:     11 Apr 2016
5 // Author:      Vitaly SMETANNIKOV
6
7 #include "ParametersPlugin_WidgetParamsMgr.h"
8 #include "ParametersPlugin_Parameter.h"
9 #include "ParametersPlugin_Validators.h"
10
11 #include <Events_InfoMessage.h>
12
13 #include <ModelAPI_ResultParameter.h>
14 #include <ModelAPI_AttributeString.h>
15 #include <ModelAPI_AttributeRefList.h>
16 #include <ModelAPI_AttributeDouble.h>
17 #include <ModelAPI_AttributeInteger.h>
18 #include <ModelAPI_Events.h>
19 #include <ModelAPI_Session.h>
20 #include <ModelAPI_Tools.h>
21 #include <ModelAPI_Expression.h>
22
23 #include <ModuleBase_Tools.h>
24
25 #include <Events_Loop.h>
26
27 #include <QLayout>
28 #include <QPushButton>
29 #include <QToolButton>
30 #include <QStyledItemDelegate>
31 #include <QPainter>
32 #include <QMessageBox>
33 #include <QTimer>
34 #include <QEvent>
35 #include <QKeyEvent>
36 #include <QDialogButtonBox>
37
38 enum ColumnType {
39   Col_Name,
40   Col_Equation,
41   Col_Result,
42   Col_Comment
43 };
44
45 const char* NoName = "<NoName>";
46 const char* NoValue = "<NoValue>";
47 const char* NotValid = "<NotValid>";
48
49 /*!
50  * \ingroup GUI
51  * ItemDelegate object in order to redefine items behavior
52  */
53 class ParametersPlugin_ItemDelegate : public QStyledItemDelegate
54 {
55 public:
56   /// Constructor
57   /// \param thaParent a parent
58   ParametersPlugin_ItemDelegate(QObject* thaParent) : 
59       QStyledItemDelegate(thaParent) {}
60
61   /// Redefinition of virtual method
62   /// \param painter a painter object
63   /// \param option the item options
64   /// \param index the current index
65   virtual void paint(QPainter* painter, 
66     const QStyleOptionViewItem& option, 
67     const QModelIndex& index ) const;
68   
69   /// Redefinition of virtual method
70   /// \param parent a parent widget
71   /// \param option the item options
72   /// \param index the current index
73   virtual QWidget* createEditor(QWidget* parent, 
74                                 const QStyleOptionViewItem& option, 
75                                 const QModelIndex& index) const;
76
77   /// Returns True if the given index is editable item
78   /// \param theIndex an item index
79   bool isEditable(const QModelIndex& theIndex) const;
80
81   /// Returns currently editing index
82   QModelIndex editIndex() const { return myEditingIdx; }
83
84 private:
85   mutable QModelIndex myEditingIdx;
86 };
87
88 bool ParametersPlugin_ItemDelegate::isEditable(const QModelIndex& theIndex) const
89 {
90   QModelIndex aParent = theIndex.parent();
91   if (aParent.isValid() && (aParent.row() == 0)) {
92     if (theIndex.column() == 2)
93       return false;
94   } else
95     return false;
96   return true;
97 }
98
99 void ParametersPlugin_ItemDelegate::paint(QPainter* painter, 
100                                           const QStyleOptionViewItem& option, 
101                                           const QModelIndex& index ) const
102 {
103   QBrush aBrush = painter->brush();
104   QPen aPen = painter->pen();
105 //  if (!isEditable(index))
106   if (!index.parent().isValid())
107     painter->setBrush(Qt::lightGray);
108
109   painter->setPen(Qt::lightGray);
110   painter->drawRect(option.rect);
111   painter->setPen(aPen);
112
113   QStyledItemDelegate::paint(painter, option, index);
114   painter->setBrush(aBrush);
115 }
116
117 QWidget* ParametersPlugin_ItemDelegate::createEditor(QWidget* parent, 
118                                                      const QStyleOptionViewItem& option, 
119                                                      const QModelIndex& index) const
120 {
121   myEditingIdx = index;
122   return QStyledItemDelegate::createEditor(parent, option, index);
123 }
124
125 /////////////////////////////////////////////////////////////////////////////////////////////////
126 void ParametersPlugin_TreeWidget::closeEditor(QWidget* theEditor, QAbstractItemDelegate::EndEditHint theHint)
127 {
128   if (theHint == QAbstractItemDelegate::EditNextItem) {
129     QModelIndex aCurrent = currentIndex();
130     QModelIndex aParent = model()->index(0, 0);
131     int aNbRows = model()->rowCount(aParent);
132     QModelIndex aIdx;
133     switch (aCurrent.column()) {
134     case 0:
135       aIdx = model()->index(aCurrent.row(), 1, aParent);
136       break;
137     case 1:
138       if (aCurrent.row() < (aNbRows - 1))
139         aIdx = model()->index(aCurrent.row() + 1, 0, aParent);
140       else {
141         QTreeWidget::closeEditor(theEditor, QAbstractItemDelegate::NoHint);
142         return;
143       }
144       break;
145     case 3:
146       QTreeWidget::closeEditor(theEditor, theHint);
147       return;
148     }
149     if (aIdx.isValid()) {
150       QTreeWidget::closeEditor(theEditor, QAbstractItemDelegate::NoHint);
151       setCurrentIndex(aIdx);
152       edit(aIdx);
153       return;
154     }
155   }
156   QTreeWidget::closeEditor(theEditor, theHint);
157 }
158
159 /////////////////////////////////////////////////////////////////////////////////////////////////
160
161 ParametersPlugin_WidgetParamsMgr::ParametersPlugin_WidgetParamsMgr(QWidget* theParent, const Config_WidgetAPI* theData)
162   : ModuleBase_ModelDialogWidget(theParent, theData)
163 {
164   QVBoxLayout* aLayout = new QVBoxLayout(this);
165
166   myTable = new ParametersPlugin_TreeWidget(this);
167   myTable->setColumnCount(4);
168   QStringList aHeaders;
169   aHeaders << tr("Name") << tr("Equation") << tr("Result") << tr("Comment");
170   myTable->setHeaderLabels(aHeaders);
171   myTable->setColumnWidth(Col_Name, 200);
172   myTable->setColumnWidth(Col_Equation, 100);
173   myTable->setColumnWidth(Col_Result, 80);
174   myTable->setColumnWidth(Col_Comment, 200);
175   myTable->setMinimumWidth(600);
176   myTable->setEditTriggers(QAbstractItemView::NoEditTriggers);
177   myTable->setSelectionMode(QAbstractItemView::SingleSelection);
178
179   connect(myTable, SIGNAL(doubleClicked(const QModelIndex&)),
180           SLOT(onDoubleClick(const QModelIndex&)));
181   connect(myTable, SIGNAL(itemSelectionChanged()), SLOT(onSelectionChanged()));
182
183   myDelegate = new ParametersPlugin_ItemDelegate(myTable);
184   connect(myDelegate, SIGNAL(closeEditor(QWidget*, QAbstractItemDelegate::EndEditHint)), 
185           SLOT(onCloseEditor(QWidget*, QAbstractItemDelegate::EndEditHint)));
186
187   myTable->setItemDelegate(myDelegate);
188   aLayout->addWidget(myTable);
189
190   // Define root nodes
191   QStringList aNames;
192   aNames<<tr("Parameters");
193   myParameters = new QTreeWidgetItem(aNames);
194   myParameters->setFlags(Qt::ItemIsEnabled);
195   myTable->addTopLevelItem(myParameters);
196
197   aNames.clear();
198   aNames<<tr("Features");
199   myFeatures = new QTreeWidgetItem(aNames);
200   myFeatures->setFlags(Qt::ItemIsEnabled);
201   myTable->addTopLevelItem(myFeatures);
202
203   QHBoxLayout* aBtnLayout = new QHBoxLayout(this);
204
205   myUpBtn = new QToolButton(this);
206   myUpBtn->setArrowType(Qt::UpArrow);
207   connect(myUpBtn, SIGNAL(clicked(bool)), SLOT(onUp()));
208   aBtnLayout->addWidget(myUpBtn);
209
210   myDownBtn = new QToolButton(this);
211   myDownBtn->setArrowType(Qt::DownArrow);
212   connect(myDownBtn, SIGNAL(clicked(bool)), SLOT(onDown()));
213   aBtnLayout->addWidget(myDownBtn);
214
215   aBtnLayout->addStretch();
216
217   myAddBtn = new QPushButton(tr("Add"), this);
218   connect(myAddBtn, SIGNAL(clicked(bool)), SLOT(onAdd()));
219   aBtnLayout->addWidget(myAddBtn);
220
221   myInsertBtn = new QPushButton(tr("Insert"), this);
222   connect(myInsertBtn, SIGNAL(clicked(bool)), SLOT(onInsert()));
223   aBtnLayout->addWidget(myInsertBtn);
224
225   myRemoveBtn = new QPushButton(tr("Remove"), this);
226   connect(myRemoveBtn, SIGNAL(clicked(bool)), SLOT(onRemove()));
227   aBtnLayout->addWidget(myRemoveBtn);
228
229   aLayout->addLayout(aBtnLayout);
230
231   onSelectionChanged();
232 }
233
234 QList<QWidget*> ParametersPlugin_WidgetParamsMgr::getControls() const
235 {
236   QList<QWidget*> aList;
237
238   return aList;
239 }
240
241 void ParametersPlugin_WidgetParamsMgr::selectItemScroll(QTreeWidgetItem* aItem)
242 {
243   myTable->clearSelection();
244   QModelIndex aParent = myTable->model()->index(0, 0);
245   int aChildIdx = myParameters->indexOfChild(aItem);
246   QModelIndex aIndex = myTable->model()->index(aChildIdx, Col_Name, aParent);
247   myTable->selectionModel()->select(aIndex, 
248     QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows);
249   myTable->scrollToItem(aItem);
250 }
251
252
253 bool ParametersPlugin_WidgetParamsMgr::storeValueCustom()
254 {
255   ParametersPlugin_ExpressionValidator aValidator;
256   std::list<std::string> aArgs;
257   std::string aAttrId = ParametersPlugin_Parameter::VARIABLE_ID();
258   Events_InfoMessage aErr;
259   int aId = 0;
260   foreach(FeaturePtr aFeature, myParametersList) {
261     if (!aValidator.isValid(aFeature->attribute(aAttrId), aArgs, aErr)) {
262       // TODO(spo): translate
263       QMessageBox::warning(this, tr("Warning"), aErr.messageString().c_str());
264       selectItemScroll(myParameters->child(aId));
265       return false;
266     }
267     aId++;
268   }
269   return true;
270 }
271
272 bool ParametersPlugin_WidgetParamsMgr::restoreValueCustom()
273 {
274   return true;
275 }
276
277 void ParametersPlugin_WidgetParamsMgr::activateCustom()
278 {
279   updateParametersFeatures();
280   updateParametersPart();
281   updateFeaturesPart();
282
283   myFeatures->setExpanded(true);
284   myParameters->setExpanded(true);
285 }
286
287 void ParametersPlugin_WidgetParamsMgr::updateParametersFeatures()
288 {
289   myParametersList.clear();
290   FeaturePtr aFeature = feature();
291   DocumentPtr aDoc = aFeature->document();
292   ObjectPtr aObj;
293   FeaturePtr aParamFeature;
294   int aNbFeatures = aDoc->numInternalFeatures();
295   for (int i = 0; i < aNbFeatures; i++) {
296     aParamFeature = aDoc->internalFeature(i);
297     if (aParamFeature->getKind() == ParametersPlugin_Parameter::ID()) {
298       myParametersList.append(aParamFeature);
299     }
300   }
301 }
302
303 void ParametersPlugin_WidgetParamsMgr::updateFeaturesPart()
304 {
305   QList<FeaturePtr> aFeatureList;
306   updateItem(myFeatures, featuresItems(myParametersList, aFeatureList));
307 }
308
309 void ParametersPlugin_WidgetParamsMgr::updateParametersPart()
310 {
311   updateItem(myParameters, parametersItems(myParametersList));
312   bool aIsValid = isValid();
313   enableButtons(aIsValid);
314 }
315
316
317 QList<QStringList> ParametersPlugin_WidgetParamsMgr::
318   featuresItems(const QList<FeaturePtr>& theFeatures, QList<FeaturePtr>& theFeatureList) const
319 {
320   QList<QStringList> aItemsList;
321   ResultParameterPtr aParam;
322   foreach(FeaturePtr aParameter, theFeatures) {
323     aParam = std::dynamic_pointer_cast<ModelAPI_ResultParameter>(aParameter->firstResult());
324     const std::set<std::shared_ptr<ModelAPI_Attribute>>& aRefs = aParam->data()->refsToMe();
325     std::set<std::shared_ptr<ModelAPI_Attribute> >::const_iterator aIt;
326     for(aIt = aRefs.cbegin(); aIt != aRefs.cend(); aIt++) {
327       std::shared_ptr<ModelAPI_Attribute> aAttr = (*aIt);
328       FeaturePtr aReferenced = std::dynamic_pointer_cast<ModelAPI_Feature>(aAttr->owner());
329       if (aReferenced.get()) {
330         if (aReferenced->getKind() == ParametersPlugin_Parameter::ID()) {
331           // Find referenced feature Recursive
332           QList<FeaturePtr> aList;
333           aList.append(aReferenced);
334           QList<QStringList> aItems = featuresItems(aList, theFeatureList);
335           aItemsList.append(aItems);
336         } else {
337           if (!theFeatureList.contains(aReferenced)) {
338             QStringList aValNames;
339             aValNames << aReferenced->data()->name().c_str();
340
341             AttributeDoublePtr aDouble = std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(aAttr);
342             if (aDouble.get()) {
343               aValNames << aDouble->text().c_str();
344               aValNames << QString::number(aDouble->value());
345             } else {
346               AttributeIntegerPtr aInt = std::dynamic_pointer_cast<ModelAPI_AttributeInteger>(aAttr);
347               if (aInt.get()) {
348                 aValNames << aInt->text().c_str();
349                 aValNames << QString::number(aInt->value());
350               }
351             }
352             aItemsList.append(aValNames);
353             theFeatureList.append(aReferenced);
354           }
355         }
356       }
357     }
358   }
359   return aItemsList;
360 }
361
362
363 QList<QStringList> ParametersPlugin_WidgetParamsMgr::
364   parametersItems(const QList<FeaturePtr>& theFeatures) const
365 {
366   std::list<std::string> aArgs;
367   std::string aErr;
368   QList<QStringList> aItemsList;
369   foreach(FeaturePtr aParameter, theFeatures) {
370     ResultPtr aParam = aParameter->firstResult();
371     QStringList aValues;
372
373     std::string aName = aParameter->string(ParametersPlugin_Parameter::VARIABLE_ID())->value();
374     if (aName.empty()) {
375       aValues << NoName;
376     } else
377       aValues << aName.c_str();
378
379     std::string aExpr = aParameter->string(ParametersPlugin_Parameter::EXPRESSION_ID())->value();
380     if (aName.empty()) {
381       aValues << NoValue;
382     } else
383       aValues << aExpr.c_str();
384
385     std::string aErr = aParameter->data()->string(ParametersPlugin_Parameter::EXPRESSION_ERROR_ID())->value();
386     if (aErr.empty()) {
387       AttributeDoublePtr aValueAttribute = aParam->data()->real(ModelAPI_ResultParameter::VALUE());
388       aValues << QString::number(aValueAttribute->value());
389     } else {
390       aValues << aErr.c_str();
391     }
392     aValues << aParameter->string(ParametersPlugin_Parameter::COMMENT_ID())->value().c_str();
393     aItemsList.append(aValues);
394   }
395   return aItemsList;
396 }
397
398
399 void ParametersPlugin_WidgetParamsMgr::onDoubleClick(const QModelIndex& theIndex)
400 {
401   if (myDelegate->isEditable(theIndex)) {
402     myTable->setCurrentIndex(theIndex);
403     myTable->edit(theIndex);
404   }
405 }
406
407 void ParametersPlugin_WidgetParamsMgr::onCloseEditor(QWidget* theEditor, 
408                                                      QAbstractItemDelegate::EndEditHint theHint)
409 {
410   FeaturePtr aFeature = myParametersList.at(myDelegate->editIndex().row());
411   QTreeWidgetItem* aItem = myParameters->child(myDelegate->editIndex().row());
412   int aColumn = myDelegate->editIndex().column();
413   QString aText = aItem->text(aColumn);
414   bool isModified = false;
415
416   switch (aColumn) {
417   case Col_Name:
418     {
419       AttributeStringPtr aStringAttr = aFeature->string(ParametersPlugin_Parameter::VARIABLE_ID());
420       if (!aText.isEmpty()) {
421         while (aText.indexOf(" ") != -1) {
422           aText.replace(" ", "");
423         }
424         if (hasName(aText)) {
425           myMessage = tr("Name '%1' already exists.").arg(aText);
426           QTimer::singleShot(50, this, SLOT(sendWarning()));
427           return;
428         }
429         aStringAttr->setValue(aText.toStdString());
430         isModified = true;
431       } 
432     }
433     break;
434   case Col_Equation:
435     {
436       AttributeStringPtr aStringAttr = aFeature->string(ParametersPlugin_Parameter::EXPRESSION_ID());
437       if (!aText.isEmpty()) {
438         if (aText != aStringAttr->value().c_str()) {
439           aStringAttr->setValue(aText.toStdString());
440           aFeature->execute();
441           isModified = true;
442         }
443       }
444     }
445     break;
446   case Col_Comment:
447     {
448       AttributeStringPtr aStringAttr = aFeature->string(ParametersPlugin_Parameter::COMMENT_ID());
449       aStringAttr->setValue(aText.toStdString());
450       isModified = true;
451     }
452     break;
453   }
454
455   if (!isModified)
456     return;
457   Events_Loop* aLoop = Events_Loop::loop();
458   aLoop->flush(Events_Loop::eventByName(EVENT_OBJECT_CREATED));
459   aLoop->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
460   aLoop->flush(Events_Loop::eventByName(EVENT_OBJECT_DELETED));
461
462   if (aColumn != Col_Comment)
463     updateParametersPart();
464   updateFeaturesPart();
465           
466   onSelectionChanged();
467 }
468
469 void ParametersPlugin_WidgetParamsMgr::updateItem(QTreeWidgetItem* theItem, 
470                                                   const QList<QStringList>& theFeaturesList)
471 {
472   if (theFeaturesList.count() != theItem->childCount()) {
473     if (theItem->childCount()  < theFeaturesList.count()) {
474       while (theItem->childCount() != theFeaturesList.count()) 
475         theItem->addChild(createNewItem(theItem));
476     } else {
477       while (theItem->childCount() != theFeaturesList.count()) 
478         theItem->removeChild(theItem->child(theItem->childCount() - 1));
479     }
480   }
481   int i = 0;
482   foreach(QStringList aFeature, theFeaturesList) {
483     int aCol = 0;
484     foreach(QString aText, aFeature) {
485       if (aText.length() > 0) {
486         theItem->child(i)->setText(aCol, aText);
487         theItem->child(i)->setToolTip(aCol, aText);
488       }
489       aCol++;
490     }
491     i++;
492   }
493 }
494
495 FeaturePtr ParametersPlugin_WidgetParamsMgr::createParameter() const
496 {
497   SessionPtr aMgr = ModelAPI_Session::get();
498   std::shared_ptr<ModelAPI_Document> aDoc = aMgr->activeDocument();
499
500   FeaturePtr aFeature = aDoc->addFeature(ParametersPlugin_Parameter::ID());
501   if (aFeature.get()) {
502     Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_CREATED));
503     Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
504   }
505   return aFeature;
506 }
507
508
509 QTreeWidgetItem* ParametersPlugin_WidgetParamsMgr::createNewItem(QTreeWidgetItem* theParent) const
510 {
511   QStringList aValues;
512   aValues << NoName;
513   aValues << NoValue;
514
515   QTreeWidgetItem* aItem = new QTreeWidgetItem(aValues);
516   if (theParent == myParameters)
517     aItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled);
518   else 
519     aItem->setFlags(Qt::NoItemFlags);
520   return aItem;
521 }
522
523
524 void ParametersPlugin_WidgetParamsMgr::onAdd()
525 {
526   FeaturePtr aFeature = createParameter();
527   if (!aFeature.get())
528     return;
529
530   myParametersList.append(aFeature);
531   updateParametersPart();    
532
533   QTreeWidgetItem* aItem = myParameters->child(myParameters->childCount() - 1);
534
535   myTable->scrollToItem(aItem);
536   myTable->setCurrentItem(aItem);
537   myTable->editItem(aItem);
538
539   enableButtons(false);
540 }
541
542 QTreeWidgetItem* ParametersPlugin_WidgetParamsMgr::selectedItem() const
543 {
544   QList<QTreeWidgetItem*> aItemsList = myTable->selectedItems();
545   if (aItemsList.count() == 0)
546     return 0;
547
548   QTreeWidgetItem* aCurrentItem = aItemsList.first();
549   if (aCurrentItem->parent() != myParameters)
550     return 0;
551
552   return aCurrentItem;
553 }
554
555
556 void ParametersPlugin_WidgetParamsMgr::onInsert()
557 {
558   QTreeWidgetItem* aCurrentItem = selectedItem();
559   if (!aCurrentItem)
560     return;
561
562   SessionPtr aMgr = ModelAPI_Session::get();
563   std::shared_ptr<ModelAPI_Document> aDoc = aMgr->activeDocument();
564
565   FeaturePtr aNewFeature = createParameter();
566   if (!aNewFeature.get())
567     return;
568
569   int aCurrentPos = myParameters->indexOfChild(aCurrentItem);
570   if (aCurrentPos == 0) {
571     aDoc->moveFeature(aNewFeature, FeaturePtr());
572   } else {
573     FeaturePtr aCurFeature = myParametersList.at(aCurrentPos - 1);
574     aDoc->moveFeature(aNewFeature, aCurFeature);
575   }
576   updateParametersFeatures();
577   updateParametersPart();
578
579   myTable->scrollToItem(aCurrentItem);
580   myTable->setCurrentItem(aCurrentItem);
581   myTable->editItem(aCurrentItem);
582 }
583
584 void ParametersPlugin_WidgetParamsMgr::onRemove()
585 {
586   QTreeWidgetItem* aCurrentItem = selectedItem();
587   if (!aCurrentItem)
588     return;
589
590   SessionPtr aMgr = ModelAPI_Session::get();
591   std::shared_ptr<ModelAPI_Document> aDoc = aMgr->activeDocument();
592
593   int aCurrentPos = myParameters->indexOfChild(aCurrentItem);
594   FeaturePtr aCurFeature = myParametersList.at(aCurrentPos);
595
596   QObjectPtrList anObjects;
597   anObjects.append(aCurFeature);
598
599   std::map<FeaturePtr, std::set<FeaturePtr> > aReferences;
600   std::set<FeaturePtr> aFeatures;
601   ModuleBase_Tools::convertToFeatures(anObjects, aFeatures);
602   ModelAPI_Tools::findAllReferences(aFeatures, aReferences);
603
604   std::set<FeaturePtr> aFeatureRefsToDelete;
605   if (ModuleBase_Tools::askToDelete(aFeatures, aReferences, this, aFeatureRefsToDelete)) {
606     if (!aFeatureRefsToDelete.empty())
607       aFeatures.insert(aFeatureRefsToDelete.begin(), aFeatureRefsToDelete.end());
608     ModelAPI_Tools::removeFeatures(aFeatures, false);
609
610     Events_Loop::loop()->flush(Events_Loop::loop()->eventByName(EVENT_OBJECT_DELETED));
611     Events_Loop::loop()->flush(Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY));
612     updateParametersFeatures();
613     updateFeaturesPart();
614     updateParametersPart();
615   }
616 }
617
618 void ParametersPlugin_WidgetParamsMgr::onUp()
619 {
620   QTreeWidgetItem* aCurrentItem = selectedItem();
621   if (!aCurrentItem)
622     return;
623
624   int aCurrentPos = myParameters->indexOfChild(aCurrentItem);
625   if (aCurrentPos == 0)
626     return;
627   FeaturePtr aCurFeature = myParametersList.at(aCurrentPos);
628
629   SessionPtr aMgr = ModelAPI_Session::get();
630   std::shared_ptr<ModelAPI_Document> aDoc = aMgr->activeDocument();
631
632   if (aCurrentPos == 1)
633     aDoc->moveFeature(aCurFeature, FeaturePtr());
634   else
635     aDoc->moveFeature(aCurFeature, myParametersList.at(aCurrentPos - 2));
636
637   // add the updated also the feature that goes down
638   Events_Loop::loop()->flush(Events_Loop::loop()->eventByName(EVENT_OBJECT_CREATED));
639   static Events_ID EVENT_UPD = Events_Loop::loop()->eventByName(EVENT_OBJECT_UPDATED);
640   ModelAPI_EventCreator::get()->sendUpdated(myParametersList.at(aCurrentPos - 1), EVENT_UPD);
641   Events_Loop::loop()->flush(EVENT_UPD);
642   Events_Loop::loop()->flush(Events_Loop::loop()->eventByName(EVENT_OBJECT_CREATED));
643   Events_Loop::loop()->flush(Events_Loop::loop()->eventByName(EVENT_OBJECT_DELETED));
644   Events_Loop::loop()->flush(Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY));
645   updateParametersFeatures();
646   updateParametersPart();
647   updateFeaturesPart();
648
649   if (aCurrentPos > 0) {
650     aCurrentItem = myParameters->child(aCurrentPos - 1);
651     myTable->setCurrentItem(aCurrentItem);
652     selectItemScroll(aCurrentItem);
653   }
654 }
655
656 void ParametersPlugin_WidgetParamsMgr::onDown()
657 {
658   QTreeWidgetItem* aCurrentItem = selectedItem();
659   if (!aCurrentItem)
660     return;
661
662   int aCurrentPos = myParameters->indexOfChild(aCurrentItem);
663   if (aCurrentPos == (myParametersList.count() - 1))
664     return;
665   FeaturePtr aCurFeature = myParametersList.at(aCurrentPos);
666
667   SessionPtr aMgr = ModelAPI_Session::get();
668   std::shared_ptr<ModelAPI_Document> aDoc = aMgr->activeDocument();
669   aDoc->moveFeature(aCurFeature, myParametersList.at(aCurrentPos + 1));
670   // add the updated also the feature that goes up
671   static Events_ID EVENT_UPD = Events_Loop::loop()->eventByName(EVENT_OBJECT_UPDATED);
672   ModelAPI_EventCreator::get()->sendUpdated(myParametersList.at(aCurrentPos + 1), EVENT_UPD);
673
674   Events_Loop::loop()->flush(Events_Loop::loop()->eventByName(EVENT_OBJECT_CREATED));
675   Events_Loop::loop()->flush(Events_Loop::loop()->eventByName(EVENT_OBJECT_UPDATED));
676   Events_Loop::loop()->flush(Events_Loop::loop()->eventByName(EVENT_OBJECT_CREATED));
677   Events_Loop::loop()->flush(Events_Loop::loop()->eventByName(EVENT_OBJECT_DELETED));
678   Events_Loop::loop()->flush(Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY));
679   updateParametersFeatures();
680   updateParametersPart();
681   updateFeaturesPart();
682
683   if (aCurrentPos < myParameters->childCount() - 1) {
684     aCurrentItem = myParameters->child(aCurrentPos + 1);
685     myTable->setCurrentItem(aCurrentItem);
686     selectItemScroll(aCurrentItem);
687   }
688 }
689
690
691 bool ParametersPlugin_WidgetParamsMgr::hasName(const QString& theName) const
692 {
693   int aCurrent = myDelegate->editIndex().row();
694   int i = 0;
695   foreach(FeaturePtr aFeature, myParametersList) {
696     if ((i != aCurrent) && (aFeature->data()->name() == theName.toStdString()))
697       return true;
698     i++;
699   }
700   return false;
701 }
702
703 void ParametersPlugin_WidgetParamsMgr::sendWarning()
704 {
705   QMessageBox::warning(this, tr("Warning"), myMessage);
706   QTreeWidgetItem* aItem = myTable->currentItem();
707   if (aItem)
708     myTable->editItem(aItem);
709 }
710
711 void ParametersPlugin_WidgetParamsMgr::onSelectionChanged()
712 {
713   QList<QTreeWidgetItem*> aItemsList = myTable->selectedItems();
714   bool aIsValid = isValid();
715   if (aIsValid) {
716     bool isParameter = false;
717     foreach(QTreeWidgetItem* aItem, aItemsList) {
718       if (aItem->parent() == myParameters) {
719         isParameter = true;
720         break;
721       }
722     }
723     myInsertBtn->setEnabled(isParameter);
724     //myRemoveBtn->setEnabled(isParameter);
725     myUpBtn->setEnabled(isParameter);
726     myDownBtn->setEnabled(isParameter);
727   } else {
728     myInsertBtn->setEnabled(false);
729     //myRemoveBtn->setEnabled(false);
730     myUpBtn->setEnabled(false);
731     myDownBtn->setEnabled(false);
732   }
733   myRemoveBtn->setEnabled(!aItemsList.isEmpty());
734 }
735
736 void ParametersPlugin_WidgetParamsMgr::enableButtons(bool theEnable)
737 {
738   myAddBtn->setEnabled(theEnable);
739   if (theEnable) 
740     onSelectionChanged();
741   else {
742     myInsertBtn->setEnabled(theEnable);
743     myRemoveBtn->setEnabled(theEnable);
744     myUpBtn->setEnabled(theEnable);
745     myDownBtn->setEnabled(theEnable);
746   }
747   myOkCancelBtn->button(QDialogButtonBox::Ok)->setEnabled(theEnable);
748 }
749
750 bool ParametersPlugin_WidgetParamsMgr::isValid()
751 {
752   QTreeWidgetItem* aItem;
753   bool aIsValid = true;
754   for(int i = 0; i < myParameters->childCount(); i++) {
755     aItem = myParameters->child(i);
756     if ((aItem->text(Col_Name) == NoName) || 
757         (aItem->text(Col_Equation) == NoValue) ||
758         (!ModelAPI_Expression::isVariable(aItem->text(Col_Name).toStdString())) ) {
759       aIsValid = false;
760       break;
761     }
762   }
763   return aIsValid;
764 }
765