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 "SalomeApp_NameDlg.h"
22 #include "SUIT_MessageBox.h"
23 #include "LogWindow.h"
24 #include "SUIT_Session.h"
27 SUPERVGUI_CanvasNode::SUPERVGUI_CanvasNode(QObject* theParent, SUPERVGUI_Main* theMain, SUPERV_CNode theNode, bool theIsCell):
39 Trace("SUPERVGUI_CanvasNode::SUPERVGUI_CanvasNode");
41 setName(myNode->Name());
43 QString aComment(myNode->Comment());
44 QString aNewComment = aComment;
45 if (getNodeType() == SUPERV::FactoryNode) {
46 aNewComment = QString(myNode->Service()->ServiceName) +
47 QString(tr("COMMENT_FROM")) +
48 QString(getFactoryNode()->GetComponentName());
50 else if (myNode->IsMacro()) {
51 aNewComment = tr("COMMENT_MNODE");
54 aNewComment = tr("COMMENT_CNODE");
56 if (aComment.isEmpty()) {
57 myNode->SetComment(aNewComment.latin1());
60 myLabelText = aNewComment;
62 // mkr : if the SUPERVGUI_CavasCellNode created (for CANVASTABLE view),
63 // we don't create the ports
67 SUPERV_Ports aPortList = myNode->Ports();
68 for (int i = 0; i < aPortList->length(); i++)
69 createPort(aPortList[i].in());
71 SUPERV_StreamPorts aStreamPortList = myNode->StreamPorts();
72 for (int i = 0; i < aStreamPortList->length(); i++) {
73 createStreamPort(aStreamPortList[i].in());
80 SUPERVGUI_CanvasNode::~SUPERVGUI_CanvasNode()
90 void SUPERVGUI_CanvasNode::setDestroyed()
96 SUPERVGUI_CanvasNodePrs* SUPERVGUI_CanvasNode::getPrs()
104 SUPERVGUI_CanvasNodePrs* SUPERVGUI_CanvasNode::createPrs() const
106 return new SUPERVGUI_CanvasNodePrs(myMain->getCanvas(), (SUPERVGUI_CanvasNode*)this);
109 void SUPERVGUI_CanvasNode::createPort(SUPERV::Port_ptr thePort)
111 SUPERVGUI_CanvasPort* aPort = 0;
112 if (thePort->IsInput())
113 aPort = new SUPERVGUI_CanvasPortIn((SUPERVGUI_CanvasNode*)this, myMain, thePort);
115 aPort = new SUPERVGUI_CanvasPortOut((SUPERVGUI_CanvasNode*)this, myMain, thePort);
118 connect(aPort, SIGNAL(destroyed(QObject*)), this, SLOT(onDestroyed(QObject*)));
119 if (!isIgnore) getPrs()->updatePorts();
123 void SUPERVGUI_CanvasNode::createStreamPort(SUPERV::StreamPort_ptr thePort)
125 SUPERVGUI_CanvasPort* aPort = 0;
126 if (thePort->IsInput())
127 aPort = new SUPERVGUI_CanvasStreamPortIn((SUPERVGUI_CanvasNode*)this, myMain, thePort);
129 aPort = new SUPERVGUI_CanvasStreamPortOut((SUPERVGUI_CanvasNode*)this, myMain, thePort);
132 connect(aPort, SIGNAL(destroyed(QObject*)), this, SLOT(onDestroyed(QObject*)));
133 if (!isIgnore) getPrs()->updatePorts();
137 void SUPERVGUI_CanvasNode::onDestroyed(QObject* theObject)
140 removeChild(theObject); // signal is sent before removing the object
141 getPrs()->updatePorts();
145 QPopupMenu* SUPERVGUI_CanvasNode::getPopupMenu(QWidget* theParent)
147 QPopupMenu* popup = new QPopupMenu(theParent);
149 if (myMain->getDataflow()->IsExecuting()) { // Execution time
150 popup->insertItem((myNode->IsSuspended()?tr("MSG_RESUME"):tr("MSG_SUSPEND")), this, SLOT(suspendResume()));
151 popup->insertItem(tr("MSG_KILL"), this, SLOT(kill()));
153 else { // Edition time
154 const int type = getNodeType();
156 // for all nodes except EndLoop and EndSwitch : Rename, Delete, Copy
157 if ( myMain->isEditable() && type != SUPERV::EndLoopNode && type != SUPERV::EndSwitchNode &&
158 // asv 26.01.05 : don't allow nodes "edition" commands in Table view
159 myMain->getViewType() != CANVASTABLE ) {
160 popup->insertItem(tr("MSG_RENAME"), this, SLOT(rename()));
161 popup->insertItem(tr("MSG_DELETE"), this, SLOT(remove()));
164 // tmp: Copy temporary does not work for Macro nodes...
165 if ( type != SUPERV::MacroNode )
166 popup->insertItem(tr("ITM_COPY_NODE"), this, SLOT(copy())); // Copy Node functionality
167 popup->insertSeparator();
169 // for all nodes : Browse
170 popup->insertItem(tr("MSG_BROWSE"), this, SLOT(browse()));
172 // for all nodes except EndLoop and EndSwitch : Change info
173 if (type != SUPERV::EndLoopNode && type != SUPERV::EndSwitchNode)
174 popup->insertItem(tr("MSG_CHANGE_INFO"), this, SLOT(changeInformation()));
176 // for all InLine nodes
177 if ( type != SUPERV::FactoryNode && type != SUPERV::ComputingNode && type != SUPERV::MacroNode ) {
178 if ( myMain->isEditable() ) {
179 popup->insertSeparator();
180 popup->insertItem( tr( "MNU_EDIT_FUNC" ), this, SLOT(editFunction()));
183 // for all InLine, regardless isEditable() : Export to Library
184 popup->insertItem( tr( "MNU_EXPORT" ), this, SLOT( exportToLib()));
186 // for all InLine except EndLoop : Add Ports menu, Paste, Manage Ports
187 if ( myMain->isEditable() && type != SUPERV::EndLoopNode ) {
188 QPopupMenu* addPortMenu = new QPopupMenu(theParent);
189 addPortMenu->insertItem( tr( "MNU_INPUT" ), this, SLOT(addInputPort()));
190 if (getNodeType() != SUPERV::LoopNode)
191 addPortMenu->insertItem( tr( "MNU_OUTPUT" ), this, SLOT(addOutputPort()));
193 popup->insertItem( tr( "MNU_ADD_PORT" ), addPortMenu);
194 popup->insertItem( tr( "MNU_MANAGE_PORTS" ), this, SLOT(managePorts()));
196 // Paste Port functionality
197 int aPasteItem = popup->insertItem(tr("ITM_PASTE_PORT"), this, SLOT(pastePort()));
198 SUPERVGUI_Clipboard* aCB = SUPERVGUI_Clipboard::getClipboard();
199 if ( !aCB->isCopyPort() || (type == SUPERV::LoopNode && !aCB->getCopyPort()->IsInput()) )
200 popup->setItemEnabled( aPasteItem, false );
207 void SUPERVGUI_CanvasNode::show()
212 void SUPERVGUI_CanvasNode::showAll()
217 void SUPERVGUI_CanvasNode::hideAll()
222 void SUPERVGUI_CanvasNode::switchLabel()
224 getPrs()->setLabelVisible(!getPrs()->isLabelVisible());
227 void SUPERVGUI_CanvasNode::switchPorts()
229 getPrs()->setPortVisible(!getPrs()->isPortVisible());
232 void SUPERVGUI_CanvasNode::move(int x, int y)
234 // myNode->Coords(x, y); // <<<- done inside Prs to reflect item movement by mouse press
235 if (x > GRAPH_MAX) x = (int) getPrs()->x();
236 if (y > GRAPH_MAX) y = (int) getPrs()->y();
237 getPrs()->move(x, y);
240 void SUPERVGUI_CanvasNode::merge()
242 // synchronize port list
245 SUPERVGUI_CanvasPort* aPort;
246 QObjectList* aPortList = queryList("SUPERVGUI_CanvasPort");
247 SUPERV_Ports aPorts = myNode->Ports();
248 for (int i = 0; i < aPorts->length(); i++) {
249 aPort = (SUPERVGUI_CanvasPort*)
250 child(myMain->getCanvas()->getPortName(aPorts[i].in()), "SUPERVGUI_CanvasPort");
252 aPortList->removeRef(aPort);
256 createPort(aPorts[i].in());
261 SUPERV_StreamPorts aStreamPorts = myNode->StreamPorts();
262 for (int i = 0; i < aStreamPorts->length(); i++) {
263 aPort = (SUPERVGUI_CanvasPort*)
264 child(myMain->getCanvas()->getPortName(aStreamPorts[i].in()), "SUPERVGUI_CanvasPort");
266 aPortList->removeRef(aPort);
270 createPort(aStreamPorts[i].in());
275 QObjectListIt it(*aPortList);
276 while ((aPort=(SUPERVGUI_CanvasPort*)it.current()) != 0) {
278 aPortList->removeRef(aPort);
284 if (update) getPrs()->updatePorts();
286 sync(); // update node state also
289 void SUPERVGUI_CanvasNode::sync() {
290 const bool isExecuting = myMain->getDataflow()->IsExecuting();
291 if ( myNode->IsMacro() && isExecuting ) {
292 // get SubGraph from MacroNode
293 SUPERV_Graph aMacro = SUPERV::Graph::_narrow(myNode);
294 if (!SUPERV_isNull(aMacro)) {
296 if (aMacro->IsStreamMacro())
297 aGraph = aMacro->StreamObjRef();
299 aGraph = aMacro->FlowObjRef();
300 if (!SUPERV_isNull(aGraph)) {
301 if (aGraph->State() != SUPERV::UndefinedState && aGraph->State() != SUPERV::NoState)
302 getPrs()->setState(aGraph->State());
304 getPrs()->setState(myNode->State());
309 SUPERV::GraphState aState = myNode->State();
311 // asv : 18.11.04 : fix for 6170 : after execution is finished, nodes' status must be reset.
312 // asv : 13.12.04 : commented out setting EditingState. See 2.21.
313 //if ( !isExecuting && myMain->IsGUIEventLoopFinished() && (aState == SUPERV::DoneState ||
314 // aState == SUPERV::KillState || aState == SUPERV::StopState ) )
315 // aState = SUPERV::EditingState;
316 getPrs()->setState(aState);
319 // update child ports
320 const QObjectList* list = children();
322 QObjectListIt it(*list);
323 while (QObject* obj = it.current()) {
325 if (obj->inherits("SUPERVGUI_CanvasPort")) {
326 ((SUPERVGUI_CanvasPort*)obj)->sync();
332 void SUPERVGUI_CanvasNode::syncOnEvent(SUPERV::GraphState theStateFromEvent)
334 getPrs()->setState(theStateFromEvent);
337 bool SUPERVGUI_CanvasNode::setNodeName(QString aName) {
338 bool result = myNode->SetName(aName.latin1());
340 setName(myNode->Name());
341 getPrs()->updateInfo();
342 // TODO: update name of all the links to this node
345 QMessageBox::warning( SUIT_Session::session()->activeApplication()->desktop(), tr( "ERROR" ), tr( "MSG_CANT_RENAMENODE" ) );
350 void SUPERVGUI_CanvasNode::rename() {
351 QString aName = SalomeApp_NameDlg::getName( SUIT_Session::session()->activeApplication()->desktop(), myNode->Name() );
352 if (!aName.isEmpty()) {
357 void SUPERVGUI_CanvasNode::remove() {
358 Trace("SUPERVGUI_CanvasNode::remove");
359 myMain->Editing(); // PAL6170: GUI->Engine: setting "Editing" flag
361 //set myCopyPort from Main object to empty if engine of this port is deleted
362 //check if any port of this deleted node has been copied
363 SUPERVGUI_Clipboard* aCB = SUPERVGUI_Clipboard::getClipboard();
364 if ( aCB->isCopyPort() )
365 if ( QString(myNode->Name()) == QString(aCB->getCopyPort()->Node()->Name()) )
366 aCB->setCopyPort( 0 );
368 //set myCopyNode from Main object to empty if engine of this node is deleted
369 //check if myCopyNode and this node engine is equal
370 if ( aCB->isCopyNode() )
371 if ( QString(myNode->Name()) == QString(aCB->getCopyNode()->Name()) )
372 aCB->setCopyNode( 0 );
374 // mkr: since the deletion of the node allow only in CANVAS view,
375 // it is necessary to remove the CanvasArray's children, which
376 // have the same CNode engine as deleting node
377 myMain->removeArrayChild(myNode);
379 SUPERVGUI_Canvas* aCanvas = myMain->getCanvas();
386 void SUPERVGUI_CanvasNode::copy() {
387 Trace("SUPERVGUI_CanvasNode::copy()");
388 SUPERVGUI_Clipboard* aCB = SUPERVGUI_Clipboard::getClipboard();
389 const int aKind = getNodeType();
390 if ( aKind == SUPERV::EndLoopNode || aKind == SUPERV::EndSwitchNode )
391 aCB->setCopyNode( SUPERV::CNode::_duplicate(SUPERV::GNode::_narrow(getEngine())->Coupled()) );
393 aCB->setCopyNode( SUPERV::CNode::_duplicate( getEngine() ) );
396 void SUPERVGUI_CanvasNode::suspendResume() {
397 Trace("SUPERVGUI_CanvasNode::suspendResume");
398 int n = queryList("SUPERVGUI_CanvasNode")->count();
399 if (myNode->IsSuspended()) {
400 if (!((n==1)? myMain->getDataflow()->Resume() : myNode->Resume())) {
401 QMessageBox::warning( SUIT_Session::session()->activeApplication()->desktop(), tr("ERROR"), tr("MSG_CANT_RESUMENODE") );
405 myMain->getMyThread()->startThread(tr("MSG_NODE_RESUMED1")+myNode->Name()+tr("MSG_NODE_RESUMED2"));
408 if (!((n==1)? myMain->getDataflow()->Suspend() : myNode->Suspend())) {
409 QMessageBox::warning( SUIT_Session::session()->activeApplication()->desktop(), tr("ERROR"), tr("MSG_CANT_SUSPENDNODE") );
411 syncOnEvent(SUPERV::SuspendReadyState);
412 myMain->getMessage()->putMessage(tr("MSG_NODE_SUSPENDED1")+myNode->Name()+tr("MSG_NODE_SUSPENDED2"));
417 void SUPERVGUI_CanvasNode::kill() {
418 Trace("SUPERVGUI_CanvasNode::kill");
419 int n = queryList("SUPERVGUI_CanvasNode")->count();
420 if (!((n==1)? myMain->getDataflow()->Kill() : myNode->Kill())) {
421 QMessageBox::warning( SUIT_Session::session()->activeApplication()->desktop(), tr("ERROR"), tr("MSG_CANT_KILLNODE") );
423 syncOnEvent(SUPERV_Kill);
424 myMain->getMessage()->putMessage(tr("MSG_NODE_KILLED1")+myNode->Name()+tr("MSG_NODE_KILLED2"));
427 /* asv : 15.12.04 : commented out stopRestart() in Main and CanvasNode because it's not called from anywhere,
428 the comment from kloss (in Main.cxx) may be explaining it, but it's in French and I do not understand it..
429 void SUPERVGUI_CanvasNode::stopRestart() {
430 Trace("SUPERVGUI_CanvasNode::stopRestart");
432 int n = queryList("SUPERVGUI_CanvasNode")->count();
433 if ((myNode->State() == SUPERV_Stop) || (myNode->State() == SUPERV_Kill)) {
434 if (!((n==1)? myMain->getDataflow()->Run() : myNode->ReStart())) {
435 QMessageBox::warning( SUIT_Session::session()->activeApplication()->desktop(), tr("ERROR"), tr("MSG_CANT_RESTARTNODE") );
438 if (!((n==1)? myMain->getDataflow()->Stop() : myNode->Stop())) {
439 QMessageBox::warning( SUIT_Session::session()->activeApplication()->desktop(), tr("ERROR"), tr("MSG_CANT_STOPNODE") );
444 void SUPERVGUI_CanvasNode::changeInformation() {
445 SUPERVGUI_Information* aDlg = new SUPERVGUI_Information(myNode, !myMain->isEditable());
447 QString aName = myNode->Name();
448 if (!aName.isEmpty() && myMain->isEditable())
454 /* asv : 13.12.04 : The functions below are not called from anywhere, so commenting them out...
455 void SUPERVGUI_CanvasNode::configure()
457 Trace("SUPERVGUI_CanvasNode::configure");
458 QMessageBox::warning( SUIT_Session::session()->activeApplication()->desktop(), tr("ERROR"), tr("MSG_NOT_IMPLEMENTED") ); // kloss : a faire : lancer l'ihm DATA
461 void SUPERVGUI_CanvasNode::showPython()
463 Trace("SUPERVGUI_CanvasNode::showPython");
464 SUPERVGUI_Python cp(myMain->getStudy()->get_PyInterp(), !myMain->isEditable());
469 bool SUPERVGUI_CanvasNode::isWarning()
471 Trace("SUPERVGUI_CanvasNode::isWarning");
475 bool SUPERVGUI_CanvasNode::isStep()
477 Trace("SUPERVGUI_CanvasNode::isStep");
481 bool SUPERVGUI_CanvasNode::isTrace()
483 Trace("SUPERVGUI_CanvasNode::isTrace");
487 bool SUPERVGUI_CanvasNode::isVerbose()
489 Trace("SUPERVGUI_CanvasNode::isVerbose");
493 void SUPERVGUI_CanvasNode::setWarning(bool b)
495 Trace("SUPERVGUI_CanvasNode::setWarning");
499 void SUPERVGUI_CanvasNode::setStep(bool b)
501 Trace("SUPERVGUI_CanvasNode::setStep");
505 void SUPERVGUI_CanvasNode::setTrace(bool b)
507 Trace("SUPERVGUI_CanvasNode::setTrace");
511 void SUPERVGUI_CanvasNode::setVerbose(bool b)
513 Trace("SUPERVGUI_CanvasNode::setVerbose");
518 void SUPERVGUI_CanvasNode::browse()
520 // asv 28.01.05 : set "Editing" flag only on "OK" pressed in BrowseDlg
521 //myMain->Editing(); // PAL6170: GUI->Engine: setting "Editing" flag
523 myBrowseDlg = new SUPERVGUI_BrowseNodeDlg(this);
524 myBrowseDlg->installEventFilter(this);
526 if (!myBrowseDlg->isVisible())
529 myBrowseDlg->raise();
530 myBrowseDlg->setActiveWindow();
531 myBrowseDlg->setFocus();
535 bool SUPERVGUI_CanvasNode::eventFilter( QObject* o, QEvent* e )
537 if (o == myBrowseDlg && e->type() == QEvent::Close)
539 return QObject::eventFilter(o, e);
542 QStringList SUPERVGUI_CanvasNode::getPortsNamesIN(SUPERV_INode theNode, bool theInputPorts)
545 if (!SUPERV_isNull(theNode)) {
546 SUPERV_Ports aPorts = theNode->Ports();
547 for (int i=0; i<aPorts->length(); i++) {
549 if (aPorts[i]->IsInput()) aPNList.append(QString(aPorts[i]->Name()));
552 if (!aPorts[i]->IsInput()) aPNList.append(QString(aPorts[i]->Name()));
558 SUPERV_Port SUPERVGUI_CanvasNode::createInPort()
560 SUPERV_INode aNode = getInlineNode();
561 if (SUPERV_isNull(aNode)) {
562 MESSAGE("SUPERVGUI_CanvasNode::createInPort: Node is wrong type");
565 SUPERVGUI_PortParamsDlg* aDlg = new SUPERVGUI_PortParamsDlg(getPortsNamesIN(aNode,true));
567 myMain->Editing(); // PAL6170: GUI->Engine: setting "Editing" flag
568 SUPERV_Port aPort = aNode->InPort(aDlg->getName().latin1(),
569 aDlg->getType().latin1());
577 SUPERV_Port SUPERVGUI_CanvasNode::createOutPort()
579 SUPERV_INode aNode = getInlineNode();
580 if (SUPERV_isNull(aNode)) {
581 MESSAGE("SUPERVGUI_CanvasNode::createOutPort: Node is wrong type");
585 SUPERVGUI_PortParamsDlg* aDlg = new SUPERVGUI_PortParamsDlg(getPortsNamesIN(aNode,false));
587 myMain->Editing(); // PAL6170: GUI->Engine: setting "Editing" flag
588 SUPERV_Port aPort = aNode->OutPort(aDlg->getName().latin1(),
589 aDlg->getType().latin1());
597 void SUPERVGUI_CanvasNode::addInputPort() {
598 SUPERV_Port aPort = createInPort();
599 if (aPort == NULL || CORBA::is_nil( aPort ) ) return;
601 createPort(aPort.in());
605 void SUPERVGUI_CanvasNode::addOutputPort() {
606 SUPERV_Port aPort = createOutPort();
607 if (aPort == NULL || CORBA::is_nil( aPort ) ) return;
609 createPort(aPort.in());
613 void SUPERVGUI_CanvasNode::editFunction() {
614 if (getNodeType() == SUPERV::LoopNode) {
615 SUPERVGUI_EditPythonDlg* aDlg = new SUPERVGUI_EditPythonDlg(true);
616 SUPERV_LNode aLNode = getLoopNode();
617 aDlg->setInitFunction(aLNode->PyInit());
618 aDlg->setMoreFunction(aLNode->PyMore());
619 aDlg->setNextFunction(aLNode->PyNext());
621 myMain->Editing(); // PAL6170: GUI->Engine: setting "Editing" flag
622 aLNode->SetPyInit(aDlg->getInitFuncName().latin1(), (aDlg->getInitFunction()).in());
623 aLNode->SetPyMore(aDlg->getMoreFuncName().latin1(), (aDlg->getMoreFunction()).in());
624 aLNode->SetPyNext(aDlg->getNextFuncName().latin1(), (aDlg->getNextFunction()).in());
629 SUPERVGUI_EditPythonDlg* aDlg = new SUPERVGUI_EditPythonDlg();
630 SUPERV_INode aINode = getInlineNode();
631 aDlg->setFunction(aINode->PyFunction());
633 myMain->Editing(); // PAL6170: GUI->Engine: setting "Editing" flag
634 aINode->SetPyFunction(aDlg->getFuncName().latin1(), (aDlg->getFunction()).in());
641 * Called on "Paste port" command of popup menu
643 void SUPERVGUI_CanvasNode::pastePort() {
644 SUPERVGUI_Clipboard::getClipboard()->pastePort( this );
648 * Called on "Edit ports" popup menu command. See SUPERVGUI_ManagePortsDlg.h
649 * for detailed description of the functionality
651 void SUPERVGUI_CanvasNode::managePorts() {
652 SUPERVGUI_ManagePortsDlg* aDlg = new SUPERVGUI_ManagePortsDlg( this );
658 * Called on "Export to Library" popup menu command. See SUPERVGUI_Library.h
659 * for details on InLine nodes library functionality
661 void SUPERVGUI_CanvasNode::exportToLib() {
662 SUPERV::INode_var anINode = SUPERV::INode::_narrow( getEngine() );
663 if ( !CORBA::is_nil( anINode ) )
664 SUPERVGUI_Library::getLibrary()->Export( anINode );
666 SUIT_MessageBox::error1( SUIT_Session::session()->activeApplication()->desktop(), tr( "ERROR" ), tr( "MSG_BAD_INODE" ), tr( "OK" ) );