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