Salome HOME
e8176696254d4ce51b8a1c0d0aae89c4cdfa22ad
[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_WidgetEditor.h>
15 #include <ModuleBase_WidgetSwitch.h>
16 #include <ModuleBase_WidgetShapeSelector.h>
17 #include <ModuleBase_WidgetDoubleValue.h>
18 #include <ModuleBase_WidgetIntValue.h>
19 #include <ModuleBase_WidgetBoolValue.h>
20 #include <ModuleBase_WidgetFileSelector.h>
21 #include <ModuleBase_WidgetChoice.h>
22 #include <ModuleBase_IWorkshop.h>
23 #include <ModuleBase_IModule.h>
24 #include <ModuleBase_Tools.h>
25 #include <ModuleBase_WidgetLineEdit.h>
26 #include <ModuleBase_WidgetMultiSelector.h>
27 #include <ModuleBase_WidgetLabel.h>
28 #include <ModuleBase_WidgetErrorLabel.h>
29 #include <ModuleBase_WidgetToolbox.h>
30 #include <ModuleBase_PageBase.h>
31 #include <ModuleBase_PageGroupBox.h>
32 #include <ModuleBase_WidgetCheckGroupBox.h>
33 #include <ModuleBase_PageWidget.h>
34 #include <ModuleBase_WidgetExprEditor.h>
35 #include <ModuleBase_WidgetCreatorFactory.h>
36
37 #include <ModelAPI_Validator.h>
38 #include <ModelAPI_Session.h>
39
40 #include <Config_Keywords.h>
41 #include <Config_WidgetAPI.h>
42
43 #include <QWidget>
44 #include <QHBoxLayout>
45 #include <QGridLayout>
46 #include <QSpinBox>
47 #include <QMetaProperty>
48 #include <QLabel>
49 #include <QPixmap>
50 #include <QGroupBox>
51 #include <QToolBox>
52
53 #ifdef _DEBUG
54 #include <QDebug>
55 #endif
56
57 #include <cfloat>
58 #include <climits>
59
60 ModuleBase_WidgetFactory::ModuleBase_WidgetFactory(const std::string& theXmlRepresentation,
61                                                    ModuleBase_IWorkshop* theWorkshop)
62     : myWorkshop(theWorkshop)
63 {
64   myWidgetApi = new Config_WidgetAPI(theXmlRepresentation);
65 }
66
67 ModuleBase_WidgetFactory::~ModuleBase_WidgetFactory()
68 {
69   delete myWidgetApi;
70 }
71
72 void ModuleBase_WidgetFactory::createWidget(ModuleBase_PageBase* thePage)
73 {
74   std::string aWType = myWidgetApi->widgetType();
75   if (aWType == NODE_FEATURE) {
76     QWidget* aPanel = createPanel(thePage->pageWidget());
77     thePage->addWidget(aPanel);
78     return;
79   }
80
81   if (!myWidgetApi->toChildWidget())
82     return;
83
84   do {  //Iterate over each node
85     std::string aWdgType = myWidgetApi->widgetType();
86     // Create PageGroup TODO: extract
87     if (myWidgetApi->isGroupBoxWidget() ||
88         ModuleBase_WidgetCreatorFactory::get()->hasPageWidget(aWdgType)) {
89
90       //if current widget is groupbox (container) process it's children recursively
91       ModuleBase_PageBase* aPage = createPageByType(aWdgType, thePage->pageWidget());
92
93       createWidget(aPage);
94       thePage->addPageWidget(aPage);
95     } else {
96       // Create a ModelWidget
97       ModuleBase_ModelWidget* aWidget = createWidgetByType(aWdgType, thePage->pageWidget());
98       if (aWidget) {
99         if (!myWidgetApi->getBooleanAttribute(ATTR_INTERNAL, false)) {
100           thePage->addModelWidget(aWidget);
101         } else {
102           aWidget->setVisible(false);
103         }
104       }
105       // Create PagedContainer TODO: extract
106       if (myWidgetApi->isPagedWidget()) {
107         //If current widget is toolbox or switch-casebox then fetch all
108         //it's pages recursively and setup into the widget.
109         myWidgetApi->toChildWidget();
110         do {
111           QString aPageName = qs(myWidgetApi->getProperty(CONTAINER_PAGE_NAME));
112           QString aCaseId = qs(myWidgetApi->getProperty(_ID));
113           ModuleBase_PageBase* aPage = new ModuleBase_PageWidget(aWidget);
114           createWidget(aPage);
115           if (aWdgType == WDG_SWITCH || aWdgType == WDG_TOOLBOX) {
116             ModuleBase_PagedContainer* aContainer = qobject_cast<ModuleBase_PagedContainer*>(aWidget);
117
118             QString anIconPath = qs( myWidgetApi->getProperty( CONTAINER_PAGE_ICON ) );
119             QPixmap anIcon( anIconPath );
120             aContainer->addPage( aPage, aPageName, aCaseId, anIcon );
121           }
122         } while (myWidgetApi->toNextWidget());
123       }
124     }
125   } while (myWidgetApi->toNextWidget());
126
127   thePage->alignToTop();
128 }
129
130 void ModuleBase_WidgetFactory::createWidget(ModuleBase_PageBase* thePage,
131                                             const std::string& theWidgetId)
132 {
133   bool aFound = false;
134   moveToWidgetId(theWidgetId, aFound);
135   if (aFound) {
136     std::string aWdgType = myWidgetApi->widgetType();
137
138     // Create a ModelWidget
139     ModuleBase_ModelWidget* aWidget = createWidgetByType(aWdgType, thePage->pageWidget());
140     if (aWidget) {
141       if (!myWidgetApi->getBooleanAttribute(ATTR_INTERNAL, false)) {
142         thePage->addModelWidget(aWidget);
143       }
144       else {
145         aWidget->setVisible(false);
146       }
147     }
148   }
149   thePage->alignToTop();
150 }
151
152 void ModuleBase_WidgetFactory::getAttributeTitle(const std::string& theAttributeId,
153                                                  std::string& theTitle)
154 {
155   bool aFound = false;
156   moveToWidgetId(theAttributeId, aFound);
157   if (aFound) {
158     theTitle = QString::fromStdString(myWidgetApi->widgetLabel()).toStdString().c_str();
159     if (theTitle.empty())
160       theTitle = QString::fromStdString(myWidgetApi->getProperty(CONTAINER_PAGE_NAME)).toStdString().c_str();
161   }
162 }
163
164 void ModuleBase_WidgetFactory::getGreedAttribute(std::string& theAttributeId)
165 {
166   if (!theAttributeId.empty())
167     return;
168
169   if (!myWidgetApi->toChildWidget())
170     return;
171
172   do {  //Iterate over each node
173     std::string aWdgType = myWidgetApi->widgetType();
174     // Find title under PageGroup
175     if (myWidgetApi->isGroupBoxWidget() ||
176       ModuleBase_WidgetCreatorFactory::get()->hasPageWidget(aWdgType)) {
177       getGreedAttribute(theAttributeId);
178     }
179     else {
180       // Find title here
181       std::string anAttributeId = myWidgetApi->widgetId();
182       if (myWidgetApi->getBooleanAttribute(ATTR_GREED, false))
183         theAttributeId = anAttributeId;
184       if (theAttributeId.empty() && myWidgetApi->isPagedWidget()) {
185         //If current widget is toolbox or switch-casebox then fetch all
186         //it's pages recursively and setup into the widget.
187         myWidgetApi->toChildWidget();
188         do {
189           getGreedAttribute(theAttributeId);
190         } while (theAttributeId.empty() && myWidgetApi->toNextWidget());
191       }
192     }
193   } while (theAttributeId.empty() && myWidgetApi->toNextWidget());
194 }
195
196 void ModuleBase_WidgetFactory::moveToWidgetId(const std::string& theWidgetId, bool& theFound)
197 {
198   if (theFound)
199     return;
200
201   if (!myWidgetApi->toChildWidget())
202     return;
203
204   do {  //Iterate over each node
205     std::string aWdgType = myWidgetApi->widgetType();
206     // Find title under PageGroup
207     if (myWidgetApi->isGroupBoxWidget() ||
208       ModuleBase_WidgetCreatorFactory::get()->hasPageWidget(aWdgType)) {
209       moveToWidgetId(theWidgetId, theFound);
210     }
211     else {
212       // Find title here
213       std::string anAttributeId = myWidgetApi->widgetId();
214       theFound = anAttributeId == theWidgetId;
215       if (!theFound && myWidgetApi->isPagedWidget()) {
216         //If current widget is toolbox or switch-casebox then fetch all
217         //it's pages recursively and setup into the widget.
218         myWidgetApi->toChildWidget();
219         do {
220           moveToWidgetId(theWidgetId, theFound);
221         } while (!theFound && myWidgetApi->toNextWidget());
222       }
223     }
224   } while (!theFound && myWidgetApi->toNextWidget());
225 }
226
227 QWidget* ModuleBase_WidgetFactory::createPanel(QWidget* theParent)
228 {
229   QWidget* aPanel = 0;
230   std::string aPanelName = myWidgetApi->getProperty(PROPERTY_PANEL_ID);
231   if (!aPanelName.empty() && ModuleBase_WidgetCreatorFactory::get()->hasPanelWidget(aPanelName))
232     aPanel = ModuleBase_WidgetCreatorFactory::get()->createPanel(aPanelName, theParent);
233   return aPanel;
234 }
235
236 ModuleBase_PageBase* ModuleBase_WidgetFactory::createPageByType(const std::string& theType,
237                                                                 QWidget* theParent)
238 {
239   ModuleBase_PageBase* aResult = NULL;
240
241   if (theType == WDG_GROUP) {
242     QString aGroupName = qs(myWidgetApi->getProperty(CONTAINER_PAGE_NAME));
243     ModuleBase_PageGroupBox* aPage = new ModuleBase_PageGroupBox(theParent);
244     aPage->setTitle(aGroupName);
245     aResult = aPage;
246   }
247   else if (theType == WDG_CHECK_GROUP) {
248     QString aGroupName = qs(myWidgetApi->getProperty(CONTAINER_PAGE_NAME));
249     ModuleBase_WidgetCheckGroupBox* aPage = new ModuleBase_WidgetCheckGroupBox(theParent,
250                                                                 myWidgetApi);
251     aPage->setTitle(aGroupName);
252     aResult = aPage;
253   }
254   if (!aResult)
255     aResult = ModuleBase_WidgetCreatorFactory::get()->createPageByType(theType, theParent,
256                                                                        myWidgetApi);
257
258   ModuleBase_ModelWidget* aWidget = dynamic_cast<ModuleBase_ModelWidget*>(aResult);
259   if (aWidget)
260     myModelWidgets.append(aWidget);
261
262   return aResult;
263 }
264
265 ModuleBase_ModelWidget* ModuleBase_WidgetFactory::createWidgetByType(const std::string& theType,
266                                                                      QWidget* theParent)
267 {
268   ModuleBase_ModelWidget* result = NULL;
269
270   if (theType == WDG_INFO) {
271     result = new ModuleBase_WidgetLabel(theParent, myWidgetApi);
272   } else if (theType == WDG_ERRORINFO) {
273     result = new ModuleBase_WidgetErrorLabel(theParent, myWidgetApi);
274   } else if (theType == WDG_DOUBLEVALUE) {
275     result = new ModuleBase_WidgetDoubleValue(theParent, myWidgetApi);
276   } else if (theType == WDG_INTEGERVALUE) {
277     result = new ModuleBase_WidgetIntValue(theParent, myWidgetApi);
278   } else if (theType == WDG_SHAPE_SELECTOR) {
279     result = new ModuleBase_WidgetShapeSelector(theParent, myWorkshop, myWidgetApi);
280   } else if (theType == WDG_BOOLVALUE) {
281     result = new ModuleBase_WidgetBoolValue(theParent, myWidgetApi);
282   //} else if (theType == WDG_DOUBLEVALUE_EDITOR) {
283   //  result = new ModuleBase_WidgetEditor(theParent, myWidgetApi);
284   } else if (theType == WDG_FILE_SELECTOR) {
285     result = new ModuleBase_WidgetFileSelector(theParent, myWidgetApi);
286   } else if (theType == WDG_CHOICE) {
287     result = new ModuleBase_WidgetChoice(theParent, myWidgetApi);
288   } else if (theType == WDG_STRINGVALUE) {
289     std::string aPlaceHolder = myWidgetApi->getProperty( WDG_PLACE_HOLDER );
290     result = new ModuleBase_WidgetLineEdit( theParent, myWidgetApi, aPlaceHolder );
291   } else if (theType == WDG_EXPR_EDITOR) {
292     std::string aPlaceHolder = myWidgetApi->getProperty( WDG_PLACE_HOLDER );
293     result = new ModuleBase_WidgetExprEditor( theParent, myWidgetApi, aPlaceHolder );
294   } else if (theType == WDG_MULTISELECTOR) {
295     result = new ModuleBase_WidgetMultiSelector(theParent, myWorkshop, myWidgetApi);
296   } else if (theType == WDG_TOOLBOX) {
297     result = new ModuleBase_WidgetToolbox(theParent, myWidgetApi);
298   } else if (theType == WDG_SWITCH) {
299     result = new ModuleBase_WidgetSwitch(theParent, myWidgetApi);
300   } else if (theType == WDG_TOOLBOX_BOX || theType == WDG_SWITCH_CASE ||
301              theType == NODE_VALIDATOR) {
302     // Do nothing for "box" and "case"
303     result = NULL;
304   } else {
305     result = myWorkshop->module()->createWidgetByType(theType, theParent, myWidgetApi);
306     if (!result)
307       result = ModuleBase_WidgetCreatorFactory::get()->createWidgetByType(theType, theParent,
308                                                               myWidgetApi, myWorkshop);
309     #ifdef _DEBUG
310     if (!result) {
311       qDebug("ModuleBase_WidgetFactory::fillWidget: find bad widget type %s", theType.c_str());
312     }
313     #endif
314   }
315   if (result)
316     myModelWidgets.append(result);
317   return result;
318 }
319
320 QString ModuleBase_WidgetFactory::qs(const std::string& theStdString)
321 {
322   return QString::fromStdString(theStdString);
323 }
324