Salome HOME
524e92710d5c5ee53d10553cb15f0d4f623aee57
[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   bool aIsValid = checkIsValid();
286   enableButtons(aIsValid);
287 }
288
289
290 QList<QStringList> ParametersPlugin_WidgetParamsMgr::
291   featuresItems(const QList<FeaturePtr>& theFeatures) const
292 {
293   QList<QStringList> aItemsList;
294   ResultParameterPtr aParam;
295   foreach(FeaturePtr aParameter, theFeatures) {
296     aParam = std::dynamic_pointer_cast<ModelAPI_ResultParameter>(aParameter->firstResult());
297     const std::set<std::shared_ptr<ModelAPI_Attribute>>& aRefs = aParam->data()->refsToMe();
298     std::set<std::shared_ptr<ModelAPI_Attribute> >::const_iterator aIt;
299     for(aIt = aRefs.cbegin(); aIt != aRefs.cend(); aIt++) {
300       std::shared_ptr<ModelAPI_Attribute> aAttr = (*aIt);
301       FeaturePtr aReferenced = std::dynamic_pointer_cast<ModelAPI_Feature>(aAttr->owner());
302       if (aReferenced.get()) {
303         if (aReferenced->getKind() == ParametersPlugin_Parameter::ID()) {
304           // Find referenced feature Recursive
305           QList<FeaturePtr> aList;
306           aList.append(aReferenced);
307           QList<QStringList> aItems = featuresItems(aList);
308           aItemsList.append(aItems);
309         } else {
310           QStringList aValNames;
311           aValNames << aReferenced->data()->name().c_str();
312
313           AttributeDoublePtr aDouble = std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(aAttr);
314           if (aDouble.get()) {
315             aValNames << aDouble->text().c_str();
316             aValNames << QString::number(aDouble->value());
317           } else {
318             AttributeIntegerPtr aInt = std::dynamic_pointer_cast<ModelAPI_AttributeInteger>(aAttr);
319             if (aInt.get()) {
320               aValNames << aInt->text().c_str();
321               aValNames << QString::number(aInt->value());
322             }
323           }
324           aItemsList.append(aValNames);
325         }
326       }
327     }
328   }
329   return aItemsList;
330 }
331
332
333 QList<QStringList> ParametersPlugin_WidgetParamsMgr::
334   parametersItems(const QList<FeaturePtr>& theFeatures) const
335 {
336   std::list<std::string> aArgs;
337   std::string aErr;
338   QList<QStringList> aItemsList;
339   foreach(FeaturePtr aParameter, theFeatures) {
340     ResultPtr aParam = aParameter->firstResult();
341     QStringList aValues;
342
343     std::string aName = aParameter->string(ParametersPlugin_Parameter::VARIABLE_ID())->value();
344     if (aName.empty()) {
345       aValues << NoName;
346     } else
347       aValues << aName.c_str();
348
349     std::string aExpr = aParameter->string(ParametersPlugin_Parameter::EXPRESSION_ID())->value();
350     if (aName.empty()) {
351       aValues << NoValue;
352     } else
353       aValues << aExpr.c_str();
354
355     std::string aErr = aParameter->data()->string(ParametersPlugin_Parameter::EXPRESSION_ERROR_ID())->value();
356     if (aErr.empty()) {
357       AttributeDoublePtr aValueAttribute = aParam->data()->real(ModelAPI_ResultParameter::VALUE());
358       aValues << QString::number(aValueAttribute->value());
359     } else {
360       aValues << aErr.c_str();
361     }
362     aValues << aParameter->string(ParametersPlugin_Parameter::COMMENT_ID())->value().c_str();
363     aItemsList.append(aValues);
364   }
365   return aItemsList;
366 }
367
368
369 void ParametersPlugin_WidgetParamsMgr::onDoubleClick(const QModelIndex& theIndex)
370 {
371   if (myDelegate->isEditable(theIndex)) {
372     myTable->setCurrentIndex(theIndex);
373     myTable->edit(theIndex);
374   }
375 }
376
377 void ParametersPlugin_WidgetParamsMgr::onCloseEditor(QWidget* theEditor, 
378                                                      QAbstractItemDelegate::EndEditHint theHint)
379 {
380   FeaturePtr aFeature = myParametersList.at(myDelegate->editIndex().row());
381   QTreeWidgetItem* aItem = myParameters->child(myDelegate->editIndex().row());
382   int aColumn = myDelegate->editIndex().column();
383   QString aText = aItem->text(aColumn);
384   bool isModified = false;
385
386   switch (aColumn) {
387   case Col_Name:
388     {
389       AttributeStringPtr aStringAttr = aFeature->string(ParametersPlugin_Parameter::VARIABLE_ID());
390       if (!aText.isEmpty()) {
391         if (hasName(aText)) {
392           myMessage = tr("Name %1 already exists.").arg(aText);
393           QTimer::singleShot(50, this, SLOT(sendWarning()));
394           return;
395         }
396         aStringAttr->setValue(aText.toStdString());
397         isModified = true;
398       } 
399     }
400     break;
401   case Col_Equation:
402     {
403       AttributeStringPtr aStringAttr = aFeature->string(ParametersPlugin_Parameter::EXPRESSION_ID());
404       if (!aText.isEmpty()) {
405         if (aText != aStringAttr->value().c_str()) {
406           aStringAttr->setValue(aText.toStdString());
407           aFeature->execute();
408           isModified = true;
409         }
410       }
411     }
412     break;
413   case Col_Comment:
414     {
415       AttributeStringPtr aStringAttr = aFeature->string(ParametersPlugin_Parameter::COMMENT_ID());
416       aStringAttr->setValue(aText.toStdString());
417       isModified = true;
418     }
419     break;
420   }
421
422   if (!isModified)
423     return;
424   Events_Loop* aLoop = Events_Loop::loop();
425   aLoop->flush(Events_Loop::eventByName(EVENT_OBJECT_CREATED));
426   aLoop->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
427   aLoop->flush(Events_Loop::eventByName(EVENT_OBJECT_DELETED));
428
429   if (aColumn == Col_Equation)
430     updateParametersPart();
431   updateFeaturesPart();
432 }
433
434 void ParametersPlugin_WidgetParamsMgr::updateItem(QTreeWidgetItem* theItem, 
435                                                   const QList<QStringList>& theFeaturesList)
436 {
437   if (theFeaturesList.count() != theItem->childCount()) {
438     if (theItem->childCount()  < theFeaturesList.count()) {
439       while (theItem->childCount() != theFeaturesList.count()) 
440         theItem->addChild(createNewItem());
441     } else {
442       while (theItem->childCount() != theFeaturesList.count()) 
443         theItem->removeChild(theItem->child(theItem->childCount() - 1));
444     }
445   }
446   int i = 0;
447   foreach(QStringList aFeature, theFeaturesList) {
448     int aCol = 0;
449     foreach(QString aText, aFeature) {
450       if (aText.length() > 0) {
451         theItem->child(i)->setText(aCol, aText);
452         theItem->child(i)->setToolTip(aCol, aText);
453       }
454       aCol++;
455     }
456     i++;
457   }
458 }
459
460 FeaturePtr ParametersPlugin_WidgetParamsMgr::createParameter() const
461 {
462   SessionPtr aMgr = ModelAPI_Session::get();
463   std::shared_ptr<ModelAPI_Document> aDoc = aMgr->activeDocument();
464
465   FeaturePtr aFeature = aDoc->addFeature(ParametersPlugin_Parameter::ID());
466   if (aFeature.get()) {
467     Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_CREATED));
468     Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
469   }
470   return aFeature;
471 }
472
473
474 QTreeWidgetItem* ParametersPlugin_WidgetParamsMgr::createNewItem() const
475 {
476   QStringList aValues;
477   aValues << NoName;
478   aValues << NoValue;
479
480   QTreeWidgetItem* aItem = new QTreeWidgetItem(aValues);
481   aItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled);
482   return aItem;
483 }
484
485
486 void ParametersPlugin_WidgetParamsMgr::onAdd()
487 {
488   FeaturePtr aFeature = createParameter();
489   if (!aFeature.get())
490     return;
491
492   myParametersList.append(aFeature);
493   updateParametersPart();    
494
495   QTreeWidgetItem* aItem = myParameters->child(myParameters->childCount() - 1);
496
497   myTable->scrollToItem(aItem);
498   myTable->setCurrentItem(aItem);
499   myTable->editItem(aItem);
500
501   enableButtons(false);
502 }
503
504 QTreeWidgetItem* ParametersPlugin_WidgetParamsMgr::selectedItem() const
505 {
506   QList<QTreeWidgetItem*> aItemsList = myTable->selectedItems();
507   if (aItemsList.count() == 0)
508     return 0;
509
510   QTreeWidgetItem* aCurrentItem = aItemsList.first();
511   if (aCurrentItem->parent() != myParameters)
512     return 0;
513
514   return aCurrentItem;
515 }
516
517
518 void ParametersPlugin_WidgetParamsMgr::onInsert()
519 {
520   QTreeWidgetItem* aCurrentItem = selectedItem();
521   if (!aCurrentItem)
522     return;
523
524   SessionPtr aMgr = ModelAPI_Session::get();
525   std::shared_ptr<ModelAPI_Document> aDoc = aMgr->activeDocument();
526
527   FeaturePtr aNewFeature = createParameter();
528   if (!aNewFeature.get())
529     return;
530
531   int aCurrentPos = myParameters->indexOfChild(aCurrentItem);
532   if (aCurrentPos == 0) {
533     aDoc->moveFeature(aNewFeature, FeaturePtr());
534   } else {
535     FeaturePtr aCurFeature = myParametersList.at(aCurrentPos - 1);
536     aDoc->moveFeature(aNewFeature, aCurFeature);
537   }
538   updateParametersFeatures();
539   updateParametersPart();
540
541   myTable->scrollToItem(aCurrentItem);
542   myTable->setCurrentItem(aCurrentItem);
543   myTable->editItem(aCurrentItem);
544 }
545
546 void ParametersPlugin_WidgetParamsMgr::onRemove()
547 {
548   QTreeWidgetItem* aCurrentItem = selectedItem();
549   if (!aCurrentItem)
550     return;
551
552   SessionPtr aMgr = ModelAPI_Session::get();
553   std::shared_ptr<ModelAPI_Document> aDoc = aMgr->activeDocument();
554
555   int aCurrentPos = myParameters->indexOfChild(aCurrentItem);
556   FeaturePtr aCurFeature = myParametersList.at(aCurrentPos);
557
558   QObjectPtrList anObjects;
559   anObjects.append(aCurFeature);
560
561   std::set<FeaturePtr> aDirectRefFeatures, aIndirectRefFeatures;
562   ModuleBase_Tools::findReferences(anObjects, aDirectRefFeatures, aIndirectRefFeatures);
563
564   bool doDeleteReferences = true;
565   if (ModuleBase_Tools::isDeleteFeatureWithReferences(anObjects, aDirectRefFeatures, 
566       aIndirectRefFeatures, this, doDeleteReferences)) {
567
568     std::set<FeaturePtr> aFeaturesToDelete;
569     if (doDeleteReferences) {
570       aFeaturesToDelete = aDirectRefFeatures;
571       aFeaturesToDelete.insert(aIndirectRefFeatures.begin(), aIndirectRefFeatures.end());
572     }
573     aDoc->removeFeature(aCurFeature);
574     std::set<FeaturePtr>::const_iterator anIt = aFeaturesToDelete.begin(),
575                                          aLast = aFeaturesToDelete.end();
576     for (; anIt != aLast; anIt++) {
577       FeaturePtr aFeature = (*anIt);
578       DocumentPtr aDoc = aFeature->document();
579       aDoc->removeFeature(aFeature);
580     }
581
582     Events_Loop::loop()->flush(Events_Loop::loop()->eventByName(EVENT_OBJECT_DELETED));
583     Events_Loop::loop()->flush(Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY));
584     updateParametersFeatures();
585     updateFeaturesPart();
586     updateParametersPart();
587   }
588 }
589
590 void ParametersPlugin_WidgetParamsMgr::onUp()
591 {
592   QTreeWidgetItem* aCurrentItem = selectedItem();
593   if (!aCurrentItem)
594     return;
595
596   int aCurrentPos = myParameters->indexOfChild(aCurrentItem);
597   if (aCurrentPos == 0)
598     return;
599   FeaturePtr aCurFeature = myParametersList.at(aCurrentPos);
600
601   SessionPtr aMgr = ModelAPI_Session::get();
602   std::shared_ptr<ModelAPI_Document> aDoc = aMgr->activeDocument();
603
604   if (aCurrentPos == 1)
605     aDoc->moveFeature(aCurFeature, FeaturePtr());
606   else
607     aDoc->moveFeature(aCurFeature, myParametersList.at(aCurrentPos - 2));
608
609
610   Events_Loop::loop()->flush(Events_Loop::loop()->eventByName(EVENT_OBJECT_UPDATED));
611   Events_Loop::loop()->flush(Events_Loop::loop()->eventByName(EVENT_OBJECT_DELETED));
612   Events_Loop::loop()->flush(Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY));
613   updateParametersFeatures();
614   updateParametersPart();
615   updateFeaturesPart();
616
617   if (aCurrentPos > 0) {
618     aCurrentItem = myParameters->child(aCurrentPos - 1);
619     myTable->setCurrentItem(aCurrentItem);
620     selectItemScroll(aCurrentItem);
621   }
622 }
623
624 void ParametersPlugin_WidgetParamsMgr::onDown()
625 {
626   QTreeWidgetItem* aCurrentItem = selectedItem();
627   if (!aCurrentItem)
628     return;
629
630   int aCurrentPos = myParameters->indexOfChild(aCurrentItem);
631   if (aCurrentPos == (myParametersList.count() - 1))
632     return;
633   FeaturePtr aCurFeature = myParametersList.at(aCurrentPos);
634
635   SessionPtr aMgr = ModelAPI_Session::get();
636   std::shared_ptr<ModelAPI_Document> aDoc = aMgr->activeDocument();
637   aDoc->moveFeature(aCurFeature, myParametersList.at(aCurrentPos + 1));
638
639   Events_Loop::loop()->flush(Events_Loop::loop()->eventByName(EVENT_OBJECT_UPDATED));
640   Events_Loop::loop()->flush(Events_Loop::loop()->eventByName(EVENT_OBJECT_DELETED));
641   Events_Loop::loop()->flush(Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY));
642   updateParametersFeatures();
643   updateParametersPart();
644   updateFeaturesPart();
645
646   if (aCurrentPos < myParameters->childCount() - 1) {
647     aCurrentItem = myParameters->child(aCurrentPos + 1);
648     myTable->setCurrentItem(aCurrentItem);
649     selectItemScroll(aCurrentItem);
650   }
651 }
652
653
654 bool ParametersPlugin_WidgetParamsMgr::hasName(const QString& theName) const
655 {
656   int aCurrent = myDelegate->editIndex().row();
657   int i = 0;
658   foreach(FeaturePtr aFeature, myParametersList) {
659     if ((i != aCurrent) && (aFeature->data()->name() == theName.toStdString()))
660       return true;
661     i++;
662   }
663   return false;
664 }
665
666 void ParametersPlugin_WidgetParamsMgr::sendWarning()
667 {
668   QMessageBox::warning(this, tr("Warning"), myMessage);
669 }
670
671 void ParametersPlugin_WidgetParamsMgr::onSelectionChanged()
672 {
673   bool isValid = checkIsValid();
674   if (isValid) {
675     QList<QTreeWidgetItem*> aItemsList = myTable->selectedItems();
676     bool isParameter = false;
677     foreach(QTreeWidgetItem* aItem, aItemsList) {
678       if (aItem->parent() == myParameters) {
679         isParameter = true;
680         break;
681       }
682     }
683     myInsertBtn->setEnabled(isParameter);
684     myRemoveBtn->setEnabled(isParameter);
685     myUpBtn->setEnabled(isParameter);
686     myDownBtn->setEnabled(isParameter);
687   } else {
688     myInsertBtn->setEnabled(false);
689     myRemoveBtn->setEnabled(false);
690     myUpBtn->setEnabled(false);
691     myDownBtn->setEnabled(false);
692   }
693 }
694
695 void ParametersPlugin_WidgetParamsMgr::enableButtons(bool theEnable)
696 {
697   myAddBtn->setEnabled(theEnable);
698   if (theEnable) 
699     onSelectionChanged();
700   else {
701     myInsertBtn->setEnabled(theEnable);
702     myRemoveBtn->setEnabled(theEnable);
703     myUpBtn->setEnabled(theEnable);
704     myDownBtn->setEnabled(theEnable);
705   }
706 }
707
708 bool ParametersPlugin_WidgetParamsMgr::checkIsValid()
709 {
710   QTreeWidgetItem* aItem;
711   bool aIsValid = true;
712   for(int i = 0; i < myParameters->childCount(); i++) {
713     aItem = myParameters->child(i);
714     if ((aItem->text(Col_Name) == NoName) || (aItem->text(Col_Equation) == NoValue)) {
715       aIsValid = false;
716       break;
717     }
718   }
719   return aIsValid;
720 }
721