Salome HOME
Memory Leaks
[modules/superv.git] / src / SUPERVGUI / SUPERVGUI_CanvasPort.cxx
1 //  SUPERV SUPERVGUI : GUI for Supervisor component
2 //
3 //  Copyright (C) 2003  OPEN CASCADE
4 //
5 //  File   : SUPERVGUI_CanvasPort.cxx
6 //  Author : Natalia KOPNOVA
7 //  Module : SUPERV
8
9 using namespace std;
10 #include "SUPERVGUI_CanvasPort.h"
11 #include "SUPERVGUI_CanvasNode.h"
12 #include "SUPERVGUI_CanvasLink.h"
13 #include "SUPERVGUI_CanvasNodePrs.h"
14 #include "SUPERVGUI_Clipboard.h"
15 #include "SUPERVGUI_Main.h"
16 #include "SUPERVGUI.h"
17 #include "SUPERVGUI_BrowseNodeDlg.h"
18
19
20 SUPERVGUI_CanvasPort::SUPERVGUI_CanvasPort(QObject* theParent, SUPERVGUI_Main* theMain, SUPERV::Port_ptr thePort):
21     QObject(theParent),
22     myMain(theMain),
23     myPrs(0),
24     isIgnore(false)
25 {
26   Trace("SUPERVGUI_CanvasPort::SUPERVGUI_CanvasPort");
27   myPort = SUPERV::Port::_duplicate(thePort);
28
29   // setName(myPort->Name());
30   setName(myMain->getCanvas()->getPortName(thePort));
31 }
32
33 SUPERVGUI_CanvasPort::~SUPERVGUI_CanvasPort()
34 {
35   Trace("SUPERVGUI_CanvasPort::~SUPERVGUI_CanvasPort");
36   if (myPrs) delete myPrs;
37
38   isIgnore = true;
39   QValueList<SUPERVGUI_CanvasLink*>::Iterator it;
40   for (it = myLinks.begin(); it != myLinks.end(); ++it) {
41     delete *it;
42   }
43 }
44
45 SUPERVGUI_CanvasPortPrs* SUPERVGUI_CanvasPort::getPrs() const
46 {
47   if (myPrs == 0) ((SUPERVGUI_CanvasPort*)this)->myPrs = createPrs();
48   return myPrs;
49 }
50
51 SUPERVGUI_CanvasPortPrs* SUPERVGUI_CanvasPort::createPrs() const
52 {
53   return new SUPERVGUI_CanvasPortPrs(myMain->getCanvas(), (SUPERVGUI_CanvasPort*)this);
54 }
55
56 QPopupMenu* SUPERVGUI_CanvasPort::getPopupMenu(QWidget* theParent) 
57 {
58   QPopupMenu* popup = new QPopupMenu(theParent);
59   if ( myMain->isEditable() && !myMain->getDataflow()->IsExecuting() ) {
60     int anItem = popup->insertItem(tr("MSG_SKETCH_LINK"), this, SLOT(sketchLink()));
61     if (myMain->getDataflow()->IsExecuting())
62       popup->setItemEnabled(anItem, false);
63     else
64       popup->setItemEnabled(anItem, !myPort->IsInput() || !myPort->IsLinked()
65                             || myPort->Kind() == SUPERV::EndSwitchParameter);
66     popup->insertSeparator();
67   }
68   if (myMain->isEditable() && !myMain->getDataflow()->IsExecuting()
69       &&
70       ((myPort->IsEndSwitch() && myPort->IsInput()) 
71        ||
72        (myPort->IsInLine() && myPort->Node()->Kind() != SUPERV::EndLoopNode
73         && 
74         !(myPort->Node()->Kind() == SUPERV::LoopNode && !myPort->IsInput())))) {
75     popup->insertItem(tr("ITM_DEL_PORT"), this, SLOT(remove()));    
76   }
77   // Copy Port functionality
78   if (myMain->isEditable() && !myPort->Node()->IsFactory()
79                            && !myPort->Node()->IsComputing()
80                            && !myPort->Node()->IsMacro())
81     popup->insertItem(tr("ITM_COPY_PORT"), this, SLOT(copy()));
82
83   /*int anItem = */popup->insertItem(tr("MSG_BROWSE"), this, SLOT(browse()));
84 //   if (getEngine()->IsLinked())
85 //     popup->setItemEnabled(anItem, getEngine()->State() == SUPERV_Ready);
86 //   else 
87 //     popup->setItemEnabled(anItem, getEngine()->HasInput());
88
89   return popup;
90 }
91
92 QPoint SUPERVGUI_CanvasPort::getConnectionPoint() const
93 {
94   QPoint p = getPrs()->getConnectionPoint();
95
96   if (!getPrs()->isVisible()) {
97     if (parent() && parent()->inherits("SUPERVGUI_CanvasNode")) {
98       SUPERVGUI_CanvasNodePrs* aNode = ((SUPERVGUI_CanvasNode*) parent())->getPrs();
99       if (myPort->IsInput())
100         p = aNode->getInConnectionPoint();
101       else
102         p = aNode->getOutConnectionPoint();
103     }
104   }
105   return p;
106 }
107
108 void SUPERVGUI_CanvasPort::update() 
109 {
110   // ignore update if node itself is destroyed (critical for Start/End control nodes)
111   if (!((SUPERVGUI_CanvasNode*) parent())->isDestroyed())
112     getPrs()->update(true);
113 }
114
115 void SUPERVGUI_CanvasPort::sync() 
116 {
117   getPrs()->update();
118 }
119
120 void SUPERVGUI_CanvasPort::sketchLink() {
121   myMain->Editing(); // PAL6170: GUI->Engine: setting "Editing" flag 
122   
123   myMain->getCanvasView()->startSketch(this);
124 }
125
126 void SUPERVGUI_CanvasPort::remove() {
127   myMain->Editing(); // PAL6170: GUI->Engine: setting "Editing" flag 
128
129   //set myCopyPort from Main object to empty if engine of this port is deleted
130   //check if myCopyPort and this port engine is equal
131   SUPERVGUI_Clipboard* aCB = SUPERVGUI_Clipboard::getClipboard();
132   if ( aCB->isCopyPort() )
133     if ( QString(myPort->Node()->Name()) == QString(aCB->getCopyPort()->Node()->Name()) &&
134          QString(myPort->Name()) == QString(aCB->getCopyPort()->Name()) &&
135          myPort->IsInput() == aCB->getCopyPort()->IsInput() )
136         aCB->setCopyPort( 0 );
137
138   Trace("SUPERVGUI_CanvasPort::remove");
139   myPort->destroy();
140   delete this;
141 }
142
143 void SUPERVGUI_CanvasPort::moveBy(int dx, int dy) 
144 {
145   getPrs()->moveBy(dx, dy);
146
147   QValueList<SUPERVGUI_CanvasLink*>::Iterator it;
148   for (it = myLinks.begin(); it != myLinks.end(); ++it) {
149     (*it)->moveByPort(this, dx, dy);
150   }
151 }
152
153 void SUPERVGUI_CanvasPort::addLink(SUPERVGUI_CanvasLink* theLink)
154 {
155   myLinks.append(theLink);
156   update();
157 }
158
159 void SUPERVGUI_CanvasPort::removeLink(SUPERVGUI_CanvasLink* theLink)
160 {
161   if (!isIgnore) {
162     myLinks.remove(theLink);
163     update();
164   }
165 }
166
167 void SUPERVGUI_CanvasPort::updateLinks() 
168 {
169   QValueList<SUPERVGUI_CanvasLink*>::Iterator it;
170   for (it = myLinks.begin(); it != myLinks.end(); ++it) {
171     (*it)->moveByPort(this);
172   }
173 }
174
175 void SUPERVGUI_CanvasPort::browse() 
176 {
177   QString aMes(getEngine()->IsInput()? tr("MSG_IPORT_VAL") : tr("MSG_OPORT_VAL"));
178   aMes += getEngine()->ToString();
179   QMessageBox::information(QAD_Application::getDesktop(), tr("MSG_INFO"), aMes);
180 }
181
182 void SUPERVGUI_CanvasPort::copy()
183 {
184   SUPERVGUI_Clipboard* aCB = SUPERVGUI_Clipboard::getClipboard();
185   aCB->setCopyPort(SUPERV::Port::_duplicate(getEngine()));
186 }
187
188 //***********************************************************
189 // Input Port
190 //***********************************************************
191 SUPERVGUI_CanvasPortIn::SUPERVGUI_CanvasPortIn(QObject* theParent, SUPERVGUI_Main* theMain, SUPERV::Port_ptr thePort):
192   SUPERVGUI_CanvasPort(theParent, theMain, thePort)
193 {
194   Trace("SUPERVGUI_CanvasPortIn::SUPERVGUI_CanvasPortIn");
195   myDlg = 0;
196 }
197
198 SUPERVGUI_CanvasPortIn::~SUPERVGUI_CanvasPortIn()
199 {
200   Trace("SUPERVGUI_CanvasPortIn::~SUPERVGUI_CanvasPortIn");
201 }
202
203 QPopupMenu* SUPERVGUI_CanvasPortIn::getPopupMenu(QWidget* theParent) 
204 {
205   QPopupMenu* popup = SUPERVGUI_CanvasPort::getPopupMenu(theParent);
206   bool editable = getEngine()->IsInput() && !getEngine()->IsLinked() && !getMain()->getDataflow()->IsExecuting();
207
208   if (!getEngine()->IsGate() && editable)
209     popup->insertItem(tr("MSG_SETVALUE"), this, SLOT(setInput()));
210
211   return popup;
212 }
213
214 void SUPERVGUI_CanvasPortIn::setValue(const char* theValue) 
215 {
216   if (getEngine()->Input(Supervision.getEngine()->StringValue(theValue)))
217     update(); // sync();
218   else
219     QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), tr("MSG_CANT_SETVAL"));
220 }
221
222 void SUPERVGUI_CanvasPortIn::setInput() 
223 {
224   // asv 28.01.05 : set "Editing" flag only on "OK" pressed in BrowseDlg
225   //getMain()->Editing(); // PAL6170: GUI->Engine: setting "Editing" flag 
226   if (!myDlg) {
227     myDlg = new SUPERVGUI_GetValueDlg(this);
228     myDlg->installEventFilter(this);
229   }
230   if (!myDlg->isVisible())
231     myDlg->show();
232   else {
233     myDlg->raise();
234     myDlg->setActiveWindow();
235     myDlg->setFocus();
236   }
237 }
238
239 bool SUPERVGUI_CanvasPortIn::eventFilter(QObject* o, QEvent* e)
240 {
241   if (o == myDlg && e->type() == QEvent::Close)
242     myDlg = 0;
243   return SUPERVGUI_CanvasPort::eventFilter(o, e);
244 }
245
246
247 //***********************************************************
248 // Output Port
249 //***********************************************************
250 SUPERVGUI_CanvasPortOut::SUPERVGUI_CanvasPortOut(QObject* theParent, SUPERVGUI_Main* theMain, SUPERV::Port_ptr thePort):
251   SUPERVGUI_CanvasPort(theParent, theMain, thePort)
252 {
253   Trace("SUPERVGUI_CanvasPortOut::SUPERVGUI_CanvasPortOut");
254   myInStudy = false;
255 }
256
257 SUPERVGUI_CanvasPortOut::~SUPERVGUI_CanvasPortOut()
258 {
259   Trace("SUPERVGUI_CanvasPortOut::~SUPERVGUI_CanvasPortOut");
260 }
261
262 QPopupMenu* SUPERVGUI_CanvasPortOut::getPopupMenu(QWidget* theParent) 
263 {
264   QPopupMenu* popup = SUPERVGUI_CanvasPort::getPopupMenu(theParent);
265
266   if (!getEngine()->IsGate()) {
267     popup->insertItem(myInStudy?tr("MSG_NOT_INSTUDY"):tr("MSG_PUT_INSTUDY"), 
268                       this, SLOT(toStudy()));
269   }
270
271   return popup;
272 }
273
274 void SUPERVGUI_CanvasPortOut::sync() 
275 {
276   /* asv : 26.01.05 : Bug PAL7164 : sometimes CanvasPortOut::sync() is called twice (or maybe even more)
277            by mistake.  It happens because of incorrect Qt events, or other reason, but it is not a
278            stable feature (bug). Adding an object in the study in sync() is therefore called more than once
279            which is a BUG.  I decided to move call to putDataStudy() method to Event handling function.
280            When a node successfully finishes execution - check the ports and put out-value to study,
281            if the corresponding flag is set.
282   bool ok = getEngine()->State() == SUPERV_Ready;
283   if (ok && myInStudy) {
284     myInStudy = getMain()->putDataStudy(getEngine(), STUDY_PORT_OUT);
285   }
286   */
287   SUPERVGUI_CanvasPort::update();
288 }
289
290 void SUPERVGUI_CanvasPortOut::toStudy() 
291 {
292   Trace("SUPERVGUI_CanvasPortOut::toStudy");
293
294   // asv 08.02.05 : added && !myInStudy - fix for PAL8105
295   if ( getMain()->getStudy()->getStudyDocument()->GetProperties()->IsLocked() && !myInStudy ) {
296     QMessageBox::warning(QAD_Application::getDesktop(), tr("WRN_WARNING"), 
297                          tr("WRN_STUDY_LOCKED"));
298     return;
299   }
300
301   myInStudy = !myInStudy;
302   sync();
303   getMain()->getCanvas()->update();
304
305   if ( myInStudy ) // put values to study (supervision, supervision->dataflow, supervision->dataflow->runXXX, etc.
306     getMain()->putDataStudy( getEngine(), STUDY_PORT_OUT ); 
307 }
308
309
310
311 //***********************************************************
312 // Stream Input Port
313 //***********************************************************
314 SUPERVGUI_CanvasStreamPortIn::SUPERVGUI_CanvasStreamPortIn(QObject* theParent, SUPERVGUI_Main* theMain, 
315                                                            SUPERV::StreamPort_ptr thePort):
316   SUPERVGUI_CanvasPortIn(theParent, theMain, thePort)
317 {
318   myStreamPort = SUPERV::StreamPort::_duplicate(thePort);
319 }
320
321 QPopupMenu* SUPERVGUI_CanvasStreamPortIn::getPopupMenu(QWidget* theParent) 
322 {
323   QPopupMenu* popup = SUPERVGUI_CanvasPortIn::getPopupMenu(theParent);
324   popup->insertItem(tr("MSG_STREAM_PARAM"),this, SLOT(setParams()));
325   return popup;
326 }
327
328 void SUPERVGUI_CanvasStreamPortIn::setParams()
329 {
330   SUPERVGUI_StreamInDlg* aDlg = new SUPERVGUI_StreamInDlg(this);
331   aDlg->exec();
332   delete aDlg;
333 }
334
335
336 //***********************************************************
337 // Stream Output Port
338 //***********************************************************
339 SUPERVGUI_CanvasStreamPortOut::SUPERVGUI_CanvasStreamPortOut(QObject* theParent, SUPERVGUI_Main* theMain, 
340                                                              SUPERV::StreamPort_ptr thePort):
341   SUPERVGUI_CanvasPortOut(theParent, theMain, thePort)
342 {
343   myStreamPort = SUPERV::StreamPort::_duplicate(thePort);
344 }
345
346
347 QPopupMenu* SUPERVGUI_CanvasStreamPortOut::getPopupMenu(QWidget* theParent) 
348 {
349   QPopupMenu* popup = SUPERVGUI_CanvasPortOut::getPopupMenu(theParent);
350   popup->insertItem(tr("MSG_STREAM_PARAM"),this, SLOT(setParams()));
351   return popup;
352 }
353
354 void SUPERVGUI_CanvasStreamPortOut::setParams()
355 {
356   SUPERVGUI_StreamOutDlg* aDlg = new SUPERVGUI_StreamOutDlg(this);
357   aDlg->exec();
358   delete aDlg;
359 }