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