Salome HOME
d89f27de4855c7bf3ef765bd546f33ed05434312
[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_MetaWidget.h>
11 #include <ModuleBase_Operation.h>
12 #include <ModuleBase_OperationDescription.h>
13 #include <ModuleBase_PropPanelOperation.h>
14 #include <ModuleBase_WidgetPoint2D.h>
15 #include <ModuleBase_WidgetSwitch.h>
16
17 #include <Config_Keywords.h>
18 #include <Config_WidgetAPI.h>
19
20 #include <QWidget>
21 #include <QHBoxLayout>
22 #include <QGridLayout>
23 #include <QSpinBox>
24 #include <QMetaProperty>
25 #include <QLabel>
26 #include <QPixmap>
27 #include <QGroupBox>
28 #include <QToolBox>
29
30 #ifdef _DEBUG
31 #include <QDebug>
32 #endif
33
34 #include <cfloat>
35 #include <climits>
36
37 ModuleBase_WidgetFactory::ModuleBase_WidgetFactory(ModuleBase_Operation* theOperation)
38  : myOperation(theOperation)
39 {
40   QString aXml = myOperation->getDescription()->xmlRepresentation();
41   myWidgetApi = new Config_WidgetAPI(aXml.toStdString());
42 }
43
44 ModuleBase_WidgetFactory::~ModuleBase_WidgetFactory()
45 {
46 }
47
48 void ModuleBase_WidgetFactory::createWidget(QWidget* theParent)
49 {
50   if (!myWidgetApi->toChildWidget())
51     return;
52
53   QVBoxLayout* aWidgetLay = new QVBoxLayout(theParent);
54   aWidgetLay->setContentsMargins(2, 2, 2, 2);
55   do { //Iterate over each node
56     std::string aWdgType = myWidgetApi->widgetType();
57     //Create a widget (doublevalue, groupbox, toolbox, etc.
58     QWidget* aWidget = createWidgetByType(aWdgType, theParent);
59     if (aWidget) {
60       aWidgetLay->addWidget(aWidget);
61     }
62     if (myWidgetApi->isContainerWidget()) {
63       //if current widget is groupbox (container) process it's children recursively
64       QString aGroupName = qs(myWidgetApi->getProperty(CONTAINER_PAGE_NAME));
65       createWidget(aWidget);
66       QGroupBox* aGrBox = qobject_cast<QGroupBox*>(aWidget);
67       aGrBox->setTitle(aGroupName);
68     }
69     if (myWidgetApi->isPagedWidget()) {
70       //If current widget is toolbox or switch-casebox then fetch all
71       //it's pages recursively and setup into the widget.
72       myWidgetApi->toChildWidget();
73       do {
74         QString aPageName = qs(myWidgetApi->getProperty(CONTAINER_PAGE_NAME));
75         QWidget* aPage = new QWidget(aWidget);
76         createWidget(aPage);
77         if (aWdgType == WDG_SWITCH) {
78           ModuleBase_WidgetSwitch* aSwitch = qobject_cast<ModuleBase_WidgetSwitch*>(aWidget);
79           aSwitch->addPage(aPage, aPageName);
80         } else if (aWdgType == WDG_TOOLBOX){
81           QToolBox* aToolbox = qobject_cast<QToolBox*>(aWidget);
82           aToolbox->addItem(aPage, aPageName);
83         }
84       } while(myWidgetApi->toNextWidget());
85     }
86   } while(myWidgetApi->toNextWidget());
87   theParent->setLayout(aWidgetLay);
88 }
89
90 QWidget* ModuleBase_WidgetFactory::labelControl(QWidget* theParent)
91 {
92   QWidget* result = new QWidget(theParent);
93   QVBoxLayout* aLabelLay = new QVBoxLayout(result);
94   QLabel* aLabel = new QLabel(result);
95   aLabel->setText(qs(myWidgetApi->getProperty(INFO_WDG_TEXT)));
96   aLabel->setToolTip(qs(myWidgetApi->getProperty(INFO_WDG_TOOLTIP)));
97   aLabelLay->addWidget(aLabel);
98   aLabelLay->addStretch(1);
99   result->setLayout(aLabelLay);
100   return result;
101 }
102
103 QWidget* ModuleBase_WidgetFactory::createWidgetByType(const std::string& theType, QWidget* theParent)
104 {
105   QWidget* result = NULL;
106   if (theType == WDG_DOUBLEVALUE) {
107     result = doubleSpinBoxControl();
108   } else if (theType == WDG_INFO) {
109     result = labelControl(theParent);
110   }
111   else if (theType == WDG_POINT_SELECTOR) {
112     result = pointSelectorControl(theParent);
113   }
114   else if (myWidgetApi->isContainerWidget() || myWidgetApi->isPagedWidget()) {
115     result = createContainer(theType, theParent);
116   }
117 #ifdef _DEBUG
118   else { qDebug() << "ModuleBase_WidgetFactory::fillWidget: find bad widget type"; }
119 #endif
120   return result;
121 }
122
123 QWidget* ModuleBase_WidgetFactory::createContainer(const std::string& theType, QWidget* theParent)
124 {
125   QWidget* result = NULL;
126   if (theType == WDG_GROUP || theType == WDG_CHECK_GROUP) {
127     QGroupBox* aGroupBox = new QGroupBox(theParent);
128     aGroupBox->setCheckable(theType == WDG_CHECK_GROUP);
129     result = aGroupBox;
130   } else if (theType == WDG_TOOLBOX) {
131     result = new QToolBox(theParent);
132   } else if (theType == WDG_SWITCH) {
133     result = new ModuleBase_WidgetSwitch(theParent);
134   } else if (theType == WDG_TOOLBOX_BOX || theType == WDG_SWITCH_CASE) {
135     result = NULL;
136   }
137 #ifdef _DEBUG
138   else { qDebug() << "ModuleBase_WidgetFactory::fillWidget: find bad container type"; }
139 #endif
140   return result;
141 }
142
143 QWidget* ModuleBase_WidgetFactory::doubleSpinBoxControl()
144 {
145   QWidget* result = new QWidget();
146   QHBoxLayout* aControlLay = new QHBoxLayout(result);
147   aControlLay->setContentsMargins(0, 0, 0, 0);
148   QString aLabelText = qs(myWidgetApi->widgetLabel());
149   QString aLabelIcon = qs(myWidgetApi->widgetIcon());
150   QLabel* aLabel = new QLabel(aLabelText);
151   aLabel->setPixmap(QPixmap(aLabelIcon));
152
153   aControlLay->addWidget(aLabel);
154   QDoubleSpinBox* aBox = new QDoubleSpinBox(result);
155   QString anObjName = QString::fromStdString(myWidgetApi->widgetId());
156   aBox->setObjectName(anObjName);
157   bool isOk = false;
158   std::string aProp = myWidgetApi->getProperty(DOUBLE_WDG_MIN);
159   double aMinVal = qs(aProp).toDouble(&isOk);
160   if (isOk) {
161     aBox->setMinimum(aMinVal);
162   } else {
163     aBox->setMinimum(-DBL_MAX);
164   }
165   aProp = myWidgetApi->getProperty(DOUBLE_WDG_MAX);
166   double aMaxVal = qs(aProp).toDouble(&isOk);
167   if (isOk) {
168     aBox->setMaximum(aMaxVal);
169   } else {
170     aBox->setMaximum(DBL_MAX);
171   }
172   aProp = myWidgetApi->getProperty(DOUBLE_WDG_STEP);
173   double aStepVal = qs(aProp).toDouble(&isOk);
174   if (isOk) {
175     aBox->setSingleStep(aStepVal);
176   }
177   aProp = myWidgetApi->getProperty(DOUBLE_WDG_DFLT);
178   double aDefVal = qs(aProp).toDouble(&isOk);
179   if (isOk) {
180     aBox->setValue(aDefVal);
181   }
182   QString aTTip = qs(myWidgetApi->widgetTooltip());
183   aBox->setToolTip(aTTip);
184   aControlLay->addWidget(aBox);
185   aControlLay->setStretch(1, 1);
186   result->setLayout(aControlLay);
187   connectWidget(aBox, WDG_DOUBLEVALUE);
188   ModuleBase_MetaWidget* aWrappedWdg =
189       new ModuleBase_MetaWidget(anObjName, aBox, myOperation->feature());
190   myWidgets.append(aWrappedWdg);
191   return result;
192 }
193
194 QWidget* ModuleBase_WidgetFactory::pointSelectorControl(QWidget* theParent)
195 {
196   ModuleBase_WidgetPoint2D* aWidget = new ModuleBase_WidgetPoint2D(theParent,
197                        qs(myWidgetApi->getProperty(CONTAINER_PAGE_NAME)), myWidgetApi->widgetId());
198   connectWidget(aWidget, WDG_POINT_SELECTOR);
199   return aWidget->getControl();
200 }
201
202 bool ModuleBase_WidgetFactory::connectWidget(QObject* theWidget,  const QString& theType)
203 {
204   bool result = false;
205   if (theType == WDG_DOUBLEVALUE) {
206     result = QObject::connect(theWidget, SIGNAL(valueChanged(double)), 
207                               myOperation, SLOT(storeReal(double)));
208   }
209   if (theType == WDG_POINT_SELECTOR) {
210     ModuleBase_WidgetCustom* aCustom = dynamic_cast<ModuleBase_WidgetCustom*>(theWidget);
211     result = QObject::connect(aCustom, SIGNAL(valuesChanged()), 
212                               myOperation, SLOT(storeCustomValue()));
213   }
214   return result;
215 }
216
217 QString ModuleBase_WidgetFactory::qs(const std::string& theStdString) const
218 {
219   return QString::fromStdString(theStdString);
220 }