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