]> SALOME platform Git repositories - modules/superv.git/blob - src/SUPERVGUI/SUPERVGUI_CanvasNode.cxx
Salome HOME
Add functionality for Table view based on QCanvas.
[modules/superv.git] / src / SUPERVGUI / SUPERVGUI_CanvasNode.cxx
1 //  SUPERV SUPERVGUI : GUI for Supervisor component
2 //
3 //  Copyright (C) 2003  OPEN CASCADE
4 //
5 //  File   : SUPERVGUI_CanvasNode.cxx
6 //  Author : Natalia KOPNOVA
7 //  Module : SUPERV
8
9 using namespace std;
10 #include "SUPERVGUI_CanvasNode.h"
11 #include "SUPERVGUI_CanvasNodePrs.h"
12 #include "SUPERVGUI_CanvasPort.h"
13 #include "SUPERVGUI_Main.h"
14 #include "SUPERVGUI_Python.h"
15 #include "SUPERVGUI.h"
16 #include "SUPERVGUI_BrowseNodeDlg.h"
17 #include "SUPERVGUI_ManagePortsDlg.h"
18 #include "SALOMEGUI_NameDlg.h"
19 #include "SUPERVGUI_Information.h"
20 /*
21 #include "SUPERVGUI_CanvasControlNode.h"
22
23 #include <qtooltip.h>
24 */
25
26 SUPERVGUI_CanvasNode::SUPERVGUI_CanvasNode(QObject* theParent, SUPERVGUI_Main* theMain, SUPERV_CNode theNode, bool theIsCell):
27     QObject(theParent),
28     myMain(theMain),
29     myNode(theNode),
30     myPrs(0),
31     myDestroyed(false),
32     warning(true),
33     step(true),
34     trace(true),
35     verbose(true),
36     myBrowseDlg(0)
37 {
38   Trace("SUPERVGUI_CanvasNode::SUPERVGUI_CanvasNode");
39
40   setName(myNode->Name());
41
42   QString aComment(myNode->Comment());
43   QString aNewComment = aComment;
44   if (getNodeType() == SUPERV::FactoryNode) {
45     aNewComment = QString(myNode->Service()->ServiceName) +
46       QString(tr("COMMENT_FROM")) +
47       QString(getFactoryNode()->GetComponentName());
48   }
49   else if (myNode->IsMacro()) {
50     aNewComment = tr("COMMENT_MNODE");
51   }
52   else {
53     aNewComment = tr("COMMENT_CNODE");
54   }
55   if (aComment.isEmpty()) {
56     myNode->SetComment(aNewComment.latin1());
57   }
58
59   myLabelText = aNewComment;
60
61   // create node ports
62   isIgnore = true;
63   //cout << "     get port list... " ;
64   SUPERV_Ports aPortList = myNode->Ports();
65   //cout << aPortList->length() << endl;
66   for (int i = 0; i < aPortList->length(); i++) {
67     createPort(aPortList[i].in());
68   }
69
70   //cout << "     get stream port list... " ;
71   SUPERV_StreamPorts aStreamPortList = myNode->StreamPorts();
72   //cout << aStreamPortList->length() << endl;
73   for (int i = 0; i < aStreamPortList->length(); i++) {
74     createStreamPort(aStreamPortList[i].in());
75   }
76
77   isIgnore = false;
78
79   QCanvasItemList anIL2 = ((QCanvas*)parent())->allItems();
80   cout<<" ===> 1 conatructor CanvasNode : CanvasArray has "<<anIL2.count()<<" children!"<<endl;
81 }
82
83 SUPERVGUI_CanvasNode::~SUPERVGUI_CanvasNode()
84 {
85   isIgnore = true;
86   if (myPrs) delete myPrs;
87 }
88
89 void SUPERVGUI_CanvasNode::setDestroyed()
90 {
91   myDestroyed = true;
92   getPrs()->hide();
93 }
94
95 SUPERVGUI_CanvasNodePrs* SUPERVGUI_CanvasNode::getPrs() const
96 {
97   if (myPrs == 0) {
98     ((SUPERVGUI_CanvasNode*)this)->myPrs = createPrs();
99   }
100   return myPrs;
101 }
102
103 SUPERVGUI_CanvasNodePrs* SUPERVGUI_CanvasNode::createPrs() const
104 {
105   return new SUPERVGUI_CanvasNodePrs(myMain->getCanvas(), (SUPERVGUI_CanvasNode*)this);
106 }
107
108 void SUPERVGUI_CanvasNode::createPort(SUPERV::Port_ptr thePort) const
109 {
110   SUPERVGUI_CanvasPort* aPort = 0;
111   if (thePort->IsInput())
112     aPort = new SUPERVGUI_CanvasPortIn((SUPERVGUI_CanvasNode*)this, myMain, thePort);
113   else
114     aPort = new SUPERVGUI_CanvasPortOut((SUPERVGUI_CanvasNode*)this, myMain, thePort);
115
116   if (aPort) {
117     connect(aPort, SIGNAL(destroyed(QObject*)), this, SLOT(onDestroyed(QObject*)));
118     if (!isIgnore) getPrs()->updatePorts();
119   }
120 }
121
122 void SUPERVGUI_CanvasNode::createStreamPort(SUPERV::StreamPort_ptr thePort) const
123 {
124   SUPERVGUI_CanvasPort* aPort = 0;
125   if (thePort->IsInput())
126     aPort = new SUPERVGUI_CanvasStreamPortIn((SUPERVGUI_CanvasNode*)this, myMain, thePort);
127   else
128     aPort = new SUPERVGUI_CanvasStreamPortOut((SUPERVGUI_CanvasNode*)this, myMain, thePort);
129
130   if (aPort) {
131     connect(aPort, SIGNAL(destroyed(QObject*)), this, SLOT(onDestroyed(QObject*)));
132     if (!isIgnore) getPrs()->updatePorts();
133   }
134 }
135
136 void SUPERVGUI_CanvasNode::onDestroyed(QObject* theObject)
137 {
138   if (!isIgnore) {
139     removeChild(theObject); // signal is sent before removing the object
140     getPrs()->updatePorts();
141   }
142 }
143
144 QPopupMenu* SUPERVGUI_CanvasNode::getPopupMenu(QWidget* theParent) 
145 {
146   QPopupMenu* popup = new QPopupMenu(theParent);
147   if (myMain->getDataflow()->IsExecuting()) {
148     popup->insertItem((myNode->IsSuspended()?tr("MSG_RESUME"):tr("MSG_SUSPEND")),
149                       this, SLOT(suspendResume()));
150     popup->insertItem(tr("MSG_KILL"), this, SLOT(kill()));
151   }
152   else {
153     if (myMain->isEditable() && getNodeType() != SUPERV::EndLoopNode
154                              && getNodeType() != SUPERV::EndSwitchNode) {
155       popup->insertItem(tr("MSG_RENAME"), this, SLOT(rename()));
156       myDeleteItem = popup->insertItem(tr("MSG_DELETE"), this, SLOT(remove()));
157       popup->insertSeparator();
158     }
159     popup->insertItem(tr("MSG_BROWSE"), this, SLOT(browse()));
160
161     if (getNodeType() != SUPERV::EndLoopNode && 
162         getNodeType() != SUPERV::EndSwitchNode)
163       popup->insertItem(tr("MSG_CHANGE_INFO"), this, SLOT(changeInformation()));
164
165     if (myMain->isEditable() && getNodeType() != SUPERV::FactoryNode
166                              && getNodeType() != SUPERV::ComputingNode
167                              && getNodeType() != SUPERV::EndLoopNode
168                              && getNodeType() != SUPERV::MacroNode) {
169       QPopupMenu* addPortMenu = new QPopupMenu(theParent);
170       addPortMenu->insertItem( tr( "MNU_INPUT" ), this, SLOT(addInputPort()));
171       if (getNodeType() != SUPERV::LoopNode)
172         addPortMenu->insertItem( tr( "MNU_OUTPUT" ), this, SLOT(addOutputPort()));
173       
174       popup->insertSeparator();
175       if ((getNodeType() != SUPERV::EndSwitchNode))
176         popup->insertItem( tr( "MNU_EDIT_FUNC" ), this, SLOT(editFunction()));
177       popup->insertItem( tr( "MNU_ADD_PORT" ), addPortMenu);
178       popup->insertItem( tr( "MNU_MANAGE_PORTS" ), this, SLOT(managePorts()));
179     }
180   }
181
182   return popup;
183 }
184
185 void SUPERVGUI_CanvasNode::show() 
186 {
187   getPrs()->show();
188 }
189
190 void SUPERVGUI_CanvasNode::showAll() 
191 {
192   getPrs()->showAll();
193 }
194
195 void SUPERVGUI_CanvasNode::hideAll() 
196 {
197   getPrs()->hideAll();
198 }
199
200 void SUPERVGUI_CanvasNode::switchLabel()
201 {
202   getPrs()->setLabelVisible(!getPrs()->isLabelVisible());
203 }
204
205 void SUPERVGUI_CanvasNode::switchPorts()
206 {
207   getPrs()->setPortVisible(!getPrs()->isPortVisible());
208 }
209
210 void SUPERVGUI_CanvasNode::move(int x, int y)
211 {
212   //  myNode->Coords(x, y); //  <<<- done inside Prs to reflect item movement by mouse press
213   if (x > GRAPH_MAX) x = (int) getPrs()->x();
214   if (y > GRAPH_MAX) y = (int) getPrs()->y();
215   getPrs()->move(x, y);
216 }
217
218 void SUPERVGUI_CanvasNode::merge() 
219 {
220   //MESSAGE("===> SUPERVGUI_CanvasNode::merge() " << myNode->Name());
221   // synchronize port list
222   bool update = false;
223   isIgnore = true;
224   SUPERVGUI_CanvasPort* aPort;
225   QObjectList* aPortList = queryList("SUPERVGUI_CanvasPort");
226   //cout << "     get port list... " ;
227   SUPERV_Ports aPorts = myNode->Ports();
228   //cout << aPorts->length() << endl;
229   for (int i = 0; i < aPorts->length(); i++) {
230     aPort = (SUPERVGUI_CanvasPort*) 
231       child(myMain->getCanvas()->getPortName(aPorts[i].in()), "SUPERVGUI_CanvasPort");
232     if (aPort) {
233   //cout << "     update port " << aPort->name() << endl;
234       aPortList->removeRef(aPort);
235       aPort->update();
236     }
237     else {
238   //cout << "     create port " << myMain->getCanvas()->getPortName(aPorts[i].in()) << endl;
239       createPort(aPorts[i].in());
240       update = true;
241     }
242   }
243
244   //cout << "     get stream port list... " ;
245   SUPERV_StreamPorts aStreamPorts = myNode->StreamPorts();
246   //cout << aStreamPorts->length() << endl;
247   for (int i = 0; i < aStreamPorts->length(); i++) {
248     aPort = (SUPERVGUI_CanvasPort*) 
249       child(myMain->getCanvas()->getPortName(aStreamPorts[i].in()), "SUPERVGUI_CanvasPort");
250     if (aPort) {
251   //cout << "     update stream port " << aPort->name() << endl;
252       aPortList->removeRef(aPort);
253       aPort->update();
254     }
255     else {
256   //cout << "     create stream port " << myMain->getCanvas()->getPortName(aStreamPorts[i].in()) << endl;
257       createPort(aStreamPorts[i].in());
258       update = true;
259     }
260   }
261
262   //cout << "     remove inexistant " << endl;
263   QObjectListIt it(*aPortList);
264   while ((aPort=(SUPERVGUI_CanvasPort*)it.current()) != 0) {
265     ++it;
266     aPortList->removeRef(aPort);
267     delete aPort;
268     update = true;
269   }
270   delete aPortList;
271   isIgnore = false;
272   if (update) getPrs()->updatePorts();
273
274   sync(); // update node state also
275 }
276
277 void SUPERVGUI_CanvasNode::sync() 
278 {
279   //MESSAGE("===> SUPERVGUI_CanvasNode::sync() " << myNode->Name() << ", state " << myNode->State());
280
281   //if myNode is a MacroNode then set it state to state of its subgraph
282   if (myNode->IsMacro() && myMain->getDataflow()->IsExecuting()) {
283     // get SubGraph from MacroNode
284     SUPERV_Graph aMacro = SUPERV::Graph::_narrow(myNode);
285     if (!SUPERV_isNull(aMacro)) {
286       SUPERV_Graph aGraph;
287       if (aMacro->IsStreamMacro())
288         aGraph = aMacro->StreamObjRef();
289       else
290         aGraph = aMacro->FlowObjRef();
291       if (!SUPERV_isNull(aGraph)) {
292         if (aGraph->State() != SUPERV::UndefinedState && aGraph->State() != SUPERV::NoState)
293           getPrs()->setState(aGraph->State());
294         else 
295           getPrs()->setState(myNode->State());
296       }
297     }
298   }
299   else 
300     getPrs()->setState(myNode->State());
301   
302   // update child ports
303   const QObjectList* list = children();
304   if (list) {
305     QObjectListIt it(*list);
306     while (QObject* obj = it.current()) {
307       ++it;
308       if (obj->inherits("SUPERVGUI_CanvasPort")) {
309         ((SUPERVGUI_CanvasPort*)obj)->sync();
310       }
311     }
312   }
313 }
314
315 void SUPERVGUI_CanvasNode::syncOnEvent(SUPERV::GraphState theStateFromEvent) 
316 {
317   getPrs()->setState(theStateFromEvent);
318 }
319
320 bool SUPERVGUI_CanvasNode::setNodeName(QString aName) 
321 {
322   bool result = myNode->SetName(aName.latin1());
323   if (result) {
324     setName(myNode->Name());
325     getPrs()->updateInfo();
326     // TODO: update name of all the links to this node
327   } 
328   else {
329     QMessageBox::warning( QAD_Application::getDesktop(), tr( "ERROR" ), tr( "MSG_CANT_RENAMENODE" ) );
330   }
331   return result;
332 }
333
334 void SUPERVGUI_CanvasNode::rename()
335 {
336   QString aName = SALOMEGUI_NameDlg::getName(QAD_Application::getDesktop(), myNode->Name());
337   if (!aName.isEmpty()) {
338     setNodeName(aName);
339   }
340 }
341
342 void SUPERVGUI_CanvasNode::remove() {
343   Trace("SUPERVGUI_CanvasNode::remove");
344   SUPERVGUI_Canvas* aCanvas = myMain->getCanvas();
345   setDestroyed();
346   myNode->destroy();
347   delete this;
348   aCanvas->update();
349 }
350
351 void SUPERVGUI_CanvasNode::suspendResume() {
352   Trace("SUPERVGUI_CanvasNode::suspendResume");
353   int n = queryList("SUPERVGUI_CanvasNode")->count(); 
354   if (myNode->IsSuspended()) {
355     if (!((n==1)? myMain->getDataflow()->Resume() : myNode->Resume())) {
356       QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), tr("MSG_CANT_RESUMENODE"));
357     }
358     else {
359       sync();
360       myMain->getMyThread()->startThread(tr("MSG_NODE_RESUMED1")+myNode->Name()+tr("MSG_NODE_RESUMED2"));
361     }
362   } else {
363     if (!((n==1)? myMain->getDataflow()->Suspend() : myNode->Suspend())) {
364       QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), tr("MSG_CANT_SUSPENDNODE"));
365     } else {
366       syncOnEvent(SUPERV::SuspendReadyState);
367       myMain->getMyThread()->stopThread(tr("MSG_NODE_SUSPENDED1")+myNode->Name()+tr("MSG_NODE_SUSPENDED2"));
368     }
369   }
370 }
371
372 void SUPERVGUI_CanvasNode::kill() {
373   Trace("SUPERVGUI_CanvasNode::kill");
374   int n = queryList("SUPERVGUI_CanvasNode")->count(); 
375   if (!((n==1)? myMain->getDataflow()->Kill() : myNode->Kill())) {
376     QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), tr("MSG_CANT_KILLNODE"));
377   } else {
378     syncOnEvent(SUPERV_Kill);
379     myMain->getMyThread()->stopThread(tr("MSG_NODE_KILLED1")+myNode->Name()+tr("MSG_NODE_KILLED2"));
380   }
381 }
382
383 void SUPERVGUI_CanvasNode::stopRestart() {
384   Trace("SUPERVGUI_CanvasNode::stopRestart");
385   
386   int n = queryList("SUPERVGUI_CanvasNode")->count(); 
387   if ((myNode->State() == SUPERV_Stop) || (myNode->State() == SUPERV_Kill)) {
388     if (!((n==1)? myMain->getDataflow()->Run() : myNode->ReStart())) {
389       QMessageBox::warning(QAD_Application::getDesktop(),  tr("ERROR"), tr("MSG_CANT_RESTARTNODE"));
390     }
391   } else {
392     if (!((n==1)? myMain->getDataflow()->Stop() : myNode->Stop())) {
393       QMessageBox::warning(QAD_Application::getDesktop(),  tr("ERROR"), tr("MSG_CANT_STOPNODE"));
394     }
395   }
396 }
397
398 void SUPERVGUI_CanvasNode::changeInformation() {
399   SUPERVGUI_Information* aDlg = new SUPERVGUI_Information(myNode, !myMain->isEditable());
400   if (aDlg->exec()) {
401     QString aName = myNode->Name();
402     if (!aName.isEmpty() && myMain->isEditable())
403       setNodeName(aName);
404   }
405   delete aDlg;
406 }
407
408 void SUPERVGUI_CanvasNode::configure() 
409 {
410   Trace("SUPERVGUI_CanvasNode::configure");
411   QMessageBox::warning(QAD_Application::getDesktop(),  tr("ERROR"), tr("MSG_NOT_IMPLEMENTED")); // kloss : a faire : lancer l'ihm DATA
412 }
413
414 void SUPERVGUI_CanvasNode::showPython() 
415 {
416   Trace("SUPERVGUI_CanvasNode::showPython");
417   SUPERVGUI_Python cp(myMain->getStudy()->get_PyInterp(), !myMain->isEditable());
418   cp.exec();
419 }
420
421 bool SUPERVGUI_CanvasNode::isWarning() 
422 {
423   Trace("SUPERVGUI_CanvasNode::isWarning");
424   return(warning);
425 }
426
427 bool SUPERVGUI_CanvasNode::isStep() 
428 {
429   Trace("SUPERVGUI_CanvasNode::isStep");
430   return(step);
431 }
432
433 bool SUPERVGUI_CanvasNode::isTrace() 
434 {
435   Trace("SUPERVGUI_CanvasNode::isTrace");
436   return(trace);
437 }
438
439 bool SUPERVGUI_CanvasNode::isVerbose() 
440 {
441   Trace("SUPERVGUI_CanvasNode::isVerbose");
442   return(verbose);
443 }
444
445 void SUPERVGUI_CanvasNode::setWarning(bool b) 
446 {
447   Trace("SUPERVGUI_CanvasNode::setWarning");
448   warning = b;
449 }
450
451 void SUPERVGUI_CanvasNode::setStep(bool b) 
452 {
453   Trace("SUPERVGUI_CanvasNode::setStep");
454   step = b;
455 }
456
457 void SUPERVGUI_CanvasNode::setTrace(bool b) 
458 {
459   Trace("SUPERVGUI_CanvasNode::setTrace");
460   trace = b;
461 }
462
463 void SUPERVGUI_CanvasNode::setVerbose(bool b) 
464 {
465   Trace("SUPERVGUI_CanvasNode::setVerbose");
466   verbose = b;
467 }
468
469
470 void SUPERVGUI_CanvasNode::browse() 
471 {
472   if (!myBrowseDlg) {
473     myBrowseDlg = new SUPERVGUI_BrowseNodeDlg(this);
474     myBrowseDlg->installEventFilter(this);
475   }
476   if (!myBrowseDlg->isVisible())
477     myBrowseDlg->show();
478   else {
479     myBrowseDlg->raise();
480     myBrowseDlg->setActiveWindow();
481     myBrowseDlg->setFocus();
482   }
483 }
484
485 bool SUPERVGUI_CanvasNode::eventFilter( QObject* o, QEvent* e )
486 {
487   if (o == myBrowseDlg && e->type() == QEvent::Close)
488     myBrowseDlg = 0;
489   return QObject::eventFilter(o, e);
490 }
491
492 QStringList SUPERVGUI_CanvasNode::getPortsNamesIN(SUPERV_INode theNode, bool theInputPorts)
493 {
494   QStringList aPNList;
495   if (!SUPERV_isNull(theNode)) {
496     SUPERV_Ports aPorts = theNode->Ports();
497     for (int i=0; i<aPorts->length(); i++) {
498       if (theInputPorts) {
499         if (aPorts[i]->IsInput()) aPNList.append(QString(aPorts[i]->Name()));
500       }
501       else 
502         if (!aPorts[i]->IsInput()) aPNList.append(QString(aPorts[i]->Name()));
503     }
504   }
505   return aPNList;
506 }
507
508 SUPERV_Port SUPERVGUI_CanvasNode::createInPort() 
509 {
510   SUPERV_INode aNode = getInlineNode();
511   if (SUPERV_isNull(aNode)) {
512     MESSAGE("SUPERVGUI_CanvasNode::createInPort: Node is wrong type");
513     return NULL;
514   }
515   SUPERVGUI_PortParamsDlg* aDlg = new SUPERVGUI_PortParamsDlg(getPortsNamesIN(aNode,true));
516   if (aDlg->exec()) {
517     SUPERV_Port aPort = aNode->InPort(aDlg->getName().latin1(),
518                                       aDlg->getType().latin1());    
519     delete aDlg;
520     return aPort;
521   }
522   delete aDlg;
523   return NULL;
524 }
525
526 SUPERV_Port SUPERVGUI_CanvasNode::createOutPort() 
527 {
528   SUPERV_INode aNode = getInlineNode();
529   if (SUPERV_isNull(aNode)) {
530     MESSAGE("SUPERVGUI_CanvasNode::createOutPort: Node is wrong type");
531     return NULL;
532   }
533   
534   SUPERVGUI_PortParamsDlg* aDlg = new SUPERVGUI_PortParamsDlg(getPortsNamesIN(aNode,false));
535   if (aDlg->exec()) {
536     SUPERV_Port aPort = aNode->OutPort(aDlg->getName().latin1(),
537                                        aDlg->getType().latin1());
538     delete aDlg;
539     return aPort;
540   }
541   delete aDlg;
542   return NULL;
543 }
544
545 void SUPERVGUI_CanvasNode::addInputPort() {
546   SUPERV_Port aPort = createInPort();
547   if (aPort == NULL) return;
548
549   createPort(aPort.in());
550 }
551
552
553 void SUPERVGUI_CanvasNode::addOutputPort() {
554   SUPERV_Port aPort = createOutPort();
555   if (aPort == NULL) return;
556
557   createPort(aPort.in());
558 }
559
560
561 void SUPERVGUI_CanvasNode::editFunction() 
562 {
563   if (getNodeType() == SUPERV::LoopNode) {
564     SUPERVGUI_EditPythonDlg* aDlg = new SUPERVGUI_EditPythonDlg(true);
565     SUPERV_LNode aLNode = getLoopNode();
566     aDlg->setInitFunction(aLNode->PyInit());
567     aDlg->setMoreFunction(aLNode->PyMore());
568     aDlg->setNextFunction(aLNode->PyNext());
569     if (aDlg->exec()) {
570       aLNode->SetPyInit(aDlg->getInitFuncName().latin1(), (aDlg->getInitFunction()).in());
571       aLNode->SetPyMore(aDlg->getMoreFuncName().latin1(), (aDlg->getMoreFunction()).in());
572       aLNode->SetPyNext(aDlg->getNextFuncName().latin1(), (aDlg->getNextFunction()).in());
573     }
574     delete aDlg;
575   } 
576   else {
577     SUPERVGUI_EditPythonDlg* aDlg = new SUPERVGUI_EditPythonDlg();
578     SUPERV_INode aINode = getInlineNode();
579     aDlg->setFunction(aINode->PyFunction());
580     if (aDlg->exec()) {
581       aINode->SetPyFunction(aDlg->getFuncName().latin1(), (aDlg->getFunction()).in());
582     }
583     delete aDlg;
584   }
585 }
586
587 /** 
588  * Called on "Edit ports" popup menu command. See SUPERVGUI_ManagePortsDlg.h
589  * for detailed description of the functionality
590  */
591 void SUPERVGUI_CanvasNode::managePorts() {
592   SUPERVGUI_ManagePortsDlg* aDlg = new SUPERVGUI_ManagePortsDlg( this );
593   aDlg->exec();
594   delete aDlg;
595 }