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