Salome HOME
Fix for the issue #2813 : Parameters : error in model update due to the desactivation...
[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   // #2813 : make the current feature the latest in the document
302   std::list<FeaturePtr> allFeatures = myFeature->document()->allFeatures();
303   if (!allFeatures.empty()) {
304     myFeature->document()->setCurrentFeature(*(allFeatures.rbegin()), true);
305   }
306   return true;
307 }
308
309 bool ParametersPlugin_WidgetParamsMgr::restoreValueCustom()
310 {
311   return true;
312 }
313
314 void ParametersPlugin_WidgetParamsMgr::activateCustom()
315 {
316   updateParametersFeatures();
317   updateParametersPart();
318   updateFeaturesPart();
319
320   myFeatures->setExpanded(true);
321   myParameters->setExpanded(true);
322 }
323
324 void ParametersPlugin_WidgetParamsMgr::updateParametersFeatures()
325 {
326   myParametersList.clear();
327   FeaturePtr aFeature = feature();
328   DocumentPtr aDoc = aFeature->document();
329   ObjectPtr aObj;
330   FeaturePtr aParamFeature;
331   int aNbFeatures = aDoc->numInternalFeatures();
332   for (int i = 0; i < aNbFeatures; i++) {
333     aParamFeature = aDoc->internalFeature(i);
334     if (aParamFeature && aParamFeature->getKind() == ParametersPlugin_Parameter::ID()) {
335       myParametersList.append(aParamFeature);
336     }
337   }
338 }
339
340 void ParametersPlugin_WidgetParamsMgr::updateFeaturesPart()
341 {
342   QList<FeaturePtr> aFeatureList;
343   updateItem(myFeatures, featuresItems(myParametersList, aFeatureList));
344 }
345
346 void ParametersPlugin_WidgetParamsMgr::updateParametersPart()
347 {
348   updateItem(myParameters, parametersItems(myParametersList));
349   bool aIsValid = isValid();
350   enableButtons(aIsValid);
351 }
352
353
354 QList<QStringList> ParametersPlugin_WidgetParamsMgr::
355   featuresItems(const QList<FeaturePtr>& theFeatures, QList<FeaturePtr>& theFeatureList) const
356 {
357   QList<QStringList> aItemsList;
358   ResultParameterPtr aParam;
359   foreach(FeaturePtr aParameter, theFeatures) {
360     aParam = std::dynamic_pointer_cast<ModelAPI_ResultParameter>(aParameter->firstResult());
361     const std::set<std::shared_ptr<ModelAPI_Attribute>>& aRefs = aParam->data()->refsToMe();
362     std::set<std::shared_ptr<ModelAPI_Attribute> >::const_iterator aIt;
363     for(aIt = aRefs.cbegin(); aIt != aRefs.cend(); aIt++) {
364       std::shared_ptr<ModelAPI_Attribute> aAttr = (*aIt);
365       FeaturePtr aReferenced = std::dynamic_pointer_cast<ModelAPI_Feature>(aAttr->owner());
366       if (aReferenced.get() && (aReferenced != aParameter)) {
367         if (aReferenced->getKind() == ParametersPlugin_Parameter::ID()) {
368           // Find referenced feature Recursive
369           QList<FeaturePtr> aList;
370           aList.append(aReferenced);
371           QList<QStringList> aItems = featuresItems(aList, theFeatureList);
372           aItemsList.append(aItems);
373         } else {
374           if (!theFeatureList.contains(aReferenced)) {
375             QStringList aValNames;
376             aValNames << aReferenced->data()->name().c_str();
377
378             AttributeDoublePtr aDouble =
379               std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(aAttr);
380             if (aDouble.get()) {
381               aValNames << aDouble->text().c_str();
382               aValNames << QString::number(aDouble->value());
383             } else {
384               AttributeIntegerPtr aInt =
385                 std::dynamic_pointer_cast<ModelAPI_AttributeInteger>(aAttr);
386               if (aInt.get()) {
387                 aValNames << aInt->text().c_str();
388                 aValNames << QString::number(aInt->value());
389               }
390             }
391             aItemsList.append(aValNames);
392             theFeatureList.append(aReferenced);
393           }
394         }
395       }
396     }
397   }
398   return aItemsList;
399 }
400
401
402 QList<QStringList> ParametersPlugin_WidgetParamsMgr::
403   parametersItems(const QList<FeaturePtr>& theFeatures) const
404 {
405   std::list<std::string> aArgs;
406   std::string aErr;
407   QList<QStringList> aItemsList;
408   foreach(FeaturePtr aParameter, theFeatures) {
409     ResultPtr aParam = aParameter->firstResult();
410     QStringList aValues;
411
412     std::string aName = aParameter->string(ParametersPlugin_Parameter::VARIABLE_ID())->value();
413     if (aName.empty()) {
414       aValues << NoName;
415     } else
416       aValues << aName.c_str();
417
418     std::string aExpr = aParameter->string(ParametersPlugin_Parameter::EXPRESSION_ID())->value();
419     if (aName.empty()) {
420       aValues << NoValue;
421     } else
422       aValues << aExpr.c_str();
423
424     std::string aErr =
425       aParameter->data()->string(ParametersPlugin_Parameter::EXPRESSION_ERROR_ID())->value();
426     if (aErr.empty()) {
427       AttributeDoublePtr aValueAttribute = aParam->data()->real(ModelAPI_ResultParameter::VALUE());
428       aValues << QString::number(aValueAttribute->value());
429     } else {
430       aValues << aErr.c_str();
431     }
432     aValues << aParameter->string(ParametersPlugin_Parameter::COMMENT_ID())->value().c_str();
433     aItemsList.append(aValues);
434   }
435   return aItemsList;
436 }
437
438
439 void ParametersPlugin_WidgetParamsMgr::onDoubleClick(const QModelIndex& theIndex)
440 {
441   if (myDelegate->isEditable(theIndex)) {
442     myTable->setCurrentIndex(theIndex);
443     myTable->edit(theIndex);
444   }
445 }
446
447 void ParametersPlugin_WidgetParamsMgr::onCloseEditor(QWidget* theEditor,
448                                                      QAbstractItemDelegate::EndEditHint theHint)
449 {
450   FeaturePtr aFeature = myParametersList.at(myDelegate->editIndex().row());
451   QTreeWidgetItem* aItem = myParameters->child(myDelegate->editIndex().row());
452   int aColumn = myDelegate->editIndex().column();
453   QString aText = aItem->text(aColumn);
454   bool isModified = false;
455
456   switch (aColumn) {
457   case Col_Name:
458     {
459       AttributeStringPtr aStringAttr = aFeature->string(ParametersPlugin_Parameter::VARIABLE_ID());
460       if (!aText.isEmpty()) {
461         while (aText.indexOf(" ") != -1) {
462           aText.replace(" ", "");
463         }
464         if (hasName(aText)) {
465           myMessage = tr("Name '%1' already exists.").arg(aText);
466           QTimer::singleShot(50, this, SLOT(sendWarning()));
467           return;
468         }
469         aStringAttr->setValue(aText.toStdString());
470         isModified = true;
471       }
472     }
473     break;
474   case Col_Equation:
475     {
476       AttributeStringPtr aStringAttr =
477         aFeature->string(ParametersPlugin_Parameter::EXPRESSION_ID());
478       if (!aText.isEmpty()) {
479         if (aText != aStringAttr->value().c_str()) {
480           aStringAttr->setValue(aText.toStdString());
481           aFeature->execute();
482           isModified = true;
483         }
484       }
485     }
486     break;
487   case Col_Comment:
488     {
489       AttributeStringPtr aStringAttr = aFeature->string(ParametersPlugin_Parameter::COMMENT_ID());
490       aStringAttr->setValue(aText.toStdString());
491       isModified = true;
492     }
493     break;
494   }
495
496   if (!isModified)
497     return;
498   Events_Loop* aLoop = Events_Loop::loop();
499   aLoop->flush(Events_Loop::eventByName(EVENT_OBJECT_CREATED));
500   aLoop->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
501   aLoop->flush(Events_Loop::eventByName(EVENT_OBJECT_DELETED));
502
503   if (aColumn != Col_Comment)
504     updateParametersPart();
505   updateFeaturesPart();
506
507   onSelectionChanged();
508 }
509
510 void ParametersPlugin_WidgetParamsMgr::updateItem(QTreeWidgetItem* theItem,
511                                                   const QList<QStringList>& theFeaturesList)
512 {
513   if (theFeaturesList.count() != theItem->childCount()) {
514     if (theItem->childCount()  < theFeaturesList.count()) {
515       while (theItem->childCount() != theFeaturesList.count())
516         theItem->addChild(createNewItem(theItem));
517     } else {
518       while (theItem->childCount() != theFeaturesList.count())
519         theItem->removeChild(theItem->child(theItem->childCount() - 1));
520     }
521   }
522   int i = 0;
523   foreach(QStringList aFeature, theFeaturesList) {
524     int aCol = 0;
525     foreach(QString aText, aFeature) {
526       if (aText.length() > 0) {
527         theItem->child(i)->setText(aCol, aText);
528         theItem->child(i)->setToolTip(aCol, aText);
529       }
530       aCol++;
531     }
532     i++;
533   }
534 }
535
536 FeaturePtr ParametersPlugin_WidgetParamsMgr::createParameter() const
537 {
538   SessionPtr aMgr = ModelAPI_Session::get();
539   std::shared_ptr<ModelAPI_Document> aDoc = aMgr->activeDocument();
540
541   FeaturePtr aFeature = aDoc->addFeature(ParametersPlugin_Parameter::ID());
542   if (aFeature.get()) {
543     Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_CREATED));
544     Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
545   }
546   return aFeature;
547 }
548
549
550 QTreeWidgetItem* ParametersPlugin_WidgetParamsMgr::createNewItem(QTreeWidgetItem* theParent) const
551 {
552   QStringList aValues;
553   aValues << NoName;
554   aValues << NoValue;
555
556   QTreeWidgetItem* aItem = new QTreeWidgetItem(aValues);
557   if (theParent == myParameters) {
558     aItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled);
559     aItem->setForeground(2, Qt::darkGray);
560   } else
561     aItem->setFlags(Qt::NoItemFlags);
562   return aItem;
563 }
564
565
566 void ParametersPlugin_WidgetParamsMgr::onAdd()
567 {
568   FeaturePtr aFeature = createParameter();
569   if (!aFeature.get())
570     return;
571
572   myParametersList.append(aFeature);
573   updateParametersPart();
574
575   QTreeWidgetItem* aItem = myParameters->child(myParameters->childCount() - 1);
576
577   myTable->scrollToItem(aItem);
578   myTable->setCurrentItem(aItem);
579   myTable->editItem(aItem);
580
581   enableButtons(false);
582 }
583
584 QTreeWidgetItem* ParametersPlugin_WidgetParamsMgr::selectedItem() const
585 {
586   QList<QTreeWidgetItem*> aItemsList = myTable->selectedItems();
587   if (aItemsList.count() == 0)
588     return 0;
589
590   QTreeWidgetItem* aCurrentItem = aItemsList.first();
591   if (aCurrentItem->parent() != myParameters)
592     return 0;
593
594   return aCurrentItem;
595 }
596
597
598 void ParametersPlugin_WidgetParamsMgr::onInsert()
599 {
600   QTreeWidgetItem* aCurrentItem = selectedItem();
601   if (!aCurrentItem)
602     return;
603
604   SessionPtr aMgr = ModelAPI_Session::get();
605   std::shared_ptr<ModelAPI_Document> aDoc = aMgr->activeDocument();
606
607   FeaturePtr aNewFeature = createParameter();
608   if (!aNewFeature.get())
609     return;
610
611   int aCurrentPos = myParameters->indexOfChild(aCurrentItem);
612   if (aCurrentPos == 0) {
613     aDoc->moveFeature(aNewFeature, FeaturePtr());
614   } else {
615     FeaturePtr aCurFeature = myParametersList.at(aCurrentPos - 1);
616     aDoc->moveFeature(aNewFeature, aCurFeature);
617   }
618   updateParametersFeatures();
619   updateParametersPart();
620
621   myTable->scrollToItem(aCurrentItem);
622   myTable->setCurrentItem(aCurrentItem);
623   myTable->editItem(aCurrentItem);
624 }
625
626 void ParametersPlugin_WidgetParamsMgr::onRemove()
627 {
628   QTreeWidgetItem* aCurrentItem = selectedItem();
629   if (!aCurrentItem)
630     return;
631
632   SessionPtr aMgr = ModelAPI_Session::get();
633   std::shared_ptr<ModelAPI_Document> aDoc = aMgr->activeDocument();
634
635   int aCurrentPos = myParameters->indexOfChild(aCurrentItem);
636   FeaturePtr aCurFeature = myParametersList.at(aCurrentPos);
637
638   QObjectPtrList anObjects;
639   anObjects.append(aCurFeature);
640
641   std::map<FeaturePtr, std::set<FeaturePtr> > aReferences;
642   std::set<FeaturePtr> aFeatures;
643   ModuleBase_Tools::convertToFeatures(anObjects, aFeatures);
644   ModelAPI_Tools::findAllReferences(aFeatures, aReferences);
645
646   std::set<FeaturePtr> aFeatureRefsToDelete;
647   if (ModuleBase_Tools::askToDelete(aFeatures, aReferences, this, aFeatureRefsToDelete)) {
648     if (!aFeatureRefsToDelete.empty())
649       aFeatures.insert(aFeatureRefsToDelete.begin(), aFeatureRefsToDelete.end());
650     ModelAPI_Tools::removeFeatures(aFeatures, false);
651
652     Events_Loop::loop()->flush(Events_Loop::loop()->eventByName(EVENT_OBJECT_DELETED));
653     Events_Loop::loop()->flush(Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY));
654     updateParametersFeatures();
655     updateFeaturesPart();
656     updateParametersPart();
657   }
658 }
659
660 void ParametersPlugin_WidgetParamsMgr::onUp()
661 {
662   QTreeWidgetItem* aCurrentItem = selectedItem();
663   if (!aCurrentItem)
664     return;
665
666   int aCurrentPos = myParameters->indexOfChild(aCurrentItem);
667   if (aCurrentPos == 0)
668     return;
669   FeaturePtr aCurFeature = myParametersList.at(aCurrentPos);
670
671   SessionPtr aMgr = ModelAPI_Session::get();
672   std::shared_ptr<ModelAPI_Document> aDoc = aMgr->activeDocument();
673
674   if (aCurrentPos == 1)
675     aDoc->moveFeature(aCurFeature, FeaturePtr());
676   else
677     aDoc->moveFeature(aCurFeature, myParametersList.at(aCurrentPos - 2));
678
679   // add the updated also the feature that goes down
680   Events_Loop::loop()->flush(Events_Loop::loop()->eventByName(EVENT_OBJECT_CREATED));
681   static Events_ID EVENT_UPD = Events_Loop::loop()->eventByName(EVENT_OBJECT_UPDATED);
682   ModelAPI_EventCreator::get()->sendUpdated(myParametersList.at(aCurrentPos - 1), EVENT_UPD);
683   Events_Loop::loop()->flush(EVENT_UPD);
684   Events_Loop::loop()->flush(Events_Loop::loop()->eventByName(EVENT_OBJECT_CREATED));
685   Events_Loop::loop()->flush(Events_Loop::loop()->eventByName(EVENT_OBJECT_DELETED));
686   Events_Loop::loop()->flush(Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY));
687   updateParametersFeatures();
688   updateParametersPart();
689   updateFeaturesPart();
690
691   if (aCurrentPos > 0) {
692     aCurrentItem = myParameters->child(aCurrentPos - 1);
693     myTable->setCurrentItem(aCurrentItem);
694     selectItemScroll(aCurrentItem);
695   }
696 }
697
698 void ParametersPlugin_WidgetParamsMgr::onDown()
699 {
700   QTreeWidgetItem* aCurrentItem = selectedItem();
701   if (!aCurrentItem)
702     return;
703
704   int aCurrentPos = myParameters->indexOfChild(aCurrentItem);
705   if (aCurrentPos == (myParametersList.count() - 1))
706     return;
707   FeaturePtr aCurFeature = myParametersList.at(aCurrentPos);
708
709   SessionPtr aMgr = ModelAPI_Session::get();
710   std::shared_ptr<ModelAPI_Document> aDoc = aMgr->activeDocument();
711   aDoc->moveFeature(aCurFeature, myParametersList.at(aCurrentPos + 1));
712   // add the updated also the feature that goes up
713   static Events_ID EVENT_UPD = Events_Loop::loop()->eventByName(EVENT_OBJECT_UPDATED);
714   ModelAPI_EventCreator::get()->sendUpdated(myParametersList.at(aCurrentPos + 1), EVENT_UPD);
715
716   Events_Loop::loop()->flush(Events_Loop::loop()->eventByName(EVENT_OBJECT_CREATED));
717   Events_Loop::loop()->flush(Events_Loop::loop()->eventByName(EVENT_OBJECT_UPDATED));
718   Events_Loop::loop()->flush(Events_Loop::loop()->eventByName(EVENT_OBJECT_CREATED));
719   Events_Loop::loop()->flush(Events_Loop::loop()->eventByName(EVENT_OBJECT_DELETED));
720   Events_Loop::loop()->flush(Events_Loop::loop()->eventByName(EVENT_OBJECT_TO_REDISPLAY));
721   updateParametersFeatures();
722   updateParametersPart();
723   updateFeaturesPart();
724
725   if (aCurrentPos < myParameters->childCount() - 1) {
726     aCurrentItem = myParameters->child(aCurrentPos + 1);
727     myTable->setCurrentItem(aCurrentItem);
728     selectItemScroll(aCurrentItem);
729   }
730 }
731
732
733 bool ParametersPlugin_WidgetParamsMgr::hasName(const QString& theName) const
734 {
735   int aCurrent = myDelegate->editIndex().row();
736   int i = 0;
737   foreach(FeaturePtr aFeature, myParametersList) {
738     if ((i != aCurrent) && (aFeature->data()->name() == theName.toStdString()))
739       return true;
740     i++;
741   }
742   return false;
743 }
744
745 void ParametersPlugin_WidgetParamsMgr::sendWarning()
746 {
747   QMessageBox::warning(this, tr("Warning"), myMessage);
748   QTreeWidgetItem* aItem = myTable->currentItem();
749   if (aItem)
750     myTable->editItem(aItem);
751 }
752
753 void ParametersPlugin_WidgetParamsMgr::onSelectionChanged()
754 {
755   QList<QTreeWidgetItem*> aItemsList = myTable->selectedItems();
756   bool aIsValid = isValid();
757   if (aIsValid) {
758     bool isParameter = false;
759     foreach(QTreeWidgetItem* aItem, aItemsList) {
760       if (aItem->parent() == myParameters) {
761         isParameter = true;
762         break;
763       }
764     }
765     myInsertBtn->setEnabled(isParameter);
766     //myRemoveBtn->setEnabled(isParameter);
767     myUpBtn->setEnabled(isParameter);
768     myDownBtn->setEnabled(isParameter);
769   } else {
770     myInsertBtn->setEnabled(false);
771     //myRemoveBtn->setEnabled(false);
772     myUpBtn->setEnabled(false);
773     myDownBtn->setEnabled(false);
774   }
775   myRemoveBtn->setEnabled(!aItemsList.isEmpty());
776 }
777
778 void ParametersPlugin_WidgetParamsMgr::enableButtons(bool theEnable)
779 {
780   myAddBtn->setEnabled(theEnable);
781   if (theEnable)
782     onSelectionChanged();
783   else {
784     myInsertBtn->setEnabled(theEnable);
785     //myRemoveBtn->setEnabled(theEnable);
786     myUpBtn->setEnabled(theEnable);
787     myDownBtn->setEnabled(theEnable);
788   }
789   myOkCancelBtn->button(QDialogButtonBox::Ok)->setEnabled(theEnable);
790 }
791
792 bool ParametersPlugin_WidgetParamsMgr::isValid()
793 {
794   QTreeWidgetItem* aItem;
795   for(int i = 0; i < myParameters->childCount(); i++) {
796     aItem = myParameters->child(i);
797     if ((aItem->text(Col_Name) == NoName) ||
798         (aItem->text(Col_Equation) == NoValue) ||
799         (!ModelAPI_Expression::isVariable(aItem->text(Col_Name).toStdString())) ) {
800       return false;
801     }
802   }
803   return true;
804 }
805
806 void ParametersPlugin_WidgetParamsMgr::showEvent(QShowEvent* theEvent)
807 {
808   ModuleBase_ModelDialogWidget::showEvent(theEvent);
809   SessionPtr aMgr = ModelAPI_Session::get();
810   isUpplyBlocked = aMgr->isAutoUpdateBlocked();
811   aMgr->blockAutoUpdate(true);
812   Events_Loop* aLoop = Events_Loop::loop();
813   aLoop->flush(aLoop->eventByName(EVENT_AUTOMATIC_RECOMPUTATION_DISABLE));
814 }
815
816 void ParametersPlugin_WidgetParamsMgr::hideEvent(QHideEvent* theEvent)
817 {
818   ModuleBase_ModelDialogWidget::hideEvent(theEvent);
819   SessionPtr aMgr = ModelAPI_Session::get();
820   aMgr->blockAutoUpdate(isUpplyBlocked);
821 }
822
823 void ParametersPlugin_WidgetParamsMgr::onShowPreview()
824 {
825   SessionPtr aMgr = ModelAPI_Session::get();
826   aMgr->blockAutoUpdate(false);
827   aMgr->blockAutoUpdate(true);
828 }