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