Salome HOME
Property pannel refactoring: focus processing in paged widgets
[modules/shaper.git] / src / ModuleBase / ModuleBase_WidgetFactory.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
2
3 /*
4  * ModuleBase_WidgetFactory.cpp
5  *
6  *  Created on: Apr 3, 2014
7  *      Author: sbh
8  */
9
10 #include <ModuleBase_WidgetFactory.h>
11
12 #include <ModuleBase_Operation.h>
13 #include <ModuleBase_OperationDescription.h>
14 //#include <ModuleBase_WidgetFeatureOrAttribute.h>
15 //#include <ModuleBase_WidgetFeature.h>
16 #include <ModuleBase_WidgetEditor.h>
17 #include <ModuleBase_WidgetSwitch.h>
18 #include <ModuleBase_WidgetShapeSelector.h>
19 #include <ModuleBase_WidgetDoubleValue.h>
20 #include <ModuleBase_WidgetBoolValue.h>
21 //#include <ModuleBase_WidgetPoint2dDistance.h>
22 #include <ModuleBase_WidgetFileSelector.h>
23 #include <ModuleBase_WidgetChoice.h>
24 #include <ModuleBase_IWorkshop.h>
25 #include <ModuleBase_IModule.h>
26 #include <ModuleBase_Tools.h>
27 #include <ModuleBase_WidgetLineEdit.h>
28 #include <ModuleBase_WidgetMultiSelector.h>
29 #include <ModuleBase_WidgetLabel.h>
30 #include <ModuleBase_WidgetToolbox.h>
31 #include <ModuleBase_PageBase.h>
32 #include <ModuleBase_PageGroupBox.h>
33 #include <ModuleBase_PageWidget.h>
34
35 #include <ModelAPI_Validator.h>
36 #include <ModelAPI_Session.h>
37
38 #include <Config_Keywords.h>
39 #include <Config_WidgetAPI.h>
40
41 #include <QWidget>
42 #include <QHBoxLayout>
43 #include <QGridLayout>
44 #include <QSpinBox>
45 #include <QMetaProperty>
46 #include <QLabel>
47 #include <QPixmap>
48 #include <QGroupBox>
49 #include <QToolBox>
50
51 #ifdef _DEBUG
52 #include <QDebug>
53 #endif
54
55 #include <cfloat>
56 #include <climits>
57
58 ModuleBase_WidgetFactory::ModuleBase_WidgetFactory(const std::string& theXmlRepresentation,
59                                                    ModuleBase_IWorkshop* theWorkshop)
60     : myWorkshop(theWorkshop)
61 {
62   myWidgetApi = new Config_WidgetAPI(theXmlRepresentation);
63 }
64
65 ModuleBase_WidgetFactory::~ModuleBase_WidgetFactory()
66 {
67   delete myWidgetApi;
68 }
69
70 void ModuleBase_WidgetFactory::createWidget(ModuleBase_PageBase* thePage)
71 {
72   myParentId = myWidgetApi->widgetId();
73   if (!myWidgetApi->toChildWidget())
74     return;
75
76   //bool isStretchLayout = false;
77   QWidget* aPageWidget = dynamic_cast<QWidget*>(thePage);
78   if(!aPageWidget) {
79     #ifdef _DEBUG
80     std::cout << "ModuleBase_WidgetFactory::createWidget: can not reinterpret_cast thePage" << std::endl;
81     #endif
82   }
83   do {  //Iterate over each node
84     std::string aWdgType = myWidgetApi->widgetType();
85     // Create PageGroup TODO: extract
86     if (myWidgetApi->isGroupBoxWidget()) {
87       //if current widget is groupbox (container) process it's children recursively
88       QString aGroupName = qs(myWidgetApi->getProperty(CONTAINER_PAGE_NAME));
89       ModuleBase_PageGroupBox* aPage = new ModuleBase_PageGroupBox(aPageWidget);
90       aPage->setTitle(aGroupName);
91       createWidget(aPage);
92       thePage->addPageWidget(aPage);
93     } else {
94       // Create a ModelWidget
95       ModuleBase_ModelWidget* aWidget = createWidgetByType(aWdgType, aPageWidget);
96       if (aWidget) {
97         if (!myWidgetApi->getBooleanAttribute(ATTR_INTERNAL, false)) {
98           thePage->addModelWidget(aWidget);
99         } else {
100           aWidget->setVisible(false);
101         }
102       }
103       // Create PagedContainer TODO: extract
104       if (myWidgetApi->isPagedWidget()) {
105         //If current widget is toolbox or switch-casebox then fetch all
106         //it's pages recursively and setup into the widget.
107         myWidgetApi->toChildWidget();
108         do {
109           QString aPageName = qs(myWidgetApi->getProperty(CONTAINER_PAGE_NAME));
110           QString aCaseId = qs(myWidgetApi->getProperty(_ID));
111           ModuleBase_PageBase* aPage = new ModuleBase_PageWidget(aWidget);
112           createWidget(aPage);
113           QWidget* aCasePageWidget = dynamic_cast<QWidget*>(aPage);
114           if (aWdgType == WDG_SWITCH) {
115             ModuleBase_WidgetSwitch* aSwitch = qobject_cast<ModuleBase_WidgetSwitch*>(aWidget);
116             aSwitch->addPage(aCasePageWidget, aPageName);
117           } else if (aWdgType == WDG_TOOLBOX) {
118             ModuleBase_WidgetToolbox* aToolbox = qobject_cast<ModuleBase_WidgetToolbox*>(aWidget);
119             aToolbox->addPage(aCasePageWidget, aPageName, aCaseId);
120           }
121         } while (myWidgetApi->toNextWidget());
122       }
123     }
124 //    if (aWidget && !isStretchLayout) {
125 //      isStretchLayout = !hasExpandingControls(aWidget);
126 //    }
127   } while (myWidgetApi->toNextWidget());
128 //  if (isStretchLayout) {
129 //    aWidgetLay->addStretch(1);
130 //  }
131 }
132
133 bool ModuleBase_WidgetFactory::hasExpandingControls(QWidget* theParent)
134 {
135   bool result = false;
136   QList<QWidget *> aListToCheck;
137   aListToCheck << theParent;
138   ModuleBase_ModelWidget* aModelWidget = qobject_cast<ModuleBase_ModelWidget*>(theParent);
139   if(aModelWidget) {
140     aListToCheck << aModelWidget->getControls();
141   }
142   foreach(QWidget* eachWidget, aListToCheck) {
143     QSizePolicy::Policy aVPolicy = eachWidget->sizePolicy().verticalPolicy();
144     if(aVPolicy & QSizePolicy::ExpandFlag) {
145       result = true;
146     }
147   }
148   return result;
149 }
150
151 ModuleBase_ModelWidget* ModuleBase_WidgetFactory
152 ::createWidgetByType(const std::string& theType, QWidget* theParent)
153 {
154   ModuleBase_ModelWidget* result = NULL;
155
156   if (theType == WDG_INFO) {
157     result = new ModuleBase_WidgetLabel(theParent, myWidgetApi, myParentId);
158
159   } else if (theType == WDG_DOUBLEVALUE) {
160     result = new ModuleBase_WidgetDoubleValue(theParent, myWidgetApi, myParentId);
161
162   } else if (theType == WDG_SHAPE_SELECTOR) {
163     result =  new ModuleBase_WidgetShapeSelector(theParent, myWorkshop, myWidgetApi, myParentId);
164
165   } else if (theType == WDG_BOOLVALUE) {
166     result = new ModuleBase_WidgetBoolValue(theParent, myWidgetApi, myParentId);
167
168   } else if (theType == WDG_DOUBLEVALUE_EDITOR) {
169     result = new ModuleBase_WidgetEditor(theParent, myWidgetApi, myParentId);
170
171   } else if (theType == WDG_FILE_SELECTOR) {
172     result = new ModuleBase_WidgetFileSelector(theParent, myWidgetApi, myParentId);
173
174   } else if (theType == WDG_CHOICE) {
175     result = new ModuleBase_WidgetChoice(theParent, myWidgetApi,myParentId);
176
177   } else if (theType == WDG_STRINGVALUE) {
178     result = new ModuleBase_WidgetLineEdit(theParent, myWidgetApi,myParentId);
179
180   } else if (theType == WDG_MULTISELECTOR) {
181     result = new ModuleBase_WidgetMultiSelector(theParent, myWorkshop, myWidgetApi,myParentId);
182
183   } else if (theType == WDG_TOOLBOX) {
184     result = new ModuleBase_WidgetToolbox(theParent, myWidgetApi, myParentId);
185
186   } else if (theType == WDG_SWITCH) {
187     result = new ModuleBase_WidgetSwitch(theParent, myWidgetApi, myParentId);
188     return result;
189
190   } else if (theType == WDG_TOOLBOX_BOX || theType == WDG_SWITCH_CASE) {
191     // Do nothing for "box" and "case"
192     result = NULL;
193   } else {
194     result = myWorkshop->module()->createWidgetByType(theType, theParent, myWidgetApi,
195                                                       myParentId);
196 #ifdef _DEBUG
197     if (!result) {qDebug("ModuleBase_WidgetFactory::fillWidget: find bad widget type");}
198 #endif
199   }
200   if (result) {
201     myModelWidgets.append(result);
202   }
203   return result;
204 }
205
206 QString ModuleBase_WidgetFactory::qs(const std::string& theStdString)
207 {
208   return QString::fromStdString(theStdString);
209 }
210