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