]> SALOME platform Git repositories - modules/yacs.git/blob - src/genericgui/SceneNodeItem.cxx
Salome HOME
mergefrom branch BR_V511_PR tag mergeto_trunk_03feb09
[modules/yacs.git] / src / genericgui / SceneNodeItem.cxx
1 //  Copyright (C) 2006-2008  CEA/DEN, EDF R&D
2 //
3 //  This library is free software; you can redistribute it and/or
4 //  modify it under the terms of the GNU Lesser General Public
5 //  License as published by the Free Software Foundation; either
6 //  version 2.1 of the License.
7 //
8 //  This library is distributed in the hope that it will be useful,
9 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
10 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 //  Lesser General Public License for more details.
12 //
13 //  You should have received a copy of the GNU Lesser General Public
14 //  License along with this library; if not, write to the Free Software
15 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 #include "SceneNodeItem.hxx"
20 #include "SceneComposedNodeItem.hxx"
21 #include "SceneHeaderNodeItem.hxx"
22 #include "SceneInPortItem.hxx"
23 #include "SceneOutPortItem.hxx"
24 #include "SceneCtrlInPortItem.hxx"
25 #include "SceneCtrlOutPortItem.hxx"
26 #include "Scene.hxx"
27 #include "QtGuiContext.hxx"
28 #include "Menus.hxx"
29
30 #include "Switch.hxx"
31
32 #include <QGraphicsSceneHoverEvent>
33 #include <QPointF>
34
35 #include <sstream>
36 #include <cassert>
37
38 //#define _DEVDEBUG_
39 #include "YacsTrace.hxx"
40
41 using namespace std;
42 using namespace YACS::ENGINE;
43 using namespace YACS::HMI;
44
45 SceneNodeItem::SceneNodeItem(QGraphicsScene *scene, SceneItem *parent,
46                              QString label, Subject *subject)
47   : SceneObserverItem(scene, parent, label, subject)
48 {
49   _inPorts.clear();
50   _outPorts.clear();
51   _header = 0;
52   _height = 50 + 2*_nml;
53   _width = 2*ScenePortItem::getPortWidth() + 3*_margin + 2*_nml;
54   _brushColor = QColor(0,0,128);
55   _moving = false;
56   _hasNml = true;
57   _dragable = true;
58   _dragButton = Qt::MidButton;
59   _execState = YACS::UNDEFINED;
60 }
61
62 SceneNodeItem::~SceneNodeItem()
63 {
64   if (SceneComposedNodeItem* parent = getParent())
65     parent->removeChildFromList(this);
66 }
67
68 void SceneNodeItem::setWidth(qreal width)
69 {
70   _width = width;
71   adjustHeader();
72 }
73
74 void SceneNodeItem::setHeight(qreal height)
75 {
76   _height = height;
77 }
78
79 void SceneNodeItem::addHeader()
80 {
81   DEBTRACE("SceneNodeItem::addHeader " << _label.toStdString());
82   if (!_hasHeader)
83     {
84       _hasHeader = true;
85       _header = new SceneHeaderNodeItem(_scene,
86                                         this,
87                                         getHeaderLabel());
88       updateState();
89       QPointF topLeft(_margin + _nml, _margin + _nml);
90       _header->setTopLeft(topLeft);
91       checkGeometryChange();
92     }
93 }
94
95 SceneHeaderItem* SceneNodeItem::getHeader()
96 {
97   return _header;
98 }
99
100 void SceneNodeItem::paint(QPainter *painter,
101                           const QStyleOptionGraphicsItem *option,
102                           QWidget *widget)
103 {
104   //DEBTRACE("SceneNodeItem::paint");
105   painter->save();
106   painter->setBrush(QBrush(Qt::NoBrush));
107   painter->setPen(QPen(Qt::NoPen));
108   painter->drawRect(QRectF(0, 0, _width, _height));
109
110   painter->setPen(getPenColor());
111   painter->setBrush(getBrushColor());
112   painter->drawRect(QRectF(_nml, _nml,
113                            _width-2*_nml, _height-2*_nml));
114   painter->restore();
115 }
116
117 void SceneNodeItem::update(GuiEvent event, int type, Subject* son)
118 {
119   DEBTRACE("SceneNodeItem::update "<< eventName(event)<<" "<<type<<" "<<son);
120   SubjectNode *snode = 0;
121   Node *node = 0;
122   switch (event)
123     {
124     case YACS::HMI::RENAME:
125       DEBTRACE("SceneNodeItem::update RENAME " << _subject->getName());
126       updateName();
127       break;
128     case YACS::HMI::EDIT:
129       if (_header) _header->setEdited(type);
130       break;
131     case YACS::HMI::UPDATE:
132       updateState();
133       break;
134     case YACS::HMI::UPDATEPROGRESS:
135       setExecState(type);
136       break;
137     default:
138       ;
139     }
140 }
141
142 //! generic method to compute a graph for child nodes. implemented in some derived classes
143 void SceneNodeItem::arrangeNodes(bool isRecursive)
144 {
145 }
146
147 void SceneNodeItem::arrangeChildNodes()
148 {
149 }
150
151 qreal SceneNodeItem::getHeaderBottom()
152 {
153   qreal bottom = 0;
154   if (_hasHeader)
155     bottom = childBoundingRect(_header).bottom();
156   return bottom;
157 }
158
159 void SceneNodeItem::autoPosNewPort(AbstractSceneItem *item, int nbPorts)
160 {
161   SceneInPortItem* inPortItem = dynamic_cast<SceneInPortItem*>(item);
162   bool isInPort = (inPortItem != 0);
163
164   qreal xLeft = _margin + _nml;
165   if (!isInPort) xLeft += ScenePortItem::getPortWidth() + _margin + _nml;
166
167   qreal yTop  = getHeaderBottom() + _margin;
168   yTop += nbPorts *(ScenePortItem::getPortHeight() + _margin);
169
170   DEBTRACE("left, top " << xLeft  << " " << yTop);
171   QPointF topLeft(xLeft, yTop);
172   item->setTopLeft(topLeft);
173 }
174
175 void SceneNodeItem::popupMenu(QWidget *caller, const QPoint &globalPos)
176 {
177   NodeMenu m;
178   m.popupMenu(caller, globalPos);
179 }
180
181 SceneComposedNodeItem* SceneNodeItem::getParent()
182 {
183   if (_parent)
184     return dynamic_cast<SceneComposedNodeItem*>(_parent);
185   else
186     return 0;
187 }
188 void SceneNodeItem::removeInPortFromList(AbstractSceneItem* inPort)
189 {
190   _inPorts.remove(inPort);
191 }
192
193 void SceneNodeItem::removeOutPortFromList(AbstractSceneItem* outPort)
194 {
195   _outPorts.remove(outPort);
196 }
197
198 void SceneNodeItem::setMoving(bool moving)
199 {
200   //DEBTRACE("SceneNodeItem::setMoving " << _label.toStdString() << " " << moving);
201   _moving = moving;
202   SceneNodeItem *nodep = 0;
203   if (_parent && (nodep = dynamic_cast<SceneNodeItem*>(_parent)))
204     nodep->setMoving(false);
205 }
206
207 ScenePortItem* SceneNodeItem::getCtrlInPortItem()
208 {
209   if (! _header) return 0;
210   return _header->getCtrlInPortItem();
211 }
212
213 ScenePortItem* SceneNodeItem::getCtrlOutPortItem()
214 {
215   if (! _header) return 0;
216   return _header->getCtrlOutPortItem();
217 }
218
219 void SceneNodeItem::updateName()
220 {
221   if (_header) _header->setText(getHeaderLabel());
222 }
223
224 QString SceneNodeItem::getMimeFormat()
225 {
226   return "yacs/subjectNode";
227 }
228
229 void SceneNodeItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
230 {
231   DEBTRACE("SceneNodeItem::mousePressEvent " << _label.toStdString());
232   SceneObserverItem::mousePressEvent(event);
233   if (!_scene->isZooming())
234     {
235       if (!_draging) setMoving(true);
236       _prevPos = pos();
237     }
238 }
239
240 void SceneNodeItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
241 {
242   //DEBTRACE("SceneNodeItem::mouseReleaseEvent " << _label.toStdString());
243   SceneObserverItem::mouseReleaseEvent(event);
244   setMoving(false);
245   if ((pos() != _prevPos) && Scene::_autoComputeLinks)
246     {
247       YACS::HMI::SubjectProc* subproc = QtGuiContext::getQtCurrent()->getSubjectProc();
248       SceneItem *item = QtGuiContext::getQtCurrent()->_mapOfSceneItem[subproc];
249       SceneComposedNodeItem *proc = dynamic_cast<SceneComposedNodeItem*>(item);
250       proc->rebuildLinks();
251     }
252 }
253
254 void SceneNodeItem::mouseMoveEvent(QGraphicsSceneMouseEvent * event)
255 {
256   SceneObserverItem::mouseMoveEvent(event);
257   if (_moving)
258     {
259       if (SceneComposedNodeItem *bloc = dynamic_cast<SceneComposedNodeItem*>(_parent))
260         {
261           QPointF oldPos = pos();
262           QPointF aPos = oldPos + event->scenePos() - event->lastScenePos();
263           if (aPos.x() < _margin + _nml)
264             aPos.setX(_margin + _nml);
265           if (aPos.y() < _margin + bloc->getHeaderBottom() + _nml)
266             aPos.setY(_margin + bloc->getHeaderBottom() + _nml);
267           setTopLeft(aPos);
268           bloc->collisionResolv(this, oldPos);
269         }
270     }
271 }
272
273 void SceneNodeItem::setTopLeft(QPointF topLeft)
274 {
275   QPointF oldPos = pos();
276   setPos(topLeft);
277   if (_parent)
278     {
279       if (SceneComposedNodeItem *bloc = dynamic_cast<SceneComposedNodeItem*>(_parent))
280         bloc->collisionResolv(this, oldPos);
281       _parent->checkGeometryChange();
282     }
283 }
284
285 void SceneNodeItem::adjustHeader()
286 {
287   if (_header) _header->adjustGeometry();
288 }
289
290  void SceneNodeItem::updateState()
291 {
292   SubjectNode *snode = dynamic_cast<SubjectNode*>(_subject);
293   assert(snode);
294   Node *node = snode->getNode();
295   assert(node);
296   switch (node->getState())
297     {
298     case YACS::INVALID:
299       if (_header) _header->setValid(false);
300       break;
301     case YACS::READY:
302       if (_header) _header->setValid(true);
303       break;
304     default:
305       break;
306     }
307 }
308
309 void SceneNodeItem::setExecState(int execState)
310 {
311   DEBTRACE("SceneNodeItem::setExecState " << execState);
312   _execState = execState;
313   if (_header) _header->setExecState(execState);
314 }
315
316 QString SceneNodeItem::getHeaderLabel()
317 {
318   QString extLabel = _subject->getName().c_str();
319
320   SceneObserverItem *soi = 0;
321   SubjectSwitch* sswi = 0;
322
323   if ((_parent)
324       && (soi = dynamic_cast<SceneObserverItem*>(_parent))
325       && (sswi = dynamic_cast<SubjectSwitch*>(soi->getSubject())))
326     {
327       Switch *aswi = dynamic_cast<Switch*>(sswi->getNode());
328       SubjectNode *sno = dynamic_cast<SubjectNode*>(_subject);
329       int idcase = aswi->getRankOfNode(sno->getNode());
330       stringstream caseid;
331       if (idcase == Switch::ID_FOR_DEFAULT_NODE)
332         caseid << "default";
333       else
334         caseid << idcase;
335       extLabel += " (";
336       //extLabel += aswi->getCaseId(sno->getNode()).c_str();
337       extLabel += caseid.str().c_str();
338       extLabel += ")";
339       DEBTRACE(extLabel.toStdString());
340     }
341
342   return extLabel;
343 }