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