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