Salome HOME
Fix SketcherSetEqual.test_length_equality
[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 {
32   myDefaultValue = theData->getProperty(ATTR_DEFAULT);
33   myUseReset = theData->getBooleanAttribute(ATTR_USE_RESET, true);
34   myIsComputedDefault = theData->getProperty(ATTR_DEFAULT) == DOUBLE_WDG_DEFAULT_COMPUTED;
35   myAttributeID = theData ? theData->widgetId() : "";
36   myIsObligatory = theData->getBooleanAttribute(ATTR_OBLIGATORY, true);
37
38   connect(this, SIGNAL(valuesChanged()), this, SLOT(onWidgetValuesChanged()));
39 }
40
41 bool ModuleBase_ModelWidget::isInitialized(ObjectPtr theObject) const
42 {
43   return theObject->data()->attribute(attributeID())->isInitialized();
44 }
45
46 void ModuleBase_ModelWidget::enableFocusProcessing()
47 {
48   QList<QWidget*> aMyControls = getControls();
49   foreach(QWidget*  eachControl, aMyControls) {
50     if (myIsObligatory) {
51       eachControl->setFocusPolicy(Qt::StrongFocus);
52       eachControl->installEventFilter(this);
53     }
54     else {
55       eachControl->setFocusPolicy(Qt::NoFocus);
56     }
57   }
58 }
59
60 void ModuleBase_ModelWidget::setHighlighted(bool isHighlighted)
61 {
62   QList<QWidget*> aWidgetList = getControls();
63   foreach(QWidget* aWidget, aWidgetList) {
64     QLabel* aLabel = qobject_cast<QLabel*>(aWidget);
65     // We won't set the effect to QLabels - it looks ugly
66     if(aLabel) continue;
67     if(isHighlighted) {
68       // If effect is the installed on a different widget, setGraphicsEffect() will
69       // remove the effect from the widget and install it on this widget.
70       // That's why we create a new effect for each widget
71       QGraphicsDropShadowEffect* aGlowEffect = new QGraphicsDropShadowEffect();
72       aGlowEffect->setOffset(.0);
73       aGlowEffect->setBlurRadius(10.0);
74       aGlowEffect->setColor(QColor(0, 170, 255)); // Light-blue color, #00AAFF
75       aWidget->setGraphicsEffect(aGlowEffect);
76     } else {
77       QGraphicsEffect* anEffect = aWidget->graphicsEffect();
78       if(anEffect)
79         anEffect->deleteLater();
80       aWidget->setGraphicsEffect(NULL);
81     }
82   }
83 }
84
85 void ModuleBase_ModelWidget::setFeature(const FeaturePtr& theFeature, const bool theToStoreValue)
86 {
87   myFeature = theFeature;
88   if (theToStoreValue)
89     storeValue();
90 }
91
92 bool ModuleBase_ModelWidget::focusTo()
93 {
94   QList<QWidget*> aControls = getControls();
95   QList<QWidget*>::const_iterator anIt = aControls.begin(), aLast = aControls.end();
96   bool isFocusAccepted = false;
97   for (; anIt != aLast && !isFocusAccepted; anIt++) {
98     QWidget* aWidget = *anIt;
99     if (aWidget && aWidget->focusPolicy() != Qt::NoFocus) {
100       aWidget->setFocus();
101       isFocusAccepted = true;
102     }
103   }
104   return isFocusAccepted;
105 }
106
107 void ModuleBase_ModelWidget::activate()
108 {
109   // the control value is stored to the mode by the focus in on the widget
110   // we need the value is initialized in order to enable the apply button in the property panel.
111   // It should happens in the creation mode only because all fields are filled in the edition mode
112   if (!isEditingMode()) {
113     AttributePtr anAttribute = myFeature->data()->attribute(myAttributeID);
114     if (anAttribute.get() != NULL && !anAttribute->isInitialized()) {
115       if (isComputedDefault()) {
116         if (myFeature->compute(myAttributeID)) {
117           restoreValue();
118         }
119       }
120       else {
121         storeValue();
122       }
123     }
124   }
125   activateCustom();
126 }
127
128 void ModuleBase_ModelWidget::setDefaultValue(const std::string& theValue)
129 {
130   myDefaultValue = theValue;
131 }
132
133 bool ModuleBase_ModelWidget::storeValue()
134 {
135   emit beforeValuesChanged();
136   bool isDone = storeValueCustom();
137   emit afterValuesChanged();
138
139   return isDone;
140 }
141
142 bool ModuleBase_ModelWidget::restoreValue()
143 {
144   emit beforeValuesRestored();
145   bool isDone = restoreValueCustom();
146   emit afterValuesRestored();
147
148   return isDone;
149 }
150
151 void ModuleBase_ModelWidget::updateObject(ObjectPtr theObj)
152 {
153   blockUpdateViewer(true);
154
155   Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_UPDATED));
156
157   blockUpdateViewer(false);
158 }
159
160 void ModuleBase_ModelWidget::moveObject(ObjectPtr theObj)
161 {
162   blockUpdateViewer(true);
163
164   static Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_MOVED);
165   ModelAPI_EventCreator::get()->sendUpdated(theObj, anEvent);
166   Events_Loop::loop()->flush(anEvent);
167
168   blockUpdateViewer(false);
169 }
170
171 bool ModuleBase_ModelWidget::eventFilter(QObject* theObject, QEvent *theEvent)
172 {
173   QWidget* aWidget = qobject_cast<QWidget*>(theObject);
174   if (theEvent->type() == QEvent::FocusIn) {
175     #ifdef _DEBUG
176     // The following two lines are for debugging purpose only
177     QFocusEvent* aFocusEvent = dynamic_cast<QFocusEvent*>(theEvent);
178     bool isWinFocus = aFocusEvent->reason() == Qt::ActiveWindowFocusReason;
179     #endif
180     if (getControls().contains(aWidget)) {
181       emit focusInWidget(this);
182     }
183   }
184   // pass the event on to the parent class
185
186   return QObject::eventFilter(theObject, theEvent);
187 }
188
189 //**************************************************************
190 void ModuleBase_ModelWidget::onWidgetValuesChanged()
191 {
192   storeValue();
193 }
194
195 //**************************************************************
196 void ModuleBase_ModelWidget::blockUpdateViewer(const bool theValue)
197 {
198   // the viewer update should be blocked in order to avoid the temporary feature content
199   // when the solver processes the feature, the redisplay message can be flushed
200   // what caused the display in the viewer preliminary states of object
201   // e.g. fillet feature, angle value change
202   std::shared_ptr<Events_Message> aMsg;
203   if (theValue) {
204     aMsg = std::shared_ptr<Events_Message>(
205         new Events_Message(Events_Loop::eventByName(EVENT_UPDATE_VIEWER_BLOCKED)));
206   }
207   else {
208     // the viewer update should be unblocked
209     aMsg = std::shared_ptr<Events_Message>(
210         new Events_Message(Events_Loop::eventByName(EVENT_UPDATE_VIEWER_UNBLOCKED)));
211   }
212   Events_Loop::loop()->send(aMsg);
213 }