1 // SUPERV SUPERVGUI : GUI for Supervisor component
3 // Copyright (C) 2003 OPEN CASCADE
5 // File : SUPERVGUI_CanvasNode.cxx
6 // Author : Natalia KOPNOVA
10 #include "SUPERVGUI_CanvasNode.h"
11 #include "SUPERVGUI_CanvasNodePrs.h"
12 #include "SUPERVGUI_CanvasPort.h"
13 #include "SUPERVGUI_Clipboard.h"
14 #include "SUPERVGUI_Main.h"
15 #include "SUPERVGUI.h"
16 #include "SUPERVGUI_BrowseNodeDlg.h"
17 #include "SUPERVGUI_ManagePortsDlg.h"
18 #include "SUPERVGUI_Information.h"
19 #include "SUPERVGUI_Library.h"
21 #include "SALOMEGUI_NameDlg.h"
22 #include "QAD_MessageBox.h"
24 SUPERVGUI_CanvasNode::SUPERVGUI_CanvasNode(QObject* theParent, SUPERVGUI_Main* theMain, SUPERV_CNode theNode, bool theIsCell):
36 Trace("SUPERVGUI_CanvasNode::SUPERVGUI_CanvasNode");
38 setName(myNode->Name());
40 QString aComment(myNode->Comment());
41 QString aNewComment = aComment;
42 if (getNodeType() == SUPERV::FactoryNode) {
43 aNewComment = QString(myNode->Service()->ServiceName) +
44 QString(tr("COMMENT_FROM")) +
45 QString(getFactoryNode()->GetComponentName());
47 else if (myNode->IsMacro()) {
48 aNewComment = tr("COMMENT_MNODE");
51 aNewComment = tr("COMMENT_CNODE");
53 if (aComment.isEmpty()) {
54 myNode->SetComment(aNewComment.latin1());
57 myLabelText = aNewComment;
61 //cout << " get port list... " ;
62 SUPERV_Ports aPortList = myNode->Ports();
63 //cout << aPortList->length() << endl;
64 for (int i = 0; i < aPortList->length(); i++) {
65 createPort(aPortList[i].in());
68 //cout << " get stream port list... " ;
69 SUPERV_StreamPorts aStreamPortList = myNode->StreamPorts();
70 //cout << aStreamPortList->length() << endl;
71 for (int i = 0; i < aStreamPortList->length(); i++) {
72 createStreamPort(aStreamPortList[i].in());
77 QCanvasItemList anIL2 = ((QCanvas*)parent())->allItems();
78 cout<<" ===> 1 conatructor CanvasNode : CanvasArray has "<<anIL2.count()<<" children!"<<endl;
81 SUPERVGUI_CanvasNode::~SUPERVGUI_CanvasNode()
84 if (myPrs) delete myPrs;
87 void SUPERVGUI_CanvasNode::setDestroyed()
93 SUPERVGUI_CanvasNodePrs* SUPERVGUI_CanvasNode::getPrs() const
96 ((SUPERVGUI_CanvasNode*)this)->myPrs = createPrs();
101 SUPERVGUI_CanvasNodePrs* SUPERVGUI_CanvasNode::createPrs() const
103 return new SUPERVGUI_CanvasNodePrs(myMain->getCanvas(), (SUPERVGUI_CanvasNode*)this);
106 void SUPERVGUI_CanvasNode::createPort(SUPERV::Port_ptr thePort) const
108 SUPERVGUI_CanvasPort* aPort = 0;
109 if (thePort->IsInput())
110 aPort = new SUPERVGUI_CanvasPortIn((SUPERVGUI_CanvasNode*)this, myMain, thePort);
112 aPort = new SUPERVGUI_CanvasPortOut((SUPERVGUI_CanvasNode*)this, myMain, thePort);
115 connect(aPort, SIGNAL(destroyed(QObject*)), this, SLOT(onDestroyed(QObject*)));
116 if (!isIgnore) getPrs()->updatePorts();
120 void SUPERVGUI_CanvasNode::createStreamPort(SUPERV::StreamPort_ptr thePort) const
122 SUPERVGUI_CanvasPort* aPort = 0;
123 if (thePort->IsInput())
124 aPort = new SUPERVGUI_CanvasStreamPortIn((SUPERVGUI_CanvasNode*)this, myMain, thePort);
126 aPort = new SUPERVGUI_CanvasStreamPortOut((SUPERVGUI_CanvasNode*)this, myMain, thePort);
129 connect(aPort, SIGNAL(destroyed(QObject*)), this, SLOT(onDestroyed(QObject*)));
130 if (!isIgnore) getPrs()->updatePorts();
134 void SUPERVGUI_CanvasNode::onDestroyed(QObject* theObject)
137 removeChild(theObject); // signal is sent before removing the object
138 getPrs()->updatePorts();
142 QPopupMenu* SUPERVGUI_CanvasNode::getPopupMenu(QWidget* theParent)
144 QPopupMenu* popup = new QPopupMenu(theParent);
146 if (myMain->getDataflow()->IsExecuting()) { // Execution time
147 popup->insertItem((myNode->IsSuspended()?tr("MSG_RESUME"):tr("MSG_SUSPEND")), this, SLOT(suspendResume()));
148 popup->insertItem(tr("MSG_KILL"), this, SLOT(kill()));
150 else { // Edition time
151 const int type = getNodeType();
153 // for all nodes except EndLoop and EndSwitch : Rename, Delete, Copy
154 if ( myMain->isEditable() && type != SUPERV::EndLoopNode && type != SUPERV::EndSwitchNode ) {
155 popup->insertItem(tr("MSG_RENAME"), this, SLOT(rename()));
156 myDeleteItem = popup->insertItem(tr("MSG_DELETE"), this, SLOT(remove()));
159 // tmp: Copy temporary does not work for Macro nodes...
160 if ( type != SUPERV::MacroNode )
161 popup->insertItem(tr("ITM_COPY_NODE"), this, SLOT(copy())); // Copy Node functionality
162 popup->insertSeparator();
164 // for all nodes : Browse
165 popup->insertItem(tr("MSG_BROWSE"), this, SLOT(browse()));
167 // for all nodes except EndLoop and EndSwitch : Change info
168 if (type != SUPERV::EndLoopNode && type != SUPERV::EndSwitchNode)
169 popup->insertItem(tr("MSG_CHANGE_INFO"), this, SLOT(changeInformation()));
171 // for all InLine nodes
172 if ( type != SUPERV::FactoryNode && type != SUPERV::ComputingNode && type != SUPERV::MacroNode ) {
173 if ( myMain->isEditable() ) {
174 popup->insertSeparator();
175 popup->insertItem( tr( "MNU_EDIT_FUNC" ), this, SLOT(editFunction()));
178 // for all InLine, regardless isEditable() : Export to Library
179 popup->insertItem( tr( "MNU_EXPORT" ), this, SLOT( exportToLib()));
181 // for all InLine except EndLoop : Add Ports menu, Paste, Manage Ports
182 if ( myMain->isEditable() && type != SUPERV::EndLoopNode ) {
183 QPopupMenu* addPortMenu = new QPopupMenu(theParent);
184 addPortMenu->insertItem( tr( "MNU_INPUT" ), this, SLOT(addInputPort()));
185 if (getNodeType() != SUPERV::LoopNode)
186 addPortMenu->insertItem( tr( "MNU_OUTPUT" ), this, SLOT(addOutputPort()));
188 popup->insertItem( tr( "MNU_ADD_PORT" ), addPortMenu);
189 popup->insertItem( tr( "MNU_MANAGE_PORTS" ), this, SLOT(managePorts()));
191 // Paste Port functionality
192 int aPasteItem = popup->insertItem(tr("ITM_PASTE_PORT"), this, SLOT(pastePort()));
193 SUPERVGUI_Clipboard* aCB = SUPERVGUI_Clipboard::getClipboard();
194 if ( !aCB->isCopyPort() || (type == SUPERV::LoopNode && !aCB->getCopyPort()->IsInput()) )
195 popup->setItemEnabled( aPasteItem, false );
202 void SUPERVGUI_CanvasNode::show()
207 void SUPERVGUI_CanvasNode::showAll()
212 void SUPERVGUI_CanvasNode::hideAll()
217 void SUPERVGUI_CanvasNode::switchLabel()
219 getPrs()->setLabelVisible(!getPrs()->isLabelVisible());
222 void SUPERVGUI_CanvasNode::switchPorts()
224 getPrs()->setPortVisible(!getPrs()->isPortVisible());
227 void SUPERVGUI_CanvasNode::move(int x, int y)
229 // myNode->Coords(x, y); // <<<- done inside Prs to reflect item movement by mouse press
230 if (x > GRAPH_MAX) x = (int) getPrs()->x();
231 if (y > GRAPH_MAX) y = (int) getPrs()->y();
232 getPrs()->move(x, y);
235 void SUPERVGUI_CanvasNode::merge()
237 //MESSAGE("===> SUPERVGUI_CanvasNode::merge() " << myNode->Name());
238 // synchronize port list
241 SUPERVGUI_CanvasPort* aPort;
242 QObjectList* aPortList = queryList("SUPERVGUI_CanvasPort");
243 //cout << " get port list... " ;
244 SUPERV_Ports aPorts = myNode->Ports();
245 //cout << aPorts->length() << endl;
246 for (int i = 0; i < aPorts->length(); i++) {
247 aPort = (SUPERVGUI_CanvasPort*)
248 child(myMain->getCanvas()->getPortName(aPorts[i].in()), "SUPERVGUI_CanvasPort");
250 //cout << " update port " << aPort->name() << endl;
251 aPortList->removeRef(aPort);
255 //cout << " create port " << myMain->getCanvas()->getPortName(aPorts[i].in()) << endl;
256 createPort(aPorts[i].in());
261 //cout << " get stream port list... " ;
262 SUPERV_StreamPorts aStreamPorts = myNode->StreamPorts();
263 //cout << aStreamPorts->length() << endl;
264 for (int i = 0; i < aStreamPorts->length(); i++) {
265 aPort = (SUPERVGUI_CanvasPort*)
266 child(myMain->getCanvas()->getPortName(aStreamPorts[i].in()), "SUPERVGUI_CanvasPort");
268 //cout << " update stream port " << aPort->name() << endl;
269 aPortList->removeRef(aPort);
273 //cout << " create stream port " << myMain->getCanvas()->getPortName(aStreamPorts[i].in()) << endl;
274 createPort(aStreamPorts[i].in());
279 //cout << " remove inexistant " << endl;
280 QObjectListIt it(*aPortList);
281 while ((aPort=(SUPERVGUI_CanvasPort*)it.current()) != 0) {
283 aPortList->removeRef(aPort);
289 if (update) getPrs()->updatePorts();
291 sync(); // update node state also
294 void SUPERVGUI_CanvasNode::sync() {
295 //MESSAGE("===> SUPERVGUI_CanvasNode::sync() " << myNode->Name() << ", state " << myNode->State());
297 const bool isExecuting = myMain->getDataflow()->IsExecuting();
298 //if myNode is a MacroNode then set it state to state of its subgraph
299 if ( myNode->IsMacro() && isExecuting ) {
300 // get SubGraph from MacroNode
301 SUPERV_Graph aMacro = SUPERV::Graph::_narrow(myNode);
302 if (!SUPERV_isNull(aMacro)) {
304 if (aMacro->IsStreamMacro())
305 aGraph = aMacro->StreamObjRef();
307 aGraph = aMacro->FlowObjRef();
308 if (!SUPERV_isNull(aGraph)) {
309 if (aGraph->State() != SUPERV::UndefinedState && aGraph->State() != SUPERV::NoState)
310 getPrs()->setState(aGraph->State());
312 getPrs()->setState(myNode->State());
317 SUPERV::GraphState aState = myNode->State();
319 // asv : 18.11.04 : fix for 6170 : after execution is finished, nodes' status must be reset.
320 // asv : 13.12.04 : commented out setting EditingState. See 2.21.
321 //if ( !isExecuting && myMain->IsGUIEventLoopFinished() && (aState == SUPERV::DoneState ||
322 // aState == SUPERV::KillState || aState == SUPERV::StopState ) )
323 // aState = SUPERV::EditingState;
324 getPrs()->setState(aState);
327 // update child ports
328 const QObjectList* list = children();
330 QObjectListIt it(*list);
331 while (QObject* obj = it.current()) {
333 if (obj->inherits("SUPERVGUI_CanvasPort")) {
334 ((SUPERVGUI_CanvasPort*)obj)->sync();
340 void SUPERVGUI_CanvasNode::syncOnEvent(SUPERV::GraphState theStateFromEvent)
342 getPrs()->setState(theStateFromEvent);
345 bool SUPERVGUI_CanvasNode::setNodeName(QString aName) {
346 bool result = myNode->SetName(aName.latin1());
348 setName(myNode->Name());
349 getPrs()->updateInfo();
350 // TODO: update name of all the links to this node
353 QMessageBox::warning( QAD_Application::getDesktop(), tr( "ERROR" ), tr( "MSG_CANT_RENAMENODE" ) );
358 void SUPERVGUI_CanvasNode::rename() {
359 QString aName = SALOMEGUI_NameDlg::getName(QAD_Application::getDesktop(), myNode->Name());
360 if (!aName.isEmpty()) {
365 void SUPERVGUI_CanvasNode::remove() {
366 myMain->Editing(); // PAL6170: GUI->Engine: setting "Editing" flag
368 //set myCopyPort from Main object to empty if engine of this port is deleted
369 //check if any port of this deleted node has been copied
370 SUPERVGUI_Clipboard* aCB = SUPERVGUI_Clipboard::getClipboard();
371 if ( aCB->isCopyPort() )
372 if ( QString(myNode->Name()) == QString(aCB->getCopyPort()->Node()->Name()) )
373 aCB->setCopyPort( 0 );
375 //set myCopyNode from Main object to empty if engine of this node is deleted
376 //check if myCopyNode and this node engine is equal
377 if ( aCB->isCopyNode() )
378 if ( QString(myNode->Name()) == QString(aCB->getCopyNode()->Name()) )
379 aCB->setCopyNode( 0 );
381 Trace("SUPERVGUI_CanvasNode::remove");
382 SUPERVGUI_Canvas* aCanvas = myMain->getCanvas();
389 void SUPERVGUI_CanvasNode::copy() {
390 Trace("SUPERVGUI_CanvasNode::copy()");
391 SUPERVGUI_Clipboard* aCB = SUPERVGUI_Clipboard::getClipboard();
392 const int aKind = getNodeType();
393 if ( aKind == SUPERV::EndLoopNode || aKind == SUPERV::EndSwitchNode )
394 aCB->setCopyNode( SUPERV::CNode::_duplicate(SUPERV::GNode::_narrow(getEngine())->Coupled()) );
396 aCB->setCopyNode( SUPERV::CNode::_duplicate( getEngine() ) );
399 void SUPERVGUI_CanvasNode::suspendResume() {
400 Trace("SUPERVGUI_CanvasNode::suspendResume");
401 int n = queryList("SUPERVGUI_CanvasNode")->count();
402 if (myNode->IsSuspended()) {
403 if (!((n==1)? myMain->getDataflow()->Resume() : myNode->Resume())) {
404 QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), tr("MSG_CANT_RESUMENODE"));
408 myMain->getMyThread()->startThread(tr("MSG_NODE_RESUMED1")+myNode->Name()+tr("MSG_NODE_RESUMED2"));
411 if (!((n==1)? myMain->getDataflow()->Suspend() : myNode->Suspend())) {
412 QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), tr("MSG_CANT_SUSPENDNODE"));
414 syncOnEvent(SUPERV::SuspendReadyState);
415 myMain->getMyThread()->stopThread(tr("MSG_NODE_SUSPENDED1")+myNode->Name()+tr("MSG_NODE_SUSPENDED2"));
420 void SUPERVGUI_CanvasNode::kill() {
421 Trace("SUPERVGUI_CanvasNode::kill");
422 int n = queryList("SUPERVGUI_CanvasNode")->count();
423 if (!((n==1)? myMain->getDataflow()->Kill() : myNode->Kill())) {
424 QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), tr("MSG_CANT_KILLNODE"));
426 syncOnEvent(SUPERV_Kill);
427 myMain->getMyThread()->stopThread(tr("MSG_NODE_KILLED1")+myNode->Name()+tr("MSG_NODE_KILLED2"));
430 /* asv : 15.12.04 : commented out stopRestart() in Main and CanvasNode because it's not called from anywhere,
431 the comment from kloss (in Main.cxx) may be explaining it, but it's in French and I do not understand it..
432 void SUPERVGUI_CanvasNode::stopRestart() {
433 Trace("SUPERVGUI_CanvasNode::stopRestart");
435 int n = queryList("SUPERVGUI_CanvasNode")->count();
436 if ((myNode->State() == SUPERV_Stop) || (myNode->State() == SUPERV_Kill)) {
437 if (!((n==1)? myMain->getDataflow()->Run() : myNode->ReStart())) {
438 QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), tr("MSG_CANT_RESTARTNODE"));
441 if (!((n==1)? myMain->getDataflow()->Stop() : myNode->Stop())) {
442 QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), tr("MSG_CANT_STOPNODE"));
447 void SUPERVGUI_CanvasNode::changeInformation() {
448 SUPERVGUI_Information* aDlg = new SUPERVGUI_Information(myNode, !myMain->isEditable());
450 QString aName = myNode->Name();
451 if (!aName.isEmpty() && myMain->isEditable())
457 /* asv : 13.12.04 : The functions below are not called from anywhere, so commenting them out...
458 void SUPERVGUI_CanvasNode::configure()
460 Trace("SUPERVGUI_CanvasNode::configure");
461 QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), tr("MSG_NOT_IMPLEMENTED")); // kloss : a faire : lancer l'ihm DATA
464 void SUPERVGUI_CanvasNode::showPython()
466 Trace("SUPERVGUI_CanvasNode::showPython");
467 SUPERVGUI_Python cp(myMain->getStudy()->get_PyInterp(), !myMain->isEditable());
472 bool SUPERVGUI_CanvasNode::isWarning()
474 Trace("SUPERVGUI_CanvasNode::isWarning");
478 bool SUPERVGUI_CanvasNode::isStep()
480 Trace("SUPERVGUI_CanvasNode::isStep");
484 bool SUPERVGUI_CanvasNode::isTrace()
486 Trace("SUPERVGUI_CanvasNode::isTrace");
490 bool SUPERVGUI_CanvasNode::isVerbose()
492 Trace("SUPERVGUI_CanvasNode::isVerbose");
496 void SUPERVGUI_CanvasNode::setWarning(bool b)
498 Trace("SUPERVGUI_CanvasNode::setWarning");
502 void SUPERVGUI_CanvasNode::setStep(bool b)
504 Trace("SUPERVGUI_CanvasNode::setStep");
508 void SUPERVGUI_CanvasNode::setTrace(bool b)
510 Trace("SUPERVGUI_CanvasNode::setTrace");
514 void SUPERVGUI_CanvasNode::setVerbose(bool b)
516 Trace("SUPERVGUI_CanvasNode::setVerbose");
521 void SUPERVGUI_CanvasNode::browse()
523 myMain->Editing(); // PAL6170: GUI->Engine: setting "Editing" flag
525 myBrowseDlg = new SUPERVGUI_BrowseNodeDlg(this);
526 myBrowseDlg->installEventFilter(this);
528 if (!myBrowseDlg->isVisible())
531 myBrowseDlg->raise();
532 myBrowseDlg->setActiveWindow();
533 myBrowseDlg->setFocus();
537 bool SUPERVGUI_CanvasNode::eventFilter( QObject* o, QEvent* e )
539 if (o == myBrowseDlg && e->type() == QEvent::Close)
541 return QObject::eventFilter(o, e);
544 QStringList SUPERVGUI_CanvasNode::getPortsNamesIN(SUPERV_INode theNode, bool theInputPorts)
547 if (!SUPERV_isNull(theNode)) {
548 SUPERV_Ports aPorts = theNode->Ports();
549 for (int i=0; i<aPorts->length(); i++) {
551 if (aPorts[i]->IsInput()) aPNList.append(QString(aPorts[i]->Name()));
554 if (!aPorts[i]->IsInput()) aPNList.append(QString(aPorts[i]->Name()));
560 SUPERV_Port SUPERVGUI_CanvasNode::createInPort()
562 SUPERV_INode aNode = getInlineNode();
563 if (SUPERV_isNull(aNode)) {
564 MESSAGE("SUPERVGUI_CanvasNode::createInPort: Node is wrong type");
567 SUPERVGUI_PortParamsDlg* aDlg = new SUPERVGUI_PortParamsDlg(getPortsNamesIN(aNode,true));
569 SUPERV_Port aPort = aNode->InPort(aDlg->getName().latin1(),
570 aDlg->getType().latin1());
578 SUPERV_Port SUPERVGUI_CanvasNode::createOutPort()
580 SUPERV_INode aNode = getInlineNode();
581 if (SUPERV_isNull(aNode)) {
582 MESSAGE("SUPERVGUI_CanvasNode::createOutPort: Node is wrong type");
586 SUPERVGUI_PortParamsDlg* aDlg = new SUPERVGUI_PortParamsDlg(getPortsNamesIN(aNode,false));
588 SUPERV_Port aPort = aNode->OutPort(aDlg->getName().latin1(),
589 aDlg->getType().latin1());
597 void SUPERVGUI_CanvasNode::addInputPort() {
598 myMain->Editing(); // PAL6170: GUI->Engine: setting "Editing" flag
600 SUPERV_Port aPort = createInPort();
601 if (aPort == NULL) return;
603 createPort(aPort.in());
607 void SUPERVGUI_CanvasNode::addOutputPort() {
608 myMain->Editing(); // PAL6170: GUI->Engine: setting "Editing" flag
610 SUPERV_Port aPort = createOutPort();
611 if (aPort == NULL) return;
613 createPort(aPort.in());
617 void SUPERVGUI_CanvasNode::editFunction() {
618 myMain->Editing(); // PAL6170: GUI->Engine: setting "Editing" flag
620 if (getNodeType() == SUPERV::LoopNode) {
621 SUPERVGUI_EditPythonDlg* aDlg = new SUPERVGUI_EditPythonDlg(true);
622 SUPERV_LNode aLNode = getLoopNode();
623 aDlg->setInitFunction(aLNode->PyInit());
624 aDlg->setMoreFunction(aLNode->PyMore());
625 aDlg->setNextFunction(aLNode->PyNext());
627 aLNode->SetPyInit(aDlg->getInitFuncName().latin1(), (aDlg->getInitFunction()).in());
628 aLNode->SetPyMore(aDlg->getMoreFuncName().latin1(), (aDlg->getMoreFunction()).in());
629 aLNode->SetPyNext(aDlg->getNextFuncName().latin1(), (aDlg->getNextFunction()).in());
634 SUPERVGUI_EditPythonDlg* aDlg = new SUPERVGUI_EditPythonDlg();
635 SUPERV_INode aINode = getInlineNode();
636 aDlg->setFunction(aINode->PyFunction());
638 aINode->SetPyFunction(aDlg->getFuncName().latin1(), (aDlg->getFunction()).in());
645 * Called on "Paste port" command of popup menu
647 void SUPERVGUI_CanvasNode::pastePort() {
648 SUPERVGUI_Clipboard::getClipboard()->pastePort( this );
652 * Called on "Edit ports" popup menu command. See SUPERVGUI_ManagePortsDlg.h
653 * for detailed description of the functionality
655 void SUPERVGUI_CanvasNode::managePorts() {
656 myMain->Editing(); // PAL6170: GUI->Engine: setting "Editing" flag
658 SUPERVGUI_ManagePortsDlg* aDlg = new SUPERVGUI_ManagePortsDlg( this );
664 * Called on "Export to Library" popup menu command. See SUPERVGUI_Library.h
665 * for details on InLine nodes library functionality
667 void SUPERVGUI_CanvasNode::exportToLib() {
668 SUPERV::INode_var anINode = SUPERV::INode::_narrow( getEngine() );
669 if ( !CORBA::is_nil( anINode ) )
670 SUPERVGUI_Library::getLibrary()->Export( anINode );
672 QAD_MessageBox::error1( QAD_Application::getDesktop(), tr( "ERROR" ), tr( "MSG_BAD_INODE" ), tr( "OK" ) );