Salome HOME
Merge branch 'Dev_0.6.1' of newgeom:newgeom into Dev_0.6.1
[modules/shaper.git] / src / ModuleBase / ModuleBase_WidgetMultiSelector.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
2
3 /*
4  * ModuleBase_WidgetMultiSelector.cpp
5  *
6  *  Created on: Aug 28, 2014
7  *      Author: sbh
8  */
9
10 #include <ModuleBase_WidgetMultiSelector.h>
11 #include <ModuleBase_WidgetShapeSelector.h>
12 #include <ModuleBase_ISelection.h>
13 #include <ModuleBase_IWorkshop.h>
14 #include <ModuleBase_Tools.h>
15
16 #include <ModelAPI_Data.h>
17 #include <ModelAPI_Object.h>
18
19 #include <Config_WidgetAPI.h>
20
21 #include <QGridLayout>
22 #include <QLabel>
23 #include <QListWidget>
24 #include <QObject>
25 #include <QString>
26 #include <QComboBox>
27 #include <QEvent>
28
29 #include <memory>
30 #include <string>
31
32 ModuleBase_WidgetMultiSelector::ModuleBase_WidgetMultiSelector(QWidget* theParent,
33                                                                ModuleBase_IWorkshop* theWorkshop,
34                                                                const Config_WidgetAPI* theData,
35                                                                const std::string& theParentId)
36     : ModuleBase_ModelWidget(theParent, theData, theParentId),
37       myWorkshop(theWorkshop), myIsActive(false), myUseSubShapes(false)
38 {
39   myMainWidget = new QWidget(theParent);
40   QGridLayout* aMainLay = new QGridLayout(myMainWidget);
41   ModuleBase_Tools::adjustMargins(aMainLay);
42
43   QLabel* aTypeLabel = new QLabel(tr("Type"), myMainWidget);
44   aMainLay->addWidget(aTypeLabel, 0, 0);
45
46   myTypeCombo = new QComboBox(myMainWidget);
47   // There is no sence to paramerize list of types while we can not parametrize selection mode
48   QString aTypesStr("Vertices Edges Faces Solids");
49   QStringList aShapeTypes = aTypesStr.split(' ');
50   myTypeCombo->addItems(aShapeTypes);
51   aMainLay->addWidget(myTypeCombo, 0, 1);
52
53   QLabel* aListLabel = new QLabel(tr("Selected objects:"), myMainWidget);
54   aMainLay->addWidget(aListLabel, 1, 0, 1, -1);
55
56   myListControl = new QListWidget(myMainWidget);
57   aMainLay->addWidget(myListControl, 2, 0, 2, -1);
58   aMainLay->setRowStretch(2, 1);
59   aMainLay->addWidget(new QLabel(myMainWidget));
60   aMainLay->setRowMinimumHeight(3, 20);
61   myMainWidget->setLayout(aMainLay);
62   //TODO: Move into the base class
63   myUseSubShapes = theData->getBooleanAttribute("use_subshapes", false);
64   //TODO_END
65   connect(myTypeCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(onSelectionTypeChanged()));
66
67   activateSelection(true);
68 }
69
70 ModuleBase_WidgetMultiSelector::~ModuleBase_WidgetMultiSelector()
71 {
72   activateSelection(false);
73 }
74
75 //********************************************************************
76 bool ModuleBase_WidgetMultiSelector::storeValue() const
77 {
78   // A rare case when plugin was not loaded. 
79   if(!myFeature)
80     return false;
81   DataPtr aData = myFeature->data();
82   AttributeSelectionListPtr aSelectionListAttr = 
83     std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(aData->attribute(attributeID()));
84
85   if (aSelectionListAttr) {
86     aSelectionListAttr->clear();
87     // Store shapes type
88     TopAbs_ShapeEnum aCurrentType =
89           ModuleBase_WidgetShapeSelector::shapeType(myTypeCombo->currentText());
90     aSelectionListAttr->setSelectionType((int) aCurrentType);
91     // Store selection in the attribute
92     foreach (GeomSelection aSelec, mySelection) {
93       aSelectionListAttr->append(aSelec.first, aSelec.second);
94     }
95     //updateSelectionList(aSelectionListAttr);
96     updateObject(myFeature);
97     return true;
98   }
99   return false;
100 }
101
102 //********************************************************************
103 bool ModuleBase_WidgetMultiSelector::restoreValue()
104 {
105   // A rare case when plugin was not loaded. 
106   if(!myFeature)
107     return false;
108   DataPtr aData = myFeature->data();
109   AttributeSelectionListPtr aSelectionListAttr = 
110     std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(aData->attribute(attributeID()));
111
112   if (aSelectionListAttr) {
113     mySelection.clear();
114     // Restore shape type
115     TopAbs_ShapeEnum aShapeType = (TopAbs_ShapeEnum) aSelectionListAttr->selectionType();
116     setCurrentShapeType(aShapeType);
117     // Restore selection in the list
118     for (int i = 0; i < aSelectionListAttr->size(); i++) {
119       AttributeSelectionPtr aSelectAttr = aSelectionListAttr->value(i);
120       mySelection.append(GeomSelection(aSelectAttr->context(), aSelectAttr->value()));
121     }
122     updateSelectionList(aSelectionListAttr);
123     return true;
124   }
125   return false;
126 }
127
128 //********************************************************************
129 QWidget* ModuleBase_WidgetMultiSelector::getControl() const
130 {
131   return myMainWidget;
132 }
133
134 //********************************************************************
135 QList<QWidget*> ModuleBase_WidgetMultiSelector::getControls() const
136 {
137   QList<QWidget*> result;
138   //result << myTypeCombo;
139   result << myListControl;
140   return result;
141 }
142
143 //********************************************************************
144 bool ModuleBase_WidgetMultiSelector::eventFilter(QObject* theObj, QEvent* theEvent)
145 {
146   //TODO: Remove maybe?
147   return ModuleBase_ModelWidget::eventFilter(theObj, theEvent);
148 }
149
150 //********************************************************************
151 void ModuleBase_WidgetMultiSelector::activateSelection(bool toActivate)
152 {
153   myIsActive = toActivate;
154   if (myIsActive) {
155     connect(myWorkshop, SIGNAL(selectionChanged()), 
156             this,       SLOT(onSelectionChanged()), 
157             Qt::UniqueConnection);
158     activateShapeSelection();
159   } else {
160     disconnect(myWorkshop, SIGNAL(selectionChanged()), this, SLOT(onSelectionChanged()));
161     myWorkshop->deactivateSubShapesSelection();
162   }
163 }
164
165 //********************************************************************
166 void ModuleBase_WidgetMultiSelector::onSelectionTypeChanged()
167 {
168   activateShapeSelection();
169   QObjectPtrList anEmptyList;
170   myWorkshop->setSelected(anEmptyList);
171   // Clear mySelection, myListControl and storeValue()
172   onSelectionChanged();
173 }
174
175 //********************************************************************
176 void ModuleBase_WidgetMultiSelector::onSelectionChanged()
177 {
178   ModuleBase_ISelection* aSelection = myWorkshop->selection();
179   NCollection_List<TopoDS_Shape> aSelectedShapes; //, aFilteredShapes;
180   std::list<ObjectPtr> aOwnersList;
181   aSelection->selectedShapes(aSelectedShapes, aOwnersList);
182
183   mySelection.clear();
184   std::list<ObjectPtr>::const_iterator aIt;
185   NCollection_List<TopoDS_Shape>::Iterator aShpIt(aSelectedShapes);
186   GeomShapePtr aShape;
187   for (aIt = aOwnersList.cbegin(); aIt != aOwnersList.cend(); aShpIt.Next(), aIt++) {
188     ResultPtr aResult = std::dynamic_pointer_cast<ModelAPI_Result>(*aIt);
189     if (myFeature) {
190       // We can not select a result of our feature
191       const std::list<ResultPtr>& aResList = myFeature->results();
192       std::list<ResultPtr>::const_iterator aIt;
193       bool isSkipSelf = false;
194       for (aIt = aResList.cbegin(); aIt != aResList.cend(); ++aIt) {
195         if ((*aIt) == aResult) {
196           isSkipSelf = true;
197           break;
198         }
199       }
200       if(isSkipSelf)
201         continue;
202     }
203     aShape = std::shared_ptr<GeomAPI_Shape>(new GeomAPI_Shape());
204     aShape->setImpl(new TopoDS_Shape(aShpIt.Value()));
205     mySelection.append(GeomSelection(aResult, aShape));
206   }
207   //updateSelectionList();
208   emit valuesChanged();
209 }
210
211 //********************************************************************
212 void ModuleBase_WidgetMultiSelector::filterShapes(const NCollection_List<TopoDS_Shape>& theShapesToFilter,
213                                                   NCollection_List<TopoDS_Shape>& theResult)
214 {
215   if(myTypeCombo->count() == 0 || theShapesToFilter.IsEmpty())
216     return;
217   TopAbs_ShapeEnum aReferenceType =
218       ModuleBase_WidgetShapeSelector::shapeType(myTypeCombo->currentText());
219   NCollection_List<TopoDS_Shape>::Iterator anIter(theShapesToFilter);
220   for (; anIter.More(); anIter.Next()) {
221     TopoDS_Shape aShape = anIter.Value();
222     if (aShape.IsNull() || aShape.ShapeType() != aReferenceType)
223       continue;
224     theResult.Append(aShape);
225   }
226 }
227
228 //********************************************************************
229 void ModuleBase_WidgetMultiSelector::setCurrentShapeType(const TopAbs_ShapeEnum theShapeType)
230 {
231   QString aShapeTypeName;
232   
233   for (int idx = 0; idx < myTypeCombo->count(); ++idx) {
234     aShapeTypeName = myTypeCombo->itemText(idx);
235     TopAbs_ShapeEnum aRefType = ModuleBase_WidgetShapeSelector::shapeType(aShapeTypeName);
236     if(aRefType == theShapeType && idx != myTypeCombo->currentIndex()) {
237       activateSelection(false);
238       bool isBlocked = myTypeCombo->blockSignals(true);
239       myTypeCombo->setCurrentIndex(idx);
240       myTypeCombo->blockSignals(isBlocked);
241       activateSelection(true);
242       break;
243     }
244   }
245 }
246
247 void ModuleBase_WidgetMultiSelector::activateShapeSelection()
248 {
249   QString aNewType = myTypeCombo->currentText();
250   QIntList aList;
251   aList.append(ModuleBase_WidgetShapeSelector::shapeType(aNewType));
252   myWorkshop->activateSubShapesSelection(aList);
253 }
254
255 //********************************************************************
256 void ModuleBase_WidgetMultiSelector::updateSelectionList(AttributeSelectionListPtr theList)
257 {
258   myListControl->clear();
259   for (int i = 0; i < theList->size(); i++) {
260     AttributeSelectionPtr aAttr = theList->value(i);
261     myListControl->addItem(aAttr->namingName().c_str());
262   }
263 }