Salome HOME
Merge branch 'master' of newgeom:newgeom
[modules/shaper.git] / src / ModuleBase / ModuleBase_WidgetMultiSelector.cpp
1 /*
2  * ModuleBase_WidgetMultiSelector.cpp
3  *
4  *  Created on: Aug 28, 2014
5  *      Author: sbh
6  */
7
8 #include <ModuleBase_WidgetMultiSelector.h>
9 #include <ModuleBase_WidgetShapeSelector.h>
10 #include <ModuleBase_ISelection.h>
11 #include <ModuleBase_IWorkshop.h>
12 #include <ModuleBase_Tools.h>
13
14 #include <ModelAPI_Data.h>
15 #include <ModelAPI_Object.h>
16 #include <ModelAPI_AttributeSelectionList.h>
17
18 #include <Config_WidgetAPI.h>
19
20 #include <QGridLayout>
21 #include <QLabel>
22 #include <QListWidget>
23 #include <QObject>
24 #include <QString>
25 #include <QComboBox>
26 #include <QEvent>
27
28 #include <boost/smart_ptr/shared_ptr.hpp>
29 #include <string>
30
31 ModuleBase_WidgetMultiSelector::ModuleBase_WidgetMultiSelector(QWidget* theParent,
32                                                                ModuleBase_IWorkshop* theWorkshop,
33                                                                const Config_WidgetAPI* theData,
34                                                                const std::string& theParentId)
35     : ModuleBase_ModelWidget(theParent, theData, theParentId),
36       myWorkshop(theWorkshop), myIsActive(false), myUseSubShapes(false)
37 {
38   myMainWidget = new QWidget(theParent);
39   QGridLayout* aMainLay = new QGridLayout(myMainWidget);
40   ModuleBase_Tools::adjustMargins(aMainLay);
41
42   QLabel* aTypeLabel = new QLabel(tr("Type"), myMainWidget);
43   aMainLay->addWidget(aTypeLabel, 0, 0);
44
45   myTypeCombo = new QComboBox(myMainWidget);
46   // There is no sence to paramerize list of types while we can not parametrize selection mode
47   QString aTypesStr("Vertices Edges Faces Solids");
48   myShapeTypes = aTypesStr.split(' ');
49   myTypeCombo->addItems(myShapeTypes);
50   aMainLay->addWidget(myTypeCombo, 0, 1);
51
52   QLabel* aListLabel = new QLabel(tr("Selected objects:"), myMainWidget);
53   aMainLay->addWidget(aListLabel, 1, 0, 1, -1);
54
55   myListControl = new QListWidget(myMainWidget);
56   aMainLay->addWidget(myListControl, 2, 0, 2, -1);
57   aMainLay->setColumnStretch(1, 1);
58   myMainWidget->setLayout(aMainLay);
59
60   //TODO: Move into the base class
61   myUseSubShapes = theData->getBooleanAttribute("use_subshapes", false);
62   //TODO_END
63   connect(myTypeCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(onSelectionTypeChanged()));
64   activateSelection(true);
65 }
66
67 ModuleBase_WidgetMultiSelector::~ModuleBase_WidgetMultiSelector()
68 {
69   activateSelection(false);
70 }
71
72 //********************************************************************
73 bool ModuleBase_WidgetMultiSelector::storeValue() const
74 {
75   // A rare case when plugin was not loaded. 
76   if(!myFeature)
77     return false;
78   DataPtr aData = myFeature->data();
79   AttributeSelectionListPtr aSelectionListAttr = 
80     boost::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(aData->attribute(attributeID()));
81
82   if (aSelectionListAttr && (mySelection.size() > 0)) {
83     aSelectionListAttr->clear();
84     foreach (GeomSelection aSelec, mySelection) {
85       aSelectionListAttr->append(aSelec.first, aSelec.second);
86     }
87     updateObject(myFeature);
88     return true;
89   }
90   return false;
91 }
92
93 //********************************************************************
94 bool ModuleBase_WidgetMultiSelector::restoreValue()
95 {
96   // A rare case when plugin was not loaded. 
97   if(!myFeature)
98     return false;
99   DataPtr aData = myFeature->data();
100   AttributeSelectionListPtr aSelectionListAttr = 
101     boost::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(aData->attribute(attributeID()));
102
103   if (aSelectionListAttr) {
104     mySelection.clear();
105     for (int i = 0; i < aSelectionListAttr->size(); i++) {
106       AttributeSelectionPtr aSelectAttr = aSelectionListAttr->value(i);
107       mySelection.append(GeomSelection(aSelectAttr->context(), aSelectAttr->value()));
108     }
109     updateSelectionList();
110     return true;
111   }
112   return false;
113 }
114
115 //********************************************************************
116 QWidget* ModuleBase_WidgetMultiSelector::getControl() const
117 {
118   return myMainWidget;
119 }
120
121 //********************************************************************
122 QList<QWidget*> ModuleBase_WidgetMultiSelector::getControls() const
123 {
124   QList<QWidget*> result;
125   result << myTypeCombo;
126   result << myListControl;
127   return result;
128 }
129
130 //********************************************************************
131 bool ModuleBase_WidgetMultiSelector::eventFilter(QObject* theObj, QEvent* theEvent)
132 {
133   if (theObj == myListControl) {
134     if (theEvent->type() == QEvent::FocusIn)
135       activateSelection(true);
136   }
137   return ModuleBase_ModelWidget::eventFilter(theObj, theEvent);
138 }
139
140 //********************************************************************
141 void ModuleBase_WidgetMultiSelector::onSelectionChanged()
142 {
143   ModuleBase_ISelection* aSelection = myWorkshop->selection();
144   NCollection_List<TopoDS_Shape> aSelectedShapes; //, aFilteredShapes;
145   std::list<ObjectPtr> aOwnersList;
146   aSelection->selectedShapes(aSelectedShapes, aOwnersList);
147
148   mySelection.clear();
149   std::list<ObjectPtr>::const_iterator aIt;
150   NCollection_List<TopoDS_Shape>::Iterator aShpIt(aSelectedShapes);
151   GeomShapePtr aShape;
152   for (aIt = aOwnersList.cbegin(); aIt != aOwnersList.cend(); aShpIt.Next(), aIt++) {
153     ResultPtr aResult = boost::dynamic_pointer_cast<ModelAPI_Result>(*aIt);
154     aShape = boost::shared_ptr<GeomAPI_Shape>(new GeomAPI_Shape());
155     aShape->setImpl(new TopoDS_Shape(aShpIt.Value()));
156     mySelection.append(GeomSelection(aResult, aShape));
157   }
158   updateSelectionList();
159   storeValue();
160   emit valuesChanged();
161 }
162
163
164 //********************************************************************
165 void ModuleBase_WidgetMultiSelector::updateSelectionList()
166 {
167   QString aType;
168   if (myTypeCombo->currentText().toLower() == "vertices")
169     aType = "vertex";
170   else if (myTypeCombo->currentText().toLower() == "edges")
171     aType = "edge";
172   else if (myTypeCombo->currentText().toLower() == "faces")
173     aType = "face";
174   else if (myTypeCombo->currentText().toLower() == "solids")
175     aType = "solid";
176  
177   myListControl->clear();
178   int i = 1;
179   foreach (GeomSelection aSel, mySelection) {
180     QString aName(aSel.first->data()->name().c_str());
181     aName += ":" + aType + QString("_%1").arg(i);
182     myListControl->addItem(aName);
183     i++;
184   }
185 }
186
187
188 //********************************************************************
189 void ModuleBase_WidgetMultiSelector::filterShapes(const NCollection_List<TopoDS_Shape>& theShapesToFilter,
190                                                   NCollection_List<TopoDS_Shape>& theResult)
191 {
192   if(myTypeCombo->count() == 0 || theShapesToFilter.IsEmpty())
193     return;
194   TopAbs_ShapeEnum aReferenceType =
195       ModuleBase_WidgetShapeSelector::shapeType(myTypeCombo->currentText());
196   NCollection_List<TopoDS_Shape>::Iterator anIter(theShapesToFilter);
197   for (; anIter.More(); anIter.Next()) {
198     TopoDS_Shape aShape = anIter.Value();
199     if (aShape.IsNull() || aShape.ShapeType() != aReferenceType)
200       continue;
201     theResult.Append(aShape);
202   }
203 }
204
205 //********************************************************************
206 void ModuleBase_WidgetMultiSelector::activateSelection(bool toActivate)
207 {
208   myIsActive = toActivate;
209   if (myIsActive) {
210     connect(myWorkshop, SIGNAL(selectionChanged()), this, SLOT(onSelectionChanged()));
211     onSelectionTypeChanged();
212   } else {
213     disconnect(myWorkshop, SIGNAL(selectionChanged()), this, SLOT(onSelectionChanged()));
214     myWorkshop->deactivateSubShapesSelection();
215   }
216 }
217
218 //********************************************************************
219 void ModuleBase_WidgetMultiSelector::onSelectionTypeChanged()
220 {
221   QString aNewType = myTypeCombo->currentText();
222   QIntList aList;
223   aList.append(ModuleBase_WidgetShapeSelector::shapeType(aNewType));
224   myWorkshop->activateSubShapesSelection(aList);
225 }