Salome HOME
Property panel widgets redesign
[modules/shaper.git] / src / ModuleBase / ModuleBase_WidgetFactory.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
2
3 /*
4  * ModuleBase_WidgetFactory.cpp
5  *
6  *  Created on: Apr 3, 2014
7  *      Author: sbh
8  */
9
10 #include <ModuleBase_WidgetFactory.h>
11
12 #include <ModuleBase_Operation.h>
13 #include <ModuleBase_OperationDescription.h>
14 //#include <ModuleBase_WidgetFeatureOrAttribute.h>
15 //#include <ModuleBase_WidgetFeature.h>
16 #include <ModuleBase_WidgetEditor.h>
17 #include <ModuleBase_WidgetSwitch.h>
18 #include <ModuleBase_WidgetShapeSelector.h>
19 #include <ModuleBase_WidgetDoubleValue.h>
20 #include <ModuleBase_WidgetBoolValue.h>
21 //#include <ModuleBase_WidgetPoint2dDistance.h>
22 #include <ModuleBase_WidgetFileSelector.h>
23 #include <ModuleBase_WidgetChoice.h>
24 #include <ModuleBase_IWorkshop.h>
25 #include <ModuleBase_IModule.h>
26 #include <ModuleBase_Tools.h>
27 #include <ModuleBase_WidgetLineEdit.h>
28 #include <ModuleBase_WidgetMultiSelector.h>
29 #include <ModuleBase_WidgetLabel.h>
30
31 #include <ModelAPI_Validator.h>
32 #include <ModelAPI_Session.h>
33
34 #include <Config_Keywords.h>
35 #include <Config_WidgetAPI.h>
36
37 #include <QWidget>
38 #include <QHBoxLayout>
39 #include <QGridLayout>
40 #include <QSpinBox>
41 #include <QMetaProperty>
42 #include <QLabel>
43 #include <QPixmap>
44 #include <QGroupBox>
45 #include <QToolBox>
46
47 #ifdef _DEBUG
48 #include <QDebug>
49 #endif
50
51 #include <cfloat>
52 #include <climits>
53
54 ModuleBase_WidgetFactory::ModuleBase_WidgetFactory(const std::string& theXmlRepresentation,
55                                                    ModuleBase_IWorkshop* theWorkshop)
56     : myWorkshop(theWorkshop)
57 {
58   myWidgetApi = new Config_WidgetAPI(theXmlRepresentation);
59 }
60
61 ModuleBase_WidgetFactory::~ModuleBase_WidgetFactory()
62 {
63   delete myWidgetApi;
64 }
65
66 void ModuleBase_WidgetFactory::createWidget(QWidget* theParent)
67 {
68   myParentId = myWidgetApi->widgetId();
69   if (!myWidgetApi->toChildWidget())
70     return;
71
72   QVBoxLayout* aWidgetLay = new QVBoxLayout(theParent);
73   bool isStretchLayout = false;
74   do {  //Iterate over each node
75     std::string aWdgType = myWidgetApi->widgetType();
76     //Create a widget (doublevalue, groupbox, toolbox, etc.
77     QWidget* aWidget = createWidgetByType(aWdgType, theParent);
78     if (aWidget) {
79       if (!myWidgetApi->getBooleanAttribute(ATTR_INTERNAL, false)) {
80         aWidgetLay->addWidget(aWidget);
81       } else {
82         aWidget->setVisible(false);
83       }
84     }
85     if (myWidgetApi->isContainerWidget()) {
86       //if current widget is groupbox (container) process it's children recursively
87       QString aGroupName = qs(myWidgetApi->getProperty(CONTAINER_PAGE_NAME));
88       createWidget(aWidget);
89       ModuleBase_Tools::adjustMargins(aWidget);
90       QGroupBox* aGrBox = qobject_cast<QGroupBox*>(aWidget);
91       aGrBox->setTitle(aGroupName);
92     }
93     if (myWidgetApi->isPagedWidget()) {
94       //If current widget is toolbox or switch-casebox then fetch all
95       //it's pages recursively and setup into the widget.
96       myWidgetApi->toChildWidget();
97       do {
98         QString aPageName = qs(myWidgetApi->getProperty(CONTAINER_PAGE_NAME));
99         QWidget* aPage = new QWidget(aWidget);
100         createWidget(aPage);
101         ModuleBase_Tools::adjustMargins(aPage);
102         if (aWdgType == WDG_SWITCH) {
103           ModuleBase_WidgetSwitch* aSwitch = qobject_cast<ModuleBase_WidgetSwitch*>(aWidget);
104           aSwitch->addPage(aPage, aPageName);
105         } else if (aWdgType == WDG_TOOLBOX) {
106           QToolBox* aToolbox = qobject_cast<QToolBox*>(aWidget);
107           aToolbox->addItem(aPage, aPageName);
108         }
109
110       } while (myWidgetApi->toNextWidget());
111     }
112     if (aWidget && !isStretchLayout) {
113       isStretchLayout = !hasExpandingControls(aWidget);
114     }
115   } while (myWidgetApi->toNextWidget());
116   if (isStretchLayout) {
117     aWidgetLay->addStretch(1);
118   }
119   theParent->setLayout(aWidgetLay);
120 }
121
122 bool ModuleBase_WidgetFactory::hasExpandingControls(QWidget* theParent)
123 {
124   bool result = false;
125   QList<QWidget *> aListToCheck;
126   aListToCheck << theParent;
127   ModuleBase_ModelWidget* aModelWidget = qobject_cast<ModuleBase_ModelWidget*>(theParent);
128   if(aModelWidget) {
129     aListToCheck << aModelWidget->getControls();
130   }
131   foreach(QWidget* eachWidget, aListToCheck) {
132     QSizePolicy::Policy aVPolicy = eachWidget->sizePolicy().verticalPolicy();
133     if(aVPolicy & QSizePolicy::ExpandFlag) {
134       result = true;
135     }
136   }
137   return result;
138 }
139
140 QWidget* ModuleBase_WidgetFactory::createWidgetByType(const std::string& theType,
141                                                       QWidget* theParent)
142 {
143   QWidget* result = NULL;
144   if (theType == WDG_DOUBLEVALUE) {
145     result = doubleSpinBoxControl(theParent);
146
147   } else if (theType == WDG_INFO) {
148     result = labelControl(theParent);
149
150   } else if (theType == WDG_SHAPE_SELECTOR) {
151     result = shapeSelectorControl(theParent);
152
153   } else if (theType == WDG_BOOLVALUE) {
154     result = booleanControl(theParent);
155
156   } else if (theType == WDG_DOUBLEVALUE_EDITOR) {
157     result = doubleValueEditor(theParent);
158
159   } else if (theType == WDG_FILE_SELECTOR) {
160     result = fileSelectorControl(theParent);
161
162   } else if (theType == WDG_CHOICE) {
163     result = choiceControl(theParent);
164
165   } else if (theType == WDG_STRINGVALUE) {
166     result = lineEditControl(theParent);
167
168   } else if (theType == WDG_MULTISELECTOR) {
169     result = multiSelectorControl(theParent);
170
171   } else if (myWidgetApi->isContainerWidget() || myWidgetApi->isPagedWidget()) {
172     result = createContainer(theType, theParent);
173   } else {
174     result = myWorkshop->module()->createWidgetByType(theType, theParent, myWidgetApi,
175                                                       myParentId, myModelWidgets);
176 #ifdef _DEBUG
177     if (!result) {qDebug("ModuleBase_WidgetFactory::fillWidget: find bad widget type");}
178 #endif
179   }
180   return result;
181 }
182
183 QWidget* ModuleBase_WidgetFactory::createContainer(const std::string& theType, QWidget* theParent)
184 {
185   QWidget* result = NULL;
186   if (theType == WDG_GROUP || theType == WDG_CHECK_GROUP) {
187     QGroupBox* aGroupBox = new QGroupBox(theParent);
188     aGroupBox->setCheckable(theType == WDG_CHECK_GROUP);
189     result = aGroupBox;
190   } else if (theType == WDG_TOOLBOX) {
191     result = new QToolBox(theParent);
192     // Dark-grey rounded tabs with button-like border #and bold font
193     QString css = "QToolBox::tab{background-color:#c8c8c8;"
194                                 "border-radius:5px;"
195                                 "border:1px inset;"
196                                 //"font-weight:700;"
197                                 "border-color:#fff #505050 #505050 #fff;}";
198     result->setStyleSheet(css);
199     // default vertical size policy is preferred
200     QSizePolicy aSizePolicy = result->sizePolicy();
201     aSizePolicy.setVerticalPolicy(QSizePolicy::MinimumExpanding);
202     result->setSizePolicy(aSizePolicy);
203   } else if (theType == WDG_SWITCH) {
204     result = new ModuleBase_WidgetSwitch(theParent);
205   } else if (theType == WDG_TOOLBOX_BOX || theType == WDG_SWITCH_CASE) {
206     // Do nothing for "box" and "case"
207     result = NULL;
208   }
209 #ifdef _DEBUG
210   else {qDebug() << "ModuleBase_WidgetFactory::fillWidget: find bad container type";}
211 #endif
212   return result;
213 }
214
215 QWidget* ModuleBase_WidgetFactory::labelControl(QWidget* theParent)
216 {
217   ModuleBase_WidgetLabel* aWgt =
218       new ModuleBase_WidgetLabel(theParent, myWidgetApi, myParentId);
219   myModelWidgets.append(aWgt);
220   return aWgt;
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;
229 }
230
231 QWidget* ModuleBase_WidgetFactory::doubleValueEditor(QWidget* theParent)
232 {
233   ModuleBase_WidgetEditor* aWidget =
234       new ModuleBase_WidgetEditor(theParent, myWidgetApi, myParentId);
235   myModelWidgets.append(aWidget);
236   return aWidget;
237 }
238
239 QWidget* ModuleBase_WidgetFactory::shapeSelectorControl(QWidget* theParent)
240 {
241   ModuleBase_WidgetShapeSelector* aSelector =
242       new ModuleBase_WidgetShapeSelector(theParent, myWorkshop, myWidgetApi, myParentId);
243   myModelWidgets.append(aSelector);
244   return aSelector;
245 }
246
247 QWidget* ModuleBase_WidgetFactory::booleanControl(QWidget* theParent)
248 {
249   ModuleBase_WidgetBoolValue* aBoolWgt =
250       new ModuleBase_WidgetBoolValue(theParent, myWidgetApi, myParentId);
251   myModelWidgets.append(aBoolWgt);
252   return aBoolWgt;
253 }
254
255 QWidget* ModuleBase_WidgetFactory::fileSelectorControl(QWidget* theParent)
256 {
257   ModuleBase_WidgetFileSelector* aFileSelectorWgt =
258       new ModuleBase_WidgetFileSelector(theParent, myWidgetApi, myParentId);
259   myModelWidgets.append(aFileSelectorWgt);
260   return aFileSelectorWgt;
261 }
262
263 QWidget* ModuleBase_WidgetFactory::choiceControl(QWidget* theParent)
264 {
265   ModuleBase_WidgetChoice* aChoiceWgt =
266       new ModuleBase_WidgetChoice(theParent, myWidgetApi,myParentId);
267   myModelWidgets.append(aChoiceWgt);
268   return aChoiceWgt;
269 }
270
271 QWidget* ModuleBase_WidgetFactory::lineEditControl(QWidget* theParent)
272 {
273   ModuleBase_WidgetLineEdit* aLineEditWgt =
274       new ModuleBase_WidgetLineEdit(theParent, myWidgetApi,myParentId);
275   myModelWidgets.append(aLineEditWgt);
276   return aLineEditWgt;
277 }
278
279 QWidget* ModuleBase_WidgetFactory::multiSelectorControl(QWidget* theParent)
280 {
281   ModuleBase_WidgetMultiSelector* aMultiselectorWgt =
282       new ModuleBase_WidgetMultiSelector(theParent, myWorkshop, myWidgetApi,myParentId);
283   myModelWidgets.append(aMultiselectorWgt);
284   return aMultiselectorWgt;
285 }
286
287 QString ModuleBase_WidgetFactory::qs(const std::string& theStdString)
288 {
289   return QString::fromStdString(theStdString);
290 }
291