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