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