Salome HOME
Synchronize adm files
[modules/yacs.git] / src / genericgui / SceneElementaryNodeItem.cxx
1 // Copyright (C) 2006-2014  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, or (at your option) any later version.
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
20 #include "SceneElementaryNodeItem.hxx"
21 #include "SceneInPortItem.hxx"
22 #include "SceneOutPortItem.hxx"
23 #include "SceneComposedNodeItem.hxx"
24 #include "guiObservers.hxx"
25 #include "commandsProc.hxx"
26 #include "Scene.hxx"
27 #include "ElementaryNode.hxx"
28 #include "InputPort.hxx"
29 #include "OutputPort.hxx"
30
31 #include "QtGuiContext.hxx"
32 #include "Menus.hxx"
33
34 #include "Resource.hxx"
35
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 SceneElementaryNodeItem::SceneElementaryNodeItem(QGraphicsScene *scene, SceneItem *parent,
46                                              QString label, Subject *subject)
47   : SceneNodeItem(scene, parent, label, subject)
48 {
49   _maxPorts = 0;
50   _width  = 2*Resource::Corner_Margin + 2*Resource::DataPort_Width + Resource::Space_Margin;
51   _height = Resource::Header_Height + Resource::Border_Margin;
52
53   _brushColor   = Resource::ElementaryNode_brush;
54   _hiBrushColor = Resource::ElementaryNode_hiBrush;
55   _penColor     = Resource::ElementaryNode_pen;
56   _hiPenColor   = Resource::ElementaryNode_hiPen;
57 }
58
59 SceneElementaryNodeItem::~SceneElementaryNodeItem()
60 {
61 }
62
63 //! SceneElementaryNodeItem cannot be resized (only ComposedNodeItem can)
64 void SceneElementaryNodeItem::setWidth(qreal width)
65 {
66 }
67
68 //! SceneElementaryNodeItem cannot be resized (only ComposedNodeItem can)
69 void SceneElementaryNodeItem::setHeight(qreal height)
70 {
71 }
72
73 void SceneElementaryNodeItem::paint(QPainter *painter,
74                           const QStyleOptionGraphicsItem *option,
75                           QWidget *widget)
76 {
77   //DEBTRACE("SceneElementaryNodeItem::paint");
78   painter->save();
79   QPen pen(getPenColor());
80   pen.setWidth(Resource::Thickness);
81   painter->setPen(pen);
82   painter->setBrush(getBrushColor());
83   int w = _width  - 2*Resource::Border_Margin;
84   int h = _height - 2*Resource::Border_Margin;
85   painter->drawRect(QRectF(Resource::Border_Margin, Resource::Border_Margin, w, h));
86   painter->restore();
87 }
88
89 void SceneElementaryNodeItem::update(GuiEvent event, int type, Subject* son)
90 {
91   DEBTRACE("SceneElementaryNodeItem::update "<< eventName(event)<<" "<<type<<" "<<son);
92   SceneNodeItem::update(event, type, son);
93   SceneItem *item;
94   switch (event)
95     {
96     case YACS::HMI::ADD:
97       switch (type)
98         {
99         case YACS::HMI::INPUTPORT:
100         case YACS::HMI::INPUTDATASTREAMPORT:
101           item =  new SceneInPortItem(_scene,
102                                       this,
103                                       son->getName().c_str(),
104                                       son);
105           autoPosNewPort(item, _inPorts.size());
106           _inPorts.push_back(item);
107           if (Scene::_autoComputeLinks && !QtGuiContext::getQtCurrent()->isLoading())
108             {
109               YACS::HMI::SubjectProc* subproc = QtGuiContext::getQtCurrent()->getSubjectProc();
110               SceneItem *item = QtGuiContext::getQtCurrent()->_mapOfSceneItem[subproc];
111               SceneComposedNodeItem *proc = dynamic_cast<SceneComposedNodeItem*>(item);
112               proc->rebuildLinks();
113             }
114           break;
115         case YACS::HMI::OUTPUTPORT:
116         case YACS::HMI::OUTPUTDATASTREAMPORT:
117           item =  new SceneOutPortItem(_scene,
118                                        this,
119                                        son->getName().c_str(),
120                                        son);
121           autoPosNewPort(item, _outPorts.size());
122           _outPorts.push_back(item);
123           if (Scene::_autoComputeLinks && !QtGuiContext::getQtCurrent()->isLoading())
124             {
125               YACS::HMI::SubjectProc* subproc = QtGuiContext::getQtCurrent()->getSubjectProc();
126               SceneItem *item = QtGuiContext::getQtCurrent()->_mapOfSceneItem[subproc];
127               SceneComposedNodeItem *proc = dynamic_cast<SceneComposedNodeItem*>(item);
128               proc->rebuildLinks();
129             }
130            break;
131 //         default:
132 //           DEBTRACE("SceneElementaryNodeItem::update() ADD, type not handled:" << type);
133         }
134       break;
135     case YACS::HMI::REMOVE:
136     case YACS::HMI::SYNCHRO:
137       reorganize();
138       break;
139 //     default:
140 //       DEBTRACE("SceneElementaryNodeItem::update(), event not handled:" << eventName(event));
141     }
142 }
143
144 void SceneElementaryNodeItem::autoPosNewPort(AbstractSceneItem *item, int nbPorts) {
145   DEBTRACE("SceneElementaryNodeItem::autoPosNewPort "<< _label.toStdString());
146   SceneInPortItem*   inPortItem = dynamic_cast<SceneInPortItem*>(item);
147   SceneOutPortItem* outPortItem = dynamic_cast<SceneOutPortItem*>(item);
148
149   bool toShow = (_shownState == expandShown);
150   if (toShow) {
151     qreal x;
152     if (inPortItem) {
153       x = Resource::Corner_Margin;
154       inPortItem->show();
155     } else {
156       x = Resource::Corner_Margin + Resource::DataPort_Width + Resource::Space_Margin;
157       outPortItem->show();
158     };
159     qreal y = Resource::Header_Height + nbPorts * (Resource::DataPort_Height + Resource::Space_Margin);
160
161     if (_maxPorts <= nbPorts) {
162       _maxPorts = nbPorts+1;
163       _height  = Resource::Header_Height + Resource::Border_Margin;
164       _height += _maxPorts * (Resource::DataPort_Height + Resource::Space_Margin);
165       _incHeight = _height; // must just be more than the actual increment of height
166       DEBTRACE("SceneElementaryNodeItem::autoPosNewPort _height=" << _height);
167     };
168
169     item->setTopLeft(QPointF(x, y));
170
171   } else {
172     _height = Resource::Header_Height + Resource::Border_Margin;
173     qreal y = Resource::Corner_Margin;
174     if (inPortItem) {
175       item->setTopLeft(QPointF(Resource::Corner_Margin, y));
176       inPortItem->hide();
177     } else {
178       item->setTopLeft(QPointF(Resource::Corner_Margin + Resource::DataPort_Width + Resource::Space_Margin, y));
179       outPortItem->hide();
180     };
181   };
182 }
183
184 void SceneElementaryNodeItem::popupMenu(QWidget *caller, const QPoint &globalPos)
185 {
186   ElementaryNodeMenu m;
187   m.popupMenu(caller, globalPos);
188 }
189
190 void SceneElementaryNodeItem::reorganizeShrinkExpand()
191 {
192   DEBTRACE("SceneElementaryNodeItem::reorganizeShrinkExpand " << isExpanded() << " "  << _label.toStdString());
193   shrinkExpandRecursive(isExpanded(), true);
194   if (Scene::_autoComputeLinks)
195     {
196       SubjectProc* subproc = QtGuiContext::getQtCurrent()->getSubjectProc();
197       SceneItem *item = QtGuiContext::getQtCurrent()->_mapOfSceneItem[subproc];
198       SceneComposedNodeItem *proc = dynamic_cast<SceneComposedNodeItem*>(item);
199       proc->rebuildLinks();
200     }
201 }
202
203 void SceneElementaryNodeItem::shrinkExpandRecursive(bool isExpanding, bool fromHere)
204 {
205   DEBTRACE("SceneElementaryNodeItem::shrinkExpandRecursive " << isExpanding << " " << fromHere << " "  << isExpanded() << " " << _label.toStdString());
206   if (isExpanding)
207     {
208       _ancestorShrinked = false;
209       if (isExpanded())
210         _shownState = expandShown;
211       else
212         _shownState = shrinkShown;
213     }
214   else
215     {
216       if (fromHere)
217         _shownState = shrinkShown;
218       else
219         {
220           _ancestorShrinked = true;
221           _shownState = shrinkHidden;
222         }
223     }
224
225   if (_shownState == shrinkHidden) // shrink of ancestor
226     setPos(0 ,0);
227   else
228     setPos(_expandedPos);
229
230   reorganize();
231 }
232
233 void SceneElementaryNodeItem::reorganize()
234 {
235   DEBTRACE("SceneElementaryNodeItem::reorganize() " << _label.toStdString());
236
237   SubjectNode* snode = dynamic_cast<SubjectNode*>(_subject);
238   ElementaryNode* father = dynamic_cast<ElementaryNode*>(snode->getNode());
239   YASSERT(father);
240
241   _maxPorts = 0;
242
243   list<InPort*> plisti = father->getSetOfInPort();
244   list<InPort*>::iterator iti = plisti.begin();
245   int nbPorts = 0;
246   for (; iti != plisti.end(); ++iti)
247     {
248       Subject *sub = QtGuiContext::getQtCurrent()->_mapOfSubjectDataPort[(*iti)];
249       SceneItem *item = QtGuiContext::getQtCurrent()->_mapOfSceneItem[sub];
250       autoPosNewPort(item, nbPorts);
251       nbPorts++;
252     }
253
254   list<OutPort*> plisto = father->getSetOfOutPort();
255   list<OutPort*>::iterator ito = plisto.begin();
256   nbPorts = 0;
257   for (; ito != plisto.end(); ++ito)
258     {
259       Subject *sub = QtGuiContext::getQtCurrent()->_mapOfSubjectDataPort[(*ito)];
260       SceneItem *item = QtGuiContext::getQtCurrent()->_mapOfSceneItem[sub];
261       autoPosNewPort(item, nbPorts);
262       nbPorts++;
263     }
264   updateLinks();
265 }
266
267 void SceneElementaryNodeItem::setShownState(shownState ss)
268 {
269   _shownState = ss;
270   if (_shownState == shrinkHidden)
271     {
272       _ancestorShrinked = true;
273       hide();
274     }
275   else
276     {
277       _ancestorShrinked = false;
278       show();
279     }
280   reorganize();
281 }
282