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