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