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