Salome HOME
The "concealment" attribute added
[modules/shaper.git] / src / ModuleBase / ModuleBase_WidgetFactory.cpp
1 /*
2  * ModuleBase_WidgetFactory.cpp
3  *
4  *  Created on: Apr 3, 2014
5  *      Author: sbh
6  */
7
8 #include <ModuleBase_WidgetFactory.h>
9
10 #include <ModuleBase_Operation.h>
11 #include <ModuleBase_OperationDescription.h>
12 #include <ModuleBase_WidgetPoint2D.h>
13 #include <ModuleBase_WidgetFeatureOrAttribute.h>
14 #include <ModuleBase_WidgetFeature.h>
15 #include <ModuleBase_WidgetEditor.h>
16 #include <ModuleBase_WidgetSwitch.h>
17 #include <ModuleBase_WidgetShapeSelector.h>
18 #include <ModuleBase_WidgetDoubleValue.h>
19 #include <ModuleBase_WidgetBoolValue.h>
20 #include <ModuleBase_WidgetPoint2dDistance.h>
21 #include <ModuleBase_WidgetFileSelector.h>
22 #include <ModuleBase_WidgetChoice.h>
23 #include <ModuleBase_IWorkshop.h>
24 #include <ModuleBase_IModule.h>
25 #include <ModuleBase_Tools.h>
26 #include <ModuleBase_WidgetLineEdit.h>
27 #include <ModuleBase_WidgetMultiSelector.h>
28
29 #include <ModelAPI_Validator.h>
30
31 #include <Config_Keywords.h>
32 #include <Config_WidgetAPI.h>
33
34 #include <QWidget>
35 #include <QHBoxLayout>
36 #include <QGridLayout>
37 #include <QSpinBox>
38 #include <QMetaProperty>
39 #include <QLabel>
40 #include <QPixmap>
41 #include <QGroupBox>
42 #include <QToolBox>
43
44 #ifdef _DEBUG
45 #include <QDebug>
46 #endif
47
48 #include <cfloat>
49 #include <climits>
50
51 ModuleBase_WidgetFactory::ModuleBase_WidgetFactory(const std::string& theXmlRepresentation,
52                                                    ModuleBase_IWorkshop* theWorkshop)
53     : myWorkshop(theWorkshop)
54 {
55   myWidgetApi = new Config_WidgetAPI(theXmlRepresentation);
56 }
57
58 ModuleBase_WidgetFactory::~ModuleBase_WidgetFactory()
59 {
60 }
61
62 void ModuleBase_WidgetFactory::createWidget(QWidget* theParent)
63 {
64   myParentId = myWidgetApi->widgetId();
65   if (!myWidgetApi->toChildWidget())
66     return;
67
68   QVBoxLayout* aWidgetLay = new QVBoxLayout(theParent);
69   do {  //Iterate over each node
70     std::string aWdgType = myWidgetApi->widgetType();
71     //Create a widget (doublevalue, groupbox, toolbox, etc.
72     QWidget* aWidget = createWidgetByType(aWdgType, theParent);
73     if (aWidget) {
74       if (!myWidgetApi->getBooleanAttribute(ATTRIBUTE_INTERNAL, false)) {
75         aWidgetLay->addWidget(aWidget);
76       } else {
77         aWidget->setVisible(false);
78       }
79     }
80     if (myWidgetApi->isContainerWidget()) {
81       //if current widget is groupbox (container) process it's children recursively
82       QString aGroupName = qs(myWidgetApi->getProperty(CONTAINER_PAGE_NAME));
83       createWidget(aWidget);
84       ModuleBase_Tools::adjustMargins(aWidget);
85       QGroupBox* aGrBox = qobject_cast<QGroupBox*>(aWidget);
86       aGrBox->setTitle(aGroupName);
87     }
88     if (myWidgetApi->isPagedWidget()) {
89       //If current widget is toolbox or switch-casebox then fetch all
90       //it's pages recursively and setup into the widget.
91       myWidgetApi->toChildWidget();
92       do {
93         QString aPageName = qs(myWidgetApi->getProperty(CONTAINER_PAGE_NAME));
94         QWidget* aPage = new QWidget(aWidget);
95         ModuleBase_Tools::adjustMargins(aPage);
96         createWidget(aPage);
97         if (aWdgType == WDG_SWITCH) {
98           ModuleBase_WidgetSwitch* aSwitch = qobject_cast<ModuleBase_WidgetSwitch*>(aWidget);
99           aSwitch->addPage(aPage, aPageName);
100         } else if (aWdgType == WDG_TOOLBOX) {
101           QToolBox* aToolbox = qobject_cast<QToolBox*>(aWidget);
102           aToolbox->addItem(aPage, aPageName);
103         }
104       } while (myWidgetApi->toNextWidget());
105     }
106   } while (myWidgetApi->toNextWidget());
107   theParent->setLayout(aWidgetLay);
108 }
109
110 QWidget* ModuleBase_WidgetFactory::labelControl(QWidget* theParent)
111 {
112   QWidget* result = new QWidget(theParent);
113   QVBoxLayout* aLabelLay = new QVBoxLayout(result);
114   QLabel* aLabel = new QLabel(result);
115   aLabel->setWordWrap(true);
116   aLabel->setText(qs(myWidgetApi->getProperty(INFO_WDG_TEXT)));
117   aLabel->setToolTip(qs(myWidgetApi->getProperty(INFO_WDG_TOOLTIP)));
118   aLabelLay->addWidget(aLabel);
119   aLabelLay->addStretch(1);
120   result->setLayout(aLabelLay);
121   return result;
122 }
123
124 void ModuleBase_WidgetFactory::processAttributes()
125 {
126   // register that this attribute in feature is not obligatory for the feature execution
127   // so, it is not needed for the standard validation mechanism
128   bool isObligatory = true;
129   bool isConcealment = false;
130   if( myWidgetApi ){
131     isObligatory = myWidgetApi->getBooleanAttribute(ATTRIBUTE_OBLIGATORY, true);
132     isConcealment = myWidgetApi->getBooleanAttribute(ATTRIBUTE_CONCEALMENT, false);
133   }
134   boost::shared_ptr<ModelAPI_Session> aSession = ModelAPI_Session::get();
135   if (!isObligatory) {
136     aSession->validators()->registerNotObligatory(myParentId, myWidgetApi->widgetId());
137   }
138   if(isConcealment) {
139     aSession->validators()->registerConcealment(myParentId, myWidgetApi->widgetId());
140   }
141 }
142
143 QWidget* ModuleBase_WidgetFactory::createWidgetByType(const std::string& theType,
144                                                       QWidget* theParent)
145 {
146   QWidget* result = NULL;
147   if (theType == WDG_DOUBLEVALUE) {
148     result = doubleSpinBoxControl(theParent);
149
150   } else if (theType == WDG_INFO) {
151     result = labelControl(theParent);
152
153   } else if (theType == WDG_SHAPE_SELECTOR) {
154     result = shapeSelectorControl(theParent);
155
156   } else if (theType == WDG_BOOLVALUE) {
157     result = booleanControl(theParent);
158
159   } else if (theType == WDG_POINT_SELECTOR) {
160     result = pointSelectorControl(theParent);
161
162   } else if (theType == WDG_FEATURE_SELECTOR) {
163     result = featureSelectorControl(theParent);
164
165   } else if (theType == WDG_FEATURE_OR_ATTRIBUTE_SELECTOR) {
166     result = featureOrAttributeSelectorControl(theParent);
167
168   } else if (theType == WDG_DOUBLEVALUE_EDITOR) {
169     result = doubleValueEditor(theParent);
170
171   } else if (theType == WDG_POINT2D_DISTANCE) {
172     result = point2dDistanceControl(theParent);
173
174   } else if (theType == WDG_FILE_SELECTOR) {
175     result = fileSelectorControl(theParent);
176
177   } else if (theType == WDG_CHOICE) {
178     result = choiceControl(theParent);
179
180   } else if (theType == WDG_STRINGVALUE) {
181     result = lineEditControl(theParent);
182
183   } else if (theType == WDG_MULTISELECTOR) {
184     result = multiSelectorControl(theParent);
185
186   } else if (myWidgetApi->isContainerWidget() || myWidgetApi->isPagedWidget()) {
187     result = createContainer(theType, theParent);
188   } else {
189     result = myWorkshop->module()->createWidgetByType(theType, theParent, myWidgetApi,
190                                                       myModelWidgets);
191 #ifdef _DEBUG
192     if (!result) {qDebug("ModuleBase_WidgetFactory::fillWidget: find bad widget type");}
193 #endif
194   }
195   if (result) {
196     processAttributes();
197   }
198
199   return result;
200 }
201
202 QWidget* ModuleBase_WidgetFactory::createContainer(const std::string& theType, QWidget* theParent)
203 {
204   QWidget* result = NULL;
205   if (theType == WDG_GROUP || theType == WDG_CHECK_GROUP) {
206     QGroupBox* aGroupBox = new QGroupBox(theParent);
207     aGroupBox->setCheckable(theType == WDG_CHECK_GROUP);
208     result = aGroupBox;
209   } else if (theType == WDG_TOOLBOX) {
210     result = new QToolBox(theParent);
211   } else if (theType == WDG_SWITCH) {
212     result = new ModuleBase_WidgetSwitch(theParent);
213   } else if (theType == WDG_TOOLBOX_BOX || theType == WDG_SWITCH_CASE) {
214     result = NULL;
215   }
216 #ifdef _DEBUG
217   else {qDebug() << "ModuleBase_WidgetFactory::fillWidget: find bad container type";}
218 #endif
219   return result;
220 }
221
222 QWidget* ModuleBase_WidgetFactory::doubleSpinBoxControl(QWidget* theParent)
223 {
224   ModuleBase_WidgetDoubleValue* aDblWgt =
225       new ModuleBase_WidgetDoubleValue(theParent, myWidgetApi, myParentId);
226   myModelWidgets.append(aDblWgt);
227   return aDblWgt->getControl();
228 }
229
230 QWidget* ModuleBase_WidgetFactory::pointSelectorControl(QWidget* theParent)
231 {
232   ModuleBase_WidgetPoint2D* aWidget =
233       new ModuleBase_WidgetPoint2D(theParent, myWidgetApi,myParentId);
234   myModelWidgets.append(aWidget);
235   return aWidget->getControl();
236 }
237
238 QWidget* ModuleBase_WidgetFactory::featureSelectorControl(QWidget* theParent)
239 {
240   ModuleBase_WidgetFeature* aWidget =
241       new ModuleBase_WidgetFeature(theParent, myWidgetApi,myParentId);
242   myModelWidgets.append(aWidget);
243   return aWidget->getControl();
244 }
245
246 QWidget* ModuleBase_WidgetFactory::featureOrAttributeSelectorControl(QWidget* theParent)
247 {
248   ModuleBase_WidgetFeatureOrAttribute* aWidget =
249       new ModuleBase_WidgetFeatureOrAttribute(theParent, myWidgetApi, myParentId);
250   myModelWidgets.append(aWidget);
251   return aWidget->getControl();
252 }
253
254 QWidget* ModuleBase_WidgetFactory::doubleValueEditor(QWidget* theParent)
255 {
256   ModuleBase_WidgetEditor* aWidget =
257       new ModuleBase_WidgetEditor(theParent, myWidgetApi, myParentId);
258   myModelWidgets.append(aWidget);
259   return aWidget->getControl();
260 }
261
262 QWidget* ModuleBase_WidgetFactory::shapeSelectorControl(QWidget* theParent)
263 {
264   ModuleBase_WidgetShapeSelector* aSelector =
265       new ModuleBase_WidgetShapeSelector(theParent, myWorkshop, myWidgetApi, myParentId);
266   myModelWidgets.append(aSelector);
267   return aSelector->getControl();
268 }
269
270 QWidget* ModuleBase_WidgetFactory::booleanControl(QWidget* theParent)
271 {
272   ModuleBase_WidgetBoolValue* aBoolWgt =
273       new ModuleBase_WidgetBoolValue(theParent, myWidgetApi, myParentId);
274   myModelWidgets.append(aBoolWgt);
275   return aBoolWgt->getControl();
276 }
277
278 QWidget* ModuleBase_WidgetFactory::point2dDistanceControl(QWidget* theParent)
279 {
280   ModuleBase_WidgetPoint2dDistance* aDistWgt =
281       new ModuleBase_WidgetPoint2dDistance(theParent, myWidgetApi, myParentId);
282   myModelWidgets.append(aDistWgt);
283   return aDistWgt->getControl();
284 }
285
286 QWidget* ModuleBase_WidgetFactory::fileSelectorControl(QWidget* theParent)
287 {
288   ModuleBase_WidgetFileSelector* aFileSelectorWgt =
289       new ModuleBase_WidgetFileSelector(theParent, myWidgetApi, myParentId);
290   myModelWidgets.append(aFileSelectorWgt);
291   return aFileSelectorWgt->getControl();
292 }
293
294 QWidget* ModuleBase_WidgetFactory::choiceControl(QWidget* theParent)
295 {
296   ModuleBase_WidgetChoice* aChoiceWgt =
297       new ModuleBase_WidgetChoice(theParent, myWidgetApi,myParentId);
298   myModelWidgets.append(aChoiceWgt);
299   return aChoiceWgt->getControl();
300 }
301
302 QWidget* ModuleBase_WidgetFactory::lineEditControl(QWidget* theParent)
303 {
304   ModuleBase_WidgetLineEdit* aLineEditWgt =
305       new ModuleBase_WidgetLineEdit(theParent, myWidgetApi,myParentId);
306   myModelWidgets.append(aLineEditWgt);
307   return aLineEditWgt->getControl();
308 }
309
310 QWidget* ModuleBase_WidgetFactory::multiSelectorControl(QWidget* theParent)
311 {
312   ModuleBase_WidgetMultiSelector* aMultiselectorWgt =
313       new ModuleBase_WidgetMultiSelector(theParent, myWorkshop, myWidgetApi,myParentId);
314   myModelWidgets.append(aMultiselectorWgt);
315   return aMultiselectorWgt->getControl();
316 }
317
318 QString ModuleBase_WidgetFactory::qs(const std::string& theStdString) const
319 {
320   return QString::fromStdString(theStdString);
321 }