Salome HOME
Update copyrights
[modules/shaper.git] / src / ParametersPlugin / ParametersPlugin_WidgetParamsMgr.cpp
1 // Copyright (C) 2014-2019  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 email : webmaster.salome@opencascade.com
18 //
19
20 #include "ParametersPlugin_WidgetParamsMgr.h"
21 #include "ParametersPlugin_Parameter.h"
22 #include "ParametersPlugin_Validators.h"
23
24 #include <Events_InfoMessage.h>
25
26 #include <ModelAPI_ResultParameter.h>
27 #include <ModelAPI_AttributeString.h>
28 #include <ModelAPI_AttributeRefList.h>
29 #include <ModelAPI_AttributeDouble.h>
30 #include <ModelAPI_AttributeInteger.h>
31 #include <ModelAPI_Events.h>
32 #include <ModelAPI_Session.h>
33 #include <ModelAPI_Tools.h>
34 #include <ModelAPI_Expression.h>
35
36 #include <ModuleBase_Tools.h>
37
38 #include <Events_Loop.h>
39
40 #include <QLayout>
41 #include <QPushButton>
42 #include <QToolButton>
43 #include <QStyledItemDelegate>
44 #include <QPainter>
45 #include <QMessageBox>
46 #include <QTimer>
47 #include <QEvent>
48 #include <QKeyEvent>
49 #include <QDialogButtonBox>
50
51 enum ColumnType {
52   Col_Name,
53   Col_Equation,
54   Col_Result,
55   Col_Comment
56 };
57
58 const char* NoName = "<NoName>";
59 const char* NoValue = "<NoValue>";
60 const char* NotValid = "<NotValid>";
61
62 /*!
63  * \ingroup GUI
64  * ItemDelegate object in order to redefine items behavior
65  */
66 class ParametersPlugin_ItemDelegate : public QStyledItemDelegate
67 {
68 public:
69   /// Constructor
70   /// \param thaParent a parent
71   ParametersPlugin_ItemDelegate(QObject* thaParent) :
72       QStyledItemDelegate(thaParent) {}
73
74   /// Redefinition of virtual method
75   /// \param painter a painter object
76   /// \param option the item options
77   /// \param index the current index
78   virtual void paint(QPainter* painter,
79     const QStyleOptionViewItem& option,
80     const QModelIndex& index ) const;
81
82   /// Redefinition of virtual method
83   /// \param parent a parent widget
84   /// \param option the item options
85   /// \param index the current index
86   virtual QWidget* createEditor(QWidget* parent,
87                                 const QStyleOptionViewItem& option,
88                                 const QModelIndex& index) const;
89
90   /// Returns True if the given index is editable item
91   /// \param theIndex an item index
92   bool isEditable(const QModelIndex& theIndex) const;
93
94   /// Returns currently editing index
95   QModelIndex editIndex() const { return myEditingIdx; }
96
97 private:
98   mutable QModelIndex myEditingIdx;
99 };
100
101 bool ParametersPlugin_ItemDelegate::isEditable(const QModelIndex& theIndex) const
102 {
103   QModelIndex aParent = theIndex.parent();
104   if (aParent.isValid() && (aParent.row() == 0)) {
105     if (theIndex.column() == 2)
106       return false;
107   } else
108     return false;
109   return true;
110 }
111
112 void ParametersPlugin_ItemDelegate::paint(QPainter* painter,
113                                           const QStyleOptionViewItem& option,
114                                           const QModelIndex& index ) const
115 {
116   QBrush aBrush = painter->brush();
117   QPen aPen = painter->pen();
118   //if (!isEditable(index))
119   //  painter->setBrush(Qt::lightGray);
120   if (!index.parent().isValid())
121     painter->setBrush(Qt::lightGray);
122
123   painter->setPen(Qt::lightGray);
124   painter->drawRect(option.rect);
125   painter->setPen(aPen);
126
127   QStyledItemDelegate::paint(painter, option, index);
128   painter->setBrush(aBrush);
129 }
130
131 QWidget* ParametersPlugin_ItemDelegate::createEditor(QWidget* parent,
132                                                      const QStyleOptionViewItem& option,
133                                                      const QModelIndex& index) const
134 {
135   myEditingIdx = index;
136   return QStyledItemDelegate::createEditor(parent, option, index);
137 }
138
139 /////////////////////////////////////////////////////////////////////////////////////////////////
140 void ParametersPlugin_TreeWidget::closeEditor(QWidget* theEditor,
141                                               QAbstractItemDelegate::EndEditHint theHint)
142 {
143   if (theHint == QAbstractItemDelegate::EditNextItem) {
144     QModelIndex aCurrent = currentIndex();
145     QModelIndex aParent = model()->index(0, 0);
146     int aNbRows = model()->rowCount(aParent);
147     QModelIndex aIdx;
148     switch (aCurrent.column()) {
149     case 0:
150       aIdx = model()->index(aCurrent.row(), 1, aParent);
151       break;
152     case 1:
153       if (aCurrent.row() < (aNbRows - 1))
154         aIdx = model()->index(aCurrent.row() + 1, 0, aParent);
155       else {
156         QTreeWidget::closeEditor(theEditor, QAbstractItemDelegate::NoHint);
157         return;
158       }
159       break;
160     case 3:
161       QTreeWidget::closeEditor(theEditor, theHint);
162       return;
163     }
164     if (aIdx.isValid()) {
165       QTreeWidget::closeEditor(theEditor, QAbstractItemDelegate::NoHint);
166       setCurrentIndex(aIdx);
167       edit(aIdx);
168       return;
169     }
170   }
171   QTreeWidget::closeEditor(theEditor, theHint);
172 }
173
174 /////////////////////////////////////////////////////////////////////////////////////////////////
175
176 ParametersPlugin_WidgetParamsMgr::ParametersPlugin_WidgetParamsMgr(QWidget* theParent,
177   const Config_WidgetAPI* theData)
178   : ModuleBase_ModelDialogWidget(theParent, theData),
179   isUpplyBlocked(false)
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 void ParametersPlugin_WidgetParamsMgr::setDialogButtons(QDialogButtonBox* theButtons)
252 {
253   ModuleBase_ModelDialogWidget::setDialogButtons(theButtons);
254
255   QWidget* aBtnParentWgt = myOkCancelBtn->parentWidget();
256   QHBoxLayout* aBtnParentLayout = dynamic_cast<QHBoxLayout*>(aBtnParentWgt->layout());
257
258   QPushButton* aPreviewBtn = new QPushButton(tr("See preview"), aBtnParentWgt);
259   aBtnParentLayout->insertWidget(0, aPreviewBtn);
260   aBtnParentLayout->insertStretch(1, 1);
261   connect(aPreviewBtn, SIGNAL(clicked(bool)), SLOT(onShowPreview()));
262 }
263
264
265 QList<QWidget*> ParametersPlugin_WidgetParamsMgr::getControls() const
266 {
267   QList<QWidget*> aList;
268
269   return aList;
270 }
271
272 void ParametersPlugin_WidgetParamsMgr::selectItemScroll(QTreeWidgetItem* aItem)
273 {
274   myTable->clearSelection();
275   QModelIndex aParent = myTable->model()->index(0, 0);
276   int aChildIdx = myParameters->indexOfChild(aItem);
277   QModelIndex aIndex = myTable->model()->index(aChildIdx, Col_Name, aParent);
278   myTable->selectionModel()->select(aIndex,
279     QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows);
280   myTable->scrollToItem(aItem);
281 }
282
283
284 bool ParametersPlugin_WidgetParamsMgr::storeValueCustom()
285 {
286   ParametersPlugin_ExpressionValidator aValidator;
287   std::list<std::string> aArgs;
288   std::string aAttrId = ParametersPlugin_Parameter::VARIABLE_ID();
289   Events_InfoMessage aErr;
290   int aId = 0;
291   foreach(FeaturePtr aFeature, myParametersList) {
292     if (!aValidator.isValid(aFeature->attribute(aAttrId), aArgs, aErr)) {
293       // TODO(spo): translate
294       QMessageBox::warning(this, tr("Warning"), aErr.messageString().c_str());
295       selectItemScroll(myParameters->child(aId));
296       return false;
297     }
298     aId++;
299   }
300   // #2813 : make the current feature the latest in the document
301   std::list<FeaturePtr> allFeatures = myFeature->document()->allFeatures();
302   if (!allFeatures.empty()) {
303     myFeature->document()->setCurrentFeature(*(allFeatures.rbegin()), true);
304   }
305   return true;
306 }
307
308 bool ParametersPlugin_WidgetParamsMgr::restoreValueCustom()
309 {
310   return true;
311 }
312
313 void ParametersPlugin_WidgetParamsMgr::activateCustom()
314 {
315   updateParametersFeatures();
316   updateParametersPart();
317   updateFeaturesPart();
318
319   myFeatures->setExpanded(true);
320   myParameters->setExpanded(true);
321 }
322
323 void ParametersPlugin_WidgetParamsMgr::updateParametersFeatures()
324 {
325   myParametersList.clear();
326   FeaturePtr aFeature = feature();
327   DocumentPtr aDoc = aFeature->document();
328   ObjectPtr aObj;
329   FeaturePtr aParamFeature;
330   int aNbFeatures = aDoc->numInternalFeatures();
331   for (int i = 0; i < aNbFeatures; i++) {
332     aParamFeature = aDoc->internalFeature(i);
333     if (aParamFeature && aParamFeature->getKind() == ParametersPlugin_Parameter::ID()) {
334       myParametersList.append(aParamFeature);
335     }
336   }
337 }
338
339 void ParametersPlugin_WidgetParamsMgr::updateFeaturesPart()
340 {
341   QList<FeaturePtr> aFeatureList;
342   updateItem(myFeatures, featuresItems(myParametersList, aFeatureList));
343 }
344
345 void ParametersPlugin_WidgetParamsMgr::updateParametersPart()
346 {
347   updateItem(myParameters, parametersItems(myParametersList));
348   bool aIsValid = isValid();
349   enableButtons(aIsValid);
350 }
351
352
353 QList<QStringList> ParametersPlugin_WidgetParamsMgr::
354   featuresItems(const QList<FeaturePtr>& theFeatures, QList<FeaturePtr>& theFeatureList) const
355 {
356   QList<QStringList> aItemsList;
357   ResultParameterPtr aParam;
358   foreach(FeaturePtr aParameter, theFeatures) {
359     aParam = std::dynamic_pointer_cast<ModelAPI_ResultParameter>(aParameter->firstResult());
360     const std::set<std::shared_ptr<ModelAPI_Attribute>>& aRefs = aParam->data()->refsToMe();
361     std::set<std::shared_ptr<ModelAPI_Attribute> >::const_iterator aIt;
362     for(aIt = aRefs.cbegin(); aIt != aRefs.cend(); aIt++) {
363       std::shared_ptr<ModelAPI_Attribute> aAttr = (*aIt);
364       FeaturePtr aReferenced = std::dynamic_pointer_cast<ModelAPI_Feature>(aAttr->owner());
365       if (aReferenced.get() && (aReferenced != aParameter)) {
366         if (aReferenced->getKind() == ParametersPlugin_Parameter::ID()) {
367           // Find referenced feature Recursive
368           QList<FeaturePtr> aList;
369           aList.append(aReferenced);
370           QList<QStringList> aItems = featuresItems(aList, theFeatureList);
371           aItemsList.append(aItems);
372         } else {
373           if (!theFeatureList.contains(aReferenced)) {
374             QStringList aValNames;
375             aValNames << aReferenced->data()->name().c_str();
376
377             AttributeDoublePtr aDouble =
378               std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(aAttr);
379             if (aDouble.get()) {
380               aValNames << aDouble->text().c_str();
381               aValNames << QString::number(aDouble->value());
382             } else {
383               AttributeIntegerPtr aInt =
384                 std::dynamic_pointer_cast<ModelAPI_AttributeInteger>(aAttr);
385               if (aInt.get()) {
386                 aValNames << aInt->text().c_str();
387                 aValNames << QString::number(aInt->value());
388               }
389             }
390             aItemsList.append(aValNames);
391             theFeatureList.append(aReferenced);
392           }
393         }
394       }
395     }
396   }
397   return aItemsList;
398 }
399
400
401 QList<QStringList> ParametersPlugin_WidgetParamsMgr::
402   parametersItems(const QList<FeaturePtr>& theFeatures) const
403 {
404   std::list<std::string> aArgs;
405   std::string aErr;
406   QList<QStringList> aItemsList;
407   foreach(FeaturePtr aParameter, theFeatures) {
408     ResultPtr aParam = aParameter->firstResult();
409     QStringList aValues;
410
411     std::string aName = aParameter->string(ParametersPlugin_Parameter::VARIABLE_ID())->value();
412     if (aName.empty()) {
413       aValues << NoName;
414     } else
415       aValues << aName.c_str();
416
417     std::string aExpr = aParameter->string(ParametersPlugin_Parameter::EXPRESSION_ID())->value();
418     if (aName.empty()) {
419       aValues << NoValue;
420     } else
421       aValues << aExpr.c_str();
422
423     std::string aErr =
424       aParameter->data()->string(ParametersPlugin_Parameter::EXPRESSION_ERROR_ID())->value();
425     if (aErr.empty()) {
426       AttributeDoublePtr aValueAttribute = aParam->data()->real(ModelAPI_ResultParameter::VALUE());
427       aValues << QString::number(aValueAttribute->value());
428     } else {
429       aValues << aErr.c_str();
430     }
431     aValues << aParameter->string(ParametersPlugin_Parameter::COMMENT_ID())->value().c_str();
432     aItemsList.append(aValues);
433   }
434   return aItemsList;
435 }
436
437
438 void ParametersPlugin_WidgetParamsMgr::onDoubleClick(const QModelIndex& theIndex)
439 {
440   if (myDelegate->isEditable(theIndex)) {
441     myTable->setCurrentIndex(theIndex);
442     myTable->edit(theIndex);
443   }
444 }
445
446 void ParametersPlugin_WidgetParamsMgr::onCloseEditor(QWidget* theEditor,
447                                                      QAbstractItemDelegate::EndEditHint theHint)
448 {
449   FeaturePtr aFeature = myParametersList.at(myDelegate->editIndex().row());
450   QTreeWidgetItem* aItem = myParameters->child(myDelegate->editIndex().row());
451   int aColumn = myDelegate->editIndex().column();
452   QString aText = aItem->text(aColumn);
453   bool isModified = false;
454
455   switch (aColumn) {
456   case Col_Name:
457     {
458       AttributeStringPtr aStringAttr = aFeature->string(ParametersPlugin_Parameter::VARIABLE_ID());
459       if (!aText.isEmpty()) {
460         while (aText.indexOf(" ") != -1) {
461           aText.replace(" ", "");
462         }
463         if (hasName(aText)) {
464           myMessage = tr("Name '%1' already exists.").arg(aText);
465           QTimer::singleShot(50, this, SLOT(sendWarning()));
466           return;
467         }
468         aStringAttr->setValue(aText.toStdString());
469         isModified = true;
470       }
471     }
472     break;
473   case Col_Equation:
474     {
475       AttributeStringPtr aStringAttr =
476         aFeature->string(ParametersPlugin_Parameter::EXPRESSION_ID());
477       if (!aText.isEmpty()) {
478         if (aText != aStringAttr->value().c_str()) {
479           aStringAttr->setValue(aText.toStdString());
480           aFeature->execute();
481           isModified = true;
482         }
483       }
484     }
485     break;
486   case Col_Comment:
487     {
488       AttributeStringPtr aStringAttr = aFeature->string(ParametersPlugin_Parameter::COMMENT_ID());
489       aStringAttr->setValue(aText.toStdString());
490       isModified = true;
491     }
492     break;
493   }
494
495   if (!isModified)
496     return;
497   Events_Loop* aLoop = Events_Loop::loop();
498   aLoop->flush(Events_Loop::eventByName(EVENT_OBJECT_CREATED));
499   aLoop->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
500   aLoop->flush(Events_Loop::eventByName(EVENT_OBJECT_DELETED));
501
502   if (aColumn != Col_Comment)
503     updateParametersPart();
504   updateFeaturesPart();
505
506   onSelectionChanged();
507 }
508
509 void ParametersPlugin_WidgetParamsMgr::updateItem(QTreeWidgetItem* theItem,
510                                                   const QList<QStringList>& theFeaturesList)
511 {
512   if (theFeaturesList.count() != theItem->childCount()) {
513     if (theItem->childCount()  < theFeaturesList.count()) {
514       while (theItem->childCount() != theFeaturesList.count())
515         theItem->addChild(createNewItem(theItem));
516     } else {
517       while (theItem->childCount() != theFeaturesList.count())
518         theItem->removeChild(theItem->child(theItem->childCount() - 1));
519     }
520   }
521   int i = 0;
522   foreach(QStringList aFeature, theFeaturesList) {
523     int aCol = 0;
524     foreach(QString aText, aFeature) {
525       if (aText.length() > 0) {
526         theItem->child(i)->setText(aCol, aText);
527         theItem->child(i)->setToolTip(aCol, aText);
528       }
529       aCol++;
530     }
531     i++;
532   }
533 }
534
535 FeaturePtr ParametersPlugin_WidgetParamsMgr::createParameter() const
536 {
537   SessionPtr aMgr = ModelAPI_Session::get();
538   std::shared_ptr<ModelAPI_Document> aDoc = aMgr->activeDocument();
539
540   FeaturePtr aFeature = aDoc->addFeature(ParametersPlugin_Parameter::ID());
541   if (aFeature.get()) {
542     Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_CREATED));
543     Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
544   }
545   return aFeature;
546 }
547
548
549 QTreeWidgetItem* ParametersPlugin_WidgetParamsMgr::createNewItem(QTreeWidgetItem* theParent) const
550 {
551   QStringList aValues;
552   aValues << NoName;
553   aValues << NoValue;
554
555   QTreeWidgetItem* aItem = new QTreeWidgetItem(aValues);
556   if (theParent == myParameters) {
557     aItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled);
558     aItem->setForeground(2, Qt::darkGray);
559   } else
560     aItem->setFlags(Qt::NoItemFlags);
561   return aItem;
562 }
563
564
565 void ParametersPlugin_WidgetParamsMgr::onAdd()
566 {
567   FeaturePtr aFeature = createParameter();
568   if (!aFeature.get())
569     return;
570
571   myParametersList.append(aFeature);
572   updateParametersPart();
573
574   QTreeWidgetItem* aItem = myParameters->child(myParameters->childCount() - 1);
575
576   myTable->scrollToItem(aItem);
577   myTable->setCurrentItem(aItem);
578   myTable->editItem(aItem);
579
580   enableButtons(false);
581 }
582
583 QTreeWidgetItem* ParametersPlugin_WidgetParamsMgr::selectedItem() const
584 {
585   QList<QTreeWidgetItem*> aItemsList = myTable->selectedItems();
586   if (aItemsList.count() == 0)
587     return 0;
588
589   QTreeWidgetItem* aCurrentItem = aItemsList.first();
590   if (aCurrentItem->parent() != myParameters)
591     return 0;
592
593   return aCurrentItem;
594 }
595
596
597 void ParametersPlugin_WidgetParamsMgr::onInsert()
598 {
599   QTreeWidgetItem* aCurrentItem = selectedItem();
600   if (!aCurrentItem)
601     return;
602
603   SessionPtr aMgr = ModelAPI_Session::get();
604   std::shared_ptr<ModelAPI_Document> aDoc = aMgr->activeDocument();
605
606   FeaturePtr aNewFeature = createParameter();
607   if (!aNewFeature.get())
608     return;
609
610   int aCurrentPos = myParameters->indexOfChild(aCurrentItem);
611   if (aCurrentPos == 0) {
612     aDoc->moveFeature(aNewFeature, FeaturePtr());
613   } else {
614     FeaturePtr aCurFeature = myParametersList.at(aCurrentPos - 1);
615     aDoc->moveFeature(aNewFeature, aCurFeature);
616   }
617   updateParametersFeatures();
618   updateParametersPart();
619
620   myTable->scrollToItem(aCurrentItem);
621   myTable->setCurrentItem(aCurrentItem);
622   myTable->editItem(aCurrentItem);
623 }
624
625 void ParametersPlugin_WidgetParamsMgr::onRemove()
626 {
627   QTreeWidgetItem* aCurrentItem = selectedItem();
628   if (!aCurrentItem)
629     return;
630
631   SessionPtr aMgr = ModelAPI_Session::get();
632   std::shared_ptr<ModelAPI_Document> aDoc = aMgr->activeDocument();
633
634   int aCurrentPos = myParameters->indexOfChild(aCurrentItem);
635   FeaturePtr aCurFeature = myParametersList.at(aCurrentPos);
636
637   QObjectPtrList anObjects;
638   anObjects.append(aCurFeature);
639
640   std::map<FeaturePtr, std::set<FeaturePtr> > aReferences;
641   std::set<FeaturePtr> aFeatures;
642   ModuleBase_Tools::convertToFeatures(anObjects, aFeatures);
643   ModelAPI_Tools::findAllReferences(aFeatures, aReferences);
644
645   std::set<FeaturePtr> aFeatureRefsToDelete;
646   if (ModuleBase_Tools::askToDelete(aFeatures, aReferences, this, aFeatureRefsToDelete)) {
647     if (!aFeatureRefsToDelete.empty())
648       aFeatures.insert(aFeatureRefsToDelete.begin(), aFeatureRefsToDelete.end());
649     ModelAPI_Tools::removeFeatures(aFeatures, false);
650
651     Events_Loop::loop()->flush(Events_Loop::loop()->eventByName(EVENT_OBJECT_DELETED));
652     Events_Loop::loop()->flush(Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY));
653     updateParametersFeatures();
654     updateFeaturesPart();
655     updateParametersPart();
656   }
657 }
658
659 void ParametersPlugin_WidgetParamsMgr::onUp()
660 {
661   QTreeWidgetItem* aCurrentItem = selectedItem();
662   if (!aCurrentItem)
663     return;
664
665   int aCurrentPos = myParameters->indexOfChild(aCurrentItem);
666   if (aCurrentPos == 0)
667     return;
668   FeaturePtr aCurFeature = myParametersList.at(aCurrentPos);
669
670   SessionPtr aMgr = ModelAPI_Session::get();
671   std::shared_ptr<ModelAPI_Document> aDoc = aMgr->activeDocument();
672
673   if (aCurrentPos == 1)
674     aDoc->moveFeature(aCurFeature, FeaturePtr());
675   else
676     aDoc->moveFeature(aCurFeature, myParametersList.at(aCurrentPos - 2));
677
678   // add the updated also the feature that goes down
679   Events_Loop::loop()->flush(Events_Loop::loop()->eventByName(EVENT_OBJECT_CREATED));
680   static Events_ID EVENT_UPD = Events_Loop::loop()->eventByName(EVENT_OBJECT_UPDATED);
681   ModelAPI_EventCreator::get()->sendUpdated(myParametersList.at(aCurrentPos - 1), EVENT_UPD);
682   Events_Loop::loop()->flush(EVENT_UPD);
683   Events_Loop::loop()->flush(Events_Loop::loop()->eventByName(EVENT_OBJECT_CREATED));
684   Events_Loop::loop()->flush(Events_Loop::loop()->eventByName(EVENT_OBJECT_DELETED));
685   Events_Loop::loop()->flush(Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY));
686   updateParametersFeatures();
687   updateParametersPart();
688   updateFeaturesPart();
689
690   if (aCurrentPos > 0) {
691     aCurrentItem = myParameters->child(aCurrentPos - 1);
692     myTable->setCurrentItem(aCurrentItem);
693     selectItemScroll(aCurrentItem);
694   }
695 }
696
697 void ParametersPlugin_WidgetParamsMgr::onDown()
698 {
699   QTreeWidgetItem* aCurrentItem = selectedItem();
700   if (!aCurrentItem)
701     return;
702
703   int aCurrentPos = myParameters->indexOfChild(aCurrentItem);
704   if (aCurrentPos == (myParametersList.count() - 1))
705     return;
706   FeaturePtr aCurFeature = myParametersList.at(aCurrentPos);
707
708   SessionPtr aMgr = ModelAPI_Session::get();
709   std::shared_ptr<ModelAPI_Document> aDoc = aMgr->activeDocument();
710   aDoc->moveFeature(aCurFeature, myParametersList.at(aCurrentPos + 1));
711   // add the updated also the feature that goes up
712   static Events_ID EVENT_UPD = Events_Loop::loop()->eventByName(EVENT_OBJECT_UPDATED);
713   ModelAPI_EventCreator::get()->sendUpdated(myParametersList.at(aCurrentPos + 1), EVENT_UPD);
714
715   Events_Loop::loop()->flush(Events_Loop::loop()->eventByName(EVENT_OBJECT_CREATED));
716   Events_Loop::loop()->flush(Events_Loop::loop()->eventByName(EVENT_OBJECT_UPDATED));
717   Events_Loop::loop()->flush(Events_Loop::loop()->eventByName(EVENT_OBJECT_CREATED));
718   Events_Loop::loop()->flush(Events_Loop::loop()->eventByName(EVENT_OBJECT_DELETED));
719   Events_Loop::loop()->flush(Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY));
720   updateParametersFeatures();
721   updateParametersPart();
722   updateFeaturesPart();
723
724   if (aCurrentPos < myParameters->childCount() - 1) {
725     aCurrentItem = myParameters->child(aCurrentPos + 1);
726     myTable->setCurrentItem(aCurrentItem);
727     selectItemScroll(aCurrentItem);
728   }
729 }
730
731
732 bool ParametersPlugin_WidgetParamsMgr::hasName(const QString& theName) const
733 {
734   int aCurrent = myDelegate->editIndex().row();
735   int i = 0;
736   foreach(FeaturePtr aFeature, myParametersList) {
737     if ((i != aCurrent) && (aFeature->data()->name() == theName.toStdString()))
738       return true;
739     i++;
740   }
741   return false;
742 }
743
744 void ParametersPlugin_WidgetParamsMgr::sendWarning()
745 {
746   QMessageBox::warning(this, tr("Warning"), myMessage);
747   QTreeWidgetItem* aItem = myTable->currentItem();
748   if (aItem)
749     myTable->editItem(aItem);
750 }
751
752 void ParametersPlugin_WidgetParamsMgr::onSelectionChanged()
753 {
754   QList<QTreeWidgetItem*> aItemsList = myTable->selectedItems();
755   bool aIsValid = isValid();
756   if (aIsValid) {
757     bool isParameter = false;
758     foreach(QTreeWidgetItem* aItem, aItemsList) {
759       if (aItem->parent() == myParameters) {
760         isParameter = true;
761         break;
762       }
763     }
764     myInsertBtn->setEnabled(isParameter);
765     //myRemoveBtn->setEnabled(isParameter);
766     myUpBtn->setEnabled(isParameter);
767     myDownBtn->setEnabled(isParameter);
768   } else {
769     myInsertBtn->setEnabled(false);
770     //myRemoveBtn->setEnabled(false);
771     myUpBtn->setEnabled(false);
772     myDownBtn->setEnabled(false);
773   }
774   myRemoveBtn->setEnabled(!aItemsList.isEmpty());
775 }
776
777 void ParametersPlugin_WidgetParamsMgr::enableButtons(bool theEnable)
778 {
779   myAddBtn->setEnabled(theEnable);
780   if (theEnable)
781     onSelectionChanged();
782   else {
783     myInsertBtn->setEnabled(theEnable);
784     //myRemoveBtn->setEnabled(theEnable);
785     myUpBtn->setEnabled(theEnable);
786     myDownBtn->setEnabled(theEnable);
787   }
788   myOkCancelBtn->button(QDialogButtonBox::Ok)->setEnabled(theEnable);
789 }
790
791 bool ParametersPlugin_WidgetParamsMgr::isValid()
792 {
793   QTreeWidgetItem* aItem;
794   for(int i = 0; i < myParameters->childCount(); i++) {
795     aItem = myParameters->child(i);
796     if ((aItem->text(Col_Name) == NoName) ||
797         (aItem->text(Col_Equation) == NoValue) ||
798         (!ModelAPI_Expression::isVariable(aItem->text(Col_Name).toStdString())) ) {
799       return false;
800     }
801   }
802   return true;
803 }
804
805 void ParametersPlugin_WidgetParamsMgr::showEvent(QShowEvent* theEvent)
806 {
807   ModuleBase_ModelDialogWidget::showEvent(theEvent);
808   SessionPtr aMgr = ModelAPI_Session::get();
809   isUpplyBlocked = aMgr->isAutoUpdateBlocked();
810   aMgr->blockAutoUpdate(true);
811   Events_Loop* aLoop = Events_Loop::loop();
812   aLoop->flush(aLoop->eventByName(EVENT_AUTOMATIC_RECOMPUTATION_DISABLE));
813 }
814
815 void ParametersPlugin_WidgetParamsMgr::hideEvent(QHideEvent* theEvent)
816 {
817   ModuleBase_ModelDialogWidget::hideEvent(theEvent);
818   SessionPtr aMgr = ModelAPI_Session::get();
819   aMgr->blockAutoUpdate(isUpplyBlocked);
820 }
821
822 void ParametersPlugin_WidgetParamsMgr::onShowPreview()
823 {
824   SessionPtr aMgr = ModelAPI_Session::get();
825   aMgr->blockAutoUpdate(false);
826   aMgr->blockAutoUpdate(true);
827 }