]> SALOME platform Git repositories - modules/shaper.git/blob - src/ModuleBase/ModuleBase_ModelWidget.cpp
Salome HOME
c84b8e6462063d7de4692decf84aea7ed3365414
[modules/shaper.git] / src / ModuleBase / ModuleBase_ModelWidget.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
2
3 // File:        ModuleBase_ModelWidget.cpp
4 // Created:     25 Apr 2014
5 // Author:      Natalia ERMOLAEVA
6
7 #include "ModuleBase_ModelWidget.h"
8
9 #include <ModelAPI_Data.h>
10 #include <ModelAPI_Attribute.h>
11 #include <ModelAPI_Events.h>
12 #include <ModelAPI_Session.h>
13
14 #include <Config_Keywords.h>
15 #include <Config_WidgetAPI.h>
16
17 #include <Events_Loop.h>
18
19 #include <QEvent>
20 #include <QGraphicsDropShadowEffect>
21 #include <QColor>
22 #include <QLabel>
23 #include <QFocusEvent>
24
25 ModuleBase_ModelWidget::ModuleBase_ModelWidget(QWidget* theParent,
26                                                const Config_WidgetAPI* theData,
27                                                const std::string& theParentId)
28     : QWidget(theParent),
29       myParentId(theParentId),
30       myIsEditing(false),
31       myState(Stored)
32 {
33   myDefaultValue = theData->getProperty(ATTR_DEFAULT);
34   myUseReset = theData->getBooleanAttribute(ATTR_USE_RESET, true);
35   myIsComputedDefault = theData->getProperty(ATTR_DEFAULT) == DOUBLE_WDG_DEFAULT_COMPUTED;
36   myAttributeID = theData ? theData->widgetId() : "";
37   myIsObligatory = theData->getBooleanAttribute(ATTR_OBLIGATORY, true);
38
39   connect(this, SIGNAL(valuesChanged()), this, SLOT(onWidgetValuesChanged()));
40   connect(this, SIGNAL(valuesModified()), this, SLOT(onWidgetValuesModified()));
41 }
42
43 bool ModuleBase_ModelWidget::reset()
44 {
45   bool aResult = resetCustom();
46   if (aResult)
47     setValueState(Reset);
48
49   return aResult;
50 }
51
52 bool ModuleBase_ModelWidget::isInitialized(ObjectPtr theObject) const
53 {
54   return theObject->data()->attribute(attributeID())->isInitialized();
55 }
56
57 void ModuleBase_ModelWidget::enableFocusProcessing()
58 {
59   QList<QWidget*> aMyControls = getControls();
60   foreach(QWidget*  eachControl, aMyControls) {
61     if (myIsObligatory) {
62       eachControl->setFocusPolicy(Qt::StrongFocus);
63       eachControl->installEventFilter(this);
64     }
65     else {
66       eachControl->setFocusPolicy(Qt::NoFocus);
67     }
68   }
69 }
70
71 void ModuleBase_ModelWidget::setHighlighted(bool isHighlighted)
72 {
73   QList<QWidget*> aWidgetList = getControls();
74   foreach(QWidget* aWidget, aWidgetList) {
75     QLabel* aLabel = qobject_cast<QLabel*>(aWidget);
76     // We won't set the effect to QLabels - it looks ugly
77     if(aLabel) continue;
78     if(isHighlighted) {
79       // If effect is the installed on a different widget, setGraphicsEffect() will
80       // remove the effect from the widget and install it on this widget.
81       // That's why we create a new effect for each widget
82       QGraphicsDropShadowEffect* aGlowEffect = new QGraphicsDropShadowEffect();
83       aGlowEffect->setOffset(.0);
84       aGlowEffect->setBlurRadius(10.0);
85       aGlowEffect->setColor(QColor(0, 170, 255)); // Light-blue color, #00AAFF
86       aWidget->setGraphicsEffect(aGlowEffect);
87     } else {
88       QGraphicsEffect* anEffect = aWidget->graphicsEffect();
89       if(anEffect)
90         anEffect->deleteLater();
91       aWidget->setGraphicsEffect(NULL);
92     }
93   }
94 }
95
96 void ModuleBase_ModelWidget::setFeature(const FeaturePtr& theFeature, const bool theToStoreValue)
97 {
98   myFeature = theFeature;
99   if (theToStoreValue)
100     storeValue();
101 }
102
103 bool ModuleBase_ModelWidget::focusTo()
104 {
105   QList<QWidget*> aControls = getControls();
106   QList<QWidget*>::const_iterator anIt = aControls.begin(), aLast = aControls.end();
107   bool isFocusAccepted = false;
108   for (; anIt != aLast && !isFocusAccepted; anIt++) {
109     QWidget* aWidget = *anIt;
110     if (aWidget && aWidget->focusPolicy() != Qt::NoFocus) {
111       aWidget->setFocus();
112       isFocusAccepted = true;
113     }
114   }
115   return isFocusAccepted;
116 }
117
118 void ModuleBase_ModelWidget::activate()
119 {
120   // the control value is stored to the mode by the focus in on the widget
121   // we need the value is initialized in order to enable the apply button in the property panel.
122   // It should happens in the creation mode only because all fields are filled in the edition mode
123   if (!isEditingMode()) {
124     AttributePtr anAttribute = myFeature->data()->attribute(myAttributeID);
125     if (anAttribute.get() != NULL && !anAttribute->isInitialized())
126       initializeValueByActivate();
127   }
128   activateCustom();
129 }
130
131 void ModuleBase_ModelWidget::initializeValueByActivate()
132 {
133   if (isComputedDefault()) {
134     if (myFeature->compute(myAttributeID)) {
135       restoreValue();
136     }
137   }
138   else {
139     storeValue();
140   }
141 }
142
143 QWidget* ModuleBase_ModelWidget::getControlAcceptingFocus(const bool isFirst)
144 {
145   QWidget* aControl = 0;
146
147   QList<QWidget*> aControls = getControls();
148   int aSize = aControls.size();
149
150   if (isFirst) {
151     for (int i = 0; i < aSize && !aControl; i++)  {
152       if (aControls[i]->focusPolicy() != Qt::NoFocus)
153         aControl = aControls[i];
154     }
155   }
156   else {
157     for (int i = aSize - 1; i >= 0 && !aControl; i--)  {
158       if (aControls[i]->focusPolicy() != Qt::NoFocus)
159         aControl = aControls[i];
160     }
161   }
162   return aControl;
163 }
164
165 void ModuleBase_ModelWidget::setDefaultValue(const std::string& theValue)
166 {
167   myDefaultValue = theValue;
168 }
169
170 bool ModuleBase_ModelWidget::storeValue()
171 {
172   setValueState(Stored);
173
174   emit beforeValuesChanged();
175   bool isDone = storeValueCustom();
176   emit afterValuesChanged();
177
178   return isDone;
179 }
180
181 void ModuleBase_ModelWidget::setValueState(const ValueState& theState)
182 {
183   if (myState == theState)
184     return;
185
186   myState = theState;
187   emit valueStateChanged();
188 }
189
190 bool ModuleBase_ModelWidget::restoreValue()
191 {
192   emit beforeValuesRestored();
193   bool isDone = restoreValueCustom();
194   emit afterValuesRestored();
195
196   return isDone;
197 }
198
199 void ModuleBase_ModelWidget::storeValueByApply()
200 {
201   // do not emit signal about update the currenty feature object
202   // in order to do not perform additional redisplay in the viewer.
203   // It should happens by finish operation of the apply action
204   storeValueCustom();
205 }
206
207 void ModuleBase_ModelWidget::updateObject(ObjectPtr theObj)
208 {
209   blockUpdateViewer(true);
210
211   Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
212
213   blockUpdateViewer(false);
214 }
215
216 void ModuleBase_ModelWidget::moveObject(ObjectPtr theObj)
217 {
218   //blockUpdateViewer(true);
219
220   static Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_MOVED);
221   ModelAPI_EventCreator::get()->sendUpdated(theObj, anEvent);
222   Events_Loop::loop()->flush(anEvent);
223
224   //blockUpdateViewer(false);
225 }
226
227 bool ModuleBase_ModelWidget::processEnter()
228 {
229   return false;
230 }
231
232 bool ModuleBase_ModelWidget::eventFilter(QObject* theObject, QEvent *theEvent)
233 {
234   QWidget* aWidget = qobject_cast<QWidget*>(theObject);
235   if (theEvent->type() == QEvent::FocusIn) {
236     #ifdef _DEBUG
237     // The following two lines are for debugging purpose only
238     QFocusEvent* aFocusEvent = dynamic_cast<QFocusEvent*>(theEvent);
239     bool isWinFocus = aFocusEvent->reason() == Qt::ActiveWindowFocusReason;
240     #endif
241     if (getControls().contains(aWidget)) {
242       emit focusInWidget(this);
243     }
244   }
245   // pass the event on to the parent class
246
247   return QObject::eventFilter(theObject, theEvent);
248 }
249
250 //**************************************************************
251 void ModuleBase_ModelWidget::onWidgetValuesChanged()
252 {
253   storeValue();
254 }
255
256 //**************************************************************
257 void ModuleBase_ModelWidget::onWidgetValuesModified()
258 {
259   setValueState(Modified);
260 }
261
262 //**************************************************************
263 void ModuleBase_ModelWidget::blockUpdateViewer(const bool theValue)
264 {
265   // the viewer update should be blocked in order to avoid the temporary feature content
266   // when the solver processes the feature, the redisplay message can be flushed
267   // what caused the display in the viewer preliminary states of object
268   // e.g. fillet feature, angle value change
269   std::shared_ptr<Events_Message> aMsg;
270   if (theValue) {
271     aMsg = std::shared_ptr<Events_Message>(
272         new Events_Message(Events_Loop::eventByName(EVENT_UPDATE_VIEWER_BLOCKED)));
273   }
274   else {
275     // the viewer update should be unblocked
276     aMsg = std::shared_ptr<Events_Message>(
277         new Events_Message(Events_Loop::eventByName(EVENT_UPDATE_VIEWER_UNBLOCKED)));
278   }
279   Events_Loop::loop()->send(aMsg);
280 }