1 // SUPERV SUPERVGUI : GUI for Supervisor component
3 // Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
24 // File : SUPERVGUI_Node.cxx
25 // Author : Francis KLOSS
29 #include "SUPERVGUI_Node.h"
30 #include "SUPERVGUI_Main.h"
31 #include "SUPERVGUI_Python.h"
32 #include "SUPERVGUI.h"
33 #include "SUPERVGUI_BrowseNodeDlg.h"
34 #include "SALOMEGUI_NameDlg.h"
35 #include "SUPERVGUI_Information.h"
36 #include "SUPERVGUI_ComputeNode.h"
37 #include "SUPERVGUI_ControlNode.h"
41 #include <qlineedit.h>
42 #include <qpushbutton.h>
44 #include <qgroupbox.h>
49 SUPERVGUI_Node::SUPERVGUI_Node(QWidget* theParent, SUPERVGUI_Main* theMain, SUPERV_CNode theNode):
50 QFrame(theParent, "", WDestructiveClose),
59 Trace("SUPERVGUI_Node::SUPERVGUI_Node");
60 QPalette BackColor = QPalette(MAIN_BACK);
61 setPalette(BackColor);
63 setName(myNode->Name());
64 //myTitle = new SUPERVGUI_Label(0, LABEL_WIDTH, LABEL_HEIGHT, name(), QLabel::AlignLeft);
65 //connect(myTitle, SIGNAL(MousePress(QMouseEvent*)), this, SLOT(showPopup(QMouseEvent*)));
68 myStatus = new SUPERVGUI_Label(0, LABEL_WIDTH/2, LABEL_HEIGHT, "", QLabel::AlignHCenter);
69 myTime = new SUPERVGUI_Label(0, LABEL_WIDTH/2, LABEL_HEIGHT, "00:00:00", QLabel::AlignHCenter);
73 connect(myStatus, SIGNAL(MousePress(QMouseEvent*)), this, SLOT(showPopup(QMouseEvent*)));
74 connect(myTime, SIGNAL(MousePress(QMouseEvent*)), this, SLOT(showPopup(QMouseEvent*)));
77 myPopup = new QPopupMenu(this);
78 if (myMain->isEditable() && getNodeType() != SUPERV::EndLoopNode
79 && getNodeType() != SUPERV::EndSwitchNode) {
80 myRenameItem = myPopup->insertItem(tr("MSG_RENAME"), this, SLOT(rename()));
81 myDeleteItem = myPopup->insertItem(tr("MSG_DELETE"), this, SLOT(remove()));
82 mySeparatorId = myPopup->insertSeparator();
84 myPopup->insertItem(tr("MSG_BROWSE"), this, SLOT(browse()));
85 if ((getNodeType() != SUPERV::EndLoopNode) && (getNodeType() != SUPERV::EndSwitchNode))
86 myPopup->insertItem(tr("MSG_CHANGE_INFO"), this, SLOT(changeInformation()));
87 //myPopup->insertItem(tr("MSG_CONFIGURE"), this, SLOT(configure()));
89 if (myMain->isEditable() && (getNodeType() != SUPERV::FactoryNode)
90 && (getNodeType() != SUPERV::ComputingNode)) {
91 if ((getNodeType() != SUPERV::EndLoopNode)) {
92 QPopupMenu* aAddPortMnu = new QPopupMenu(this);
93 aAddPortMnu->insertItem("Input", this, SLOT(addInputPort()));
94 if (getNodeType() != SUPERV::LoopNode)
95 aAddPortMnu->insertItem("Output", this, SLOT(addOutputPort()));
97 myPopup->insertSeparator();
98 if ((getNodeType() != SUPERV::EndSwitchNode))
99 myPopup->insertItem("Edit Function", this, SLOT(editFunction()));
100 myPopup->insertItem("Add Port", aAddPortMnu);
104 // create execution popup
105 myRunPopup = new QPopupMenu(this);
106 mySuspendItem = myRunPopup->insertItem(tr("MSG_SUSPEND"), this, SLOT(suspendResume()));
107 myKillItem = myRunPopup->insertItem(tr("MSG_KILL"), this, SLOT(kill()));
108 //myStopItem = myRunPopup->insertItem(tr("MSG_STOP"), this, SLOT(stopRestart()));
110 setState(myNode->State());
113 SUPERVGUI_Node::~SUPERVGUI_Node()
115 Trace("SUPERVGUI_Node::~SUPERVGUI_Node")
119 void SUPERVGUI_Node::sync() {
120 // asv : 18.11.04 : fix for 6170 : after execution is finished, nodes' status must be reset.
121 // this code here seems to be executed only in Table View (array).
122 SUPERV::GraphState aState = myNode->State();
123 if ( !myMain->getDataflow()->IsExecuting() && myMain->IsGUIEventLoopFinished() &&
124 (aState == SUPERV::DoneState || aState == SUPERV::KillState || aState == SUPERV::StopState ) )
125 aState = SUPERV::EditingState;
130 void SUPERVGUI_Node::syncOnEvent(SUPERV::GraphState theStateFromEvent) {
131 setState(theStateFromEvent);
134 void SUPERVGUI_Node::setState(SUPERV::GraphState theState)
136 MESSAGE("NodeState="<<theState);
137 myRunPopup->changeItem(mySuspendItem, tr("MSG_SUSPEND"));
138 myRunPopup->setItemEnabled(mySuspendItem, true);
139 myRunPopup->setItemEnabled(myStopItem, false);
143 myStatus->setText("Waiting");
144 myStatus->setPaletteBackgroundColor(QColor(35, 192, 255));
147 case SUPERV::ReadyState:
148 myStatus->setText("Running");
149 myStatus->setPaletteBackgroundColor(QColor(32,210,32));
150 myRunPopup->changeItem(myStopItem, tr("MSG_STOP"));
151 myRunPopup->setItemEnabled(myStopItem, true);
154 case SUPERV::SuspendReadyState:
155 myStatus->setText("Suspended");
156 myStatus->setPaletteBackgroundColor(QColor(255,180, 0));
157 myRunPopup->changeItem(mySuspendItem, tr("MSG_RESUME"));
160 myStatus->setText("Finished");
161 myStatus->setPaletteBackgroundColor(QColor(255, 158, 255));
162 myRunPopup->setItemEnabled(mySuspendItem, false);
163 myRunPopup->changeItem(myStopItem, tr("MSG_RESTART"));
164 myRunPopup->setItemEnabled(myStopItem, true);
167 myStatus->setText("Aborted");
168 myStatus->setPaletteBackgroundColor(red);
169 myRunPopup->setItemEnabled(mySuspendItem, false);
170 myRunPopup->changeItem(myStopItem, tr("MSG_RESTART"));
171 myRunPopup->setItemEnabled(myStopItem, true);
174 myStatus->setText("Killed");
175 myStatus->setPaletteBackgroundColor(red);
176 myRunPopup->setItemEnabled(mySuspendItem, false);
177 myRunPopup->changeItem(myStopItem, tr("MSG_RESTART"));
178 myRunPopup->setItemEnabled(myStopItem, true);
181 myStatus->setText("No Status");
182 myStatus->setPaletteBackgroundColor(QColor(NODE_RED, NODE_GREEN, NODE_BLUE));
183 myRunPopup->setItemEnabled(mySuspendItem, false);
186 myTime->setPaletteBackgroundColor(myStatus->paletteBackgroundColor());
187 long sec = myNode->CpuUsed();
191 hms[0]=(char)(((s/10)%10)+48);
192 hms[1]=(char)((s%10)+48);
196 hms[3]=(char)((s/10)+48);
197 hms[4]=(char)((s%10)+48);
200 hms[6]=(char)((sec/10)+48);
201 hms[7]=(char)((sec%10)+48);
203 myTime->setText(hms);
206 void SUPERVGUI_Node::rename()
208 QString nm = SALOMEGUI_NameDlg::getName( QAD_Application::getDesktop(), myNode->Name() );
209 if ( !nm.isEmpty() ) {
215 void SUPERVGUI_Node::remove() {
216 Trace("SUPERVGUI_Node::remove");
219 myMain->getGraph()->deleteNode(this);
222 void SUPERVGUI_Node::suspendResume() {
223 Trace("SUPERVGUI_Node::suspendResume");
224 int n = queryList("SUPERVGUI_Node")->count();
225 if (myNode->IsSuspended()) {
226 if (!((n==1)? myMain->getDataflow()->Resume() : myNode->Resume())) {
227 QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), tr("MSG_CANT_RESUMENODE"));
230 myMain->getMyThread()->startThread(tr("MSG_NODE_RESUMED1")+myNode->Name()+tr("MSG_NODE_RESUMED2"));
233 if (!((n==1)? myMain->getDataflow()->Suspend() : myNode->Suspend())) {
234 QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), tr("MSG_CANT_SUSPENDNODE"));
236 myStatus->setPaletteBackgroundColor(QColor(255,180, 0));
237 myTime->setPaletteBackgroundColor(QColor(255,180, 0));
238 myMain->getMyThread()->stopThread(tr("MSG_NODE_SUSPENDED1")+myNode->Name()+tr("MSG_NODE_SUSPENDED2"));
243 void SUPERVGUI_Node::kill() {
244 Trace("SUPERVGUI_Node::kill");
245 int n = queryList("SUPERVGUI_Node")->count();
246 if (!((n==1)? myMain->getDataflow()->Kill() : myNode->Kill())) {
247 QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), tr("MSG_CANT_KILLNODE"));
249 myStatus->setPaletteBackgroundColor(Qt::red);
250 myTime->setPaletteBackgroundColor(Qt::red);
251 myMain->getMyThread()->stopThread(tr("MSG_NODE_KILLED1")+myNode->Name()+tr("MSG_NODE_KILLED2"));
255 void SUPERVGUI_Node::stopRestart() {
256 Trace("SUPERVGUI_Node::stopRestart");
258 int n = queryList("SUPERVGUI_Node")->count();
259 if ((myNode->State() == SUPERV_Stop) || (myNode->State() == SUPERV_Kill)) {
260 if (!((n==1)? myMain->getDataflow()->Run() : myNode->ReStart())) {
261 QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), tr("MSG_CANT_RESTARTNODE"));
264 if (!((n==1)? myMain->getDataflow()->Stop() : myNode->Stop())) {
265 QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), tr("MSG_CANT_STOPNODE"));
270 void SUPERVGUI_Node::changeInformation() {
271 SUPERVGUI_Information* aDlg = new SUPERVGUI_Information(myNode, !myMain->isEditable());
275 if (myNode->IsGOTO()) {
276 QString nmGT = myNode->Name();
277 if ( !nmGT.isEmpty() ) {
281 if (myMain->isEditable()) {
282 if (myMain->isArrayShown()) { //Table View
283 if (myNode->IsLoop() || myNode->IsSwitch()) { //for synchronic names changing
284 QString nmA = myNode->Name();
285 if ( !nmA.isEmpty() ) {
287 QString aStrA(tr("ENDNODE_PREFIX"));
289 (dynamic_cast<SUPERVGUI_Cell*>(this))->getPairCell()->getTitle()->setText(aStrA);
290 (dynamic_cast<SUPERVGUI_Cell*>(this))->getPairCell()->setNodeName(aStrA);
291 // QToolTip::remove((dynamic_cast<SUPERVGUI_Cell*>(this))->getPairCell()->getTitle());
292 QToolTip::add((dynamic_cast<SUPERVGUI_Cell*>(this))->getPairCell()->getTitle(),
293 (dynamic_cast<SUPERVGUI_Cell*>(this))->getPairCell()->getTitle()->text());
297 // QToolTip::remove((dynamic_cast<SUPERVGUI_Cell*>(this))->getTitle());
298 QToolTip::add((dynamic_cast<SUPERVGUI_Cell*>(this))->getTitle(),
299 (dynamic_cast<SUPERVGUI_Cell*>(this))->getTitle()->text());
300 QToolTip::add((dynamic_cast<SUPERVGUI_Cell*>(this))->getComponent(),
301 (dynamic_cast<SUPERVGUI_Cell*>(this))->getComponent()->text());
304 if (myNode->IsLoop() || myNode->IsSwitch()) { //for synchronic names changing
305 QString nm = myNode->Name();
306 if ( !nm.isEmpty() ) {
308 QString aStr(tr("ENDNODE_PREFIX"));
310 (dynamic_cast<SUPERVGUI_StartControlNode*>(this))->getEndNode()->setNodeName(aStr);
314 if (!(myNode->IsGOTO())) {
315 // QToolTip::remove((dynamic_cast<SUPERVGUI_ComputeNode*>(this))->getCommLabel());
316 QToolTip::add((dynamic_cast<SUPERVGUI_ComputeNode*>(this))->getCommLabel(),
317 (dynamic_cast<SUPERVGUI_ComputeNode*>(this))->getCommLabel()->text());
318 QToolTip::add((dynamic_cast<SUPERVGUI_ComputeNode*>(this))->getTitleLabel(),
319 (dynamic_cast<SUPERVGUI_ComputeNode*>(this))->getTitleLabel()->text());
324 /* Trace("SUPERVGUI_Node::changeInformation")
325 if (Supervision.information(myNode, !myMain->isEditable())) {
330 void SUPERVGUI_Node::configure() {
331 Trace("SUPERVGUI_Node::configure")
332 QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), tr("MSG_NOT_IMPLEMENTED")); // kloss : a faire : lancer l'ihm DATA
335 void SUPERVGUI_Node::showPython() {
336 Trace("SUPERVGUI_Node::showPython")
337 SUPERVGUI_Python cp(myMain->getStudy()->get_PyInterp(), !myMain->isEditable());
341 void SUPERVGUI_Node::showPopup(QMouseEvent* e) {
342 Trace("SUPERVGUI_Node::showPopup");
343 if (myMain->getDataflow()->IsExecuting())
344 myMain->showPopup(myRunPopup, e);
346 myMain->showPopup(myPopup, e);
350 void SUPERVGUI_Node::mousePressEvent(QMouseEvent* e) {
351 if (!myMain->getDataflow()->IsExecuting())
352 myMain->showPopup(myPopup, e);
356 bool SUPERVGUI_Node::isWarning() {
357 Trace("SUPERVGUI_Node::isWarning")
361 bool SUPERVGUI_Node::isStep() {
362 Trace("SUPERVGUI_Node::isStep")
366 bool SUPERVGUI_Node::isTrace() {
367 Trace("SUPERVGUI_Node::isTrace")
371 bool SUPERVGUI_Node::isVerbose() {
372 Trace("SUPERVGUI_Node::isVerbose")
376 void SUPERVGUI_Node::setWarning(bool b) {
377 Trace("SUPERVGUI_Node::setWarning")
381 void SUPERVGUI_Node::setStep(bool b) {
382 Trace("SUPERVGUI_Node::setStep")
386 void SUPERVGUI_Node::setTrace(bool b) {
387 Trace("SUPERVGUI_Node::setTrace")
391 void SUPERVGUI_Node::setVerbose(bool b) {
392 Trace("SUPERVGUI_Node::setVerbose")
397 void SUPERVGUI_Node::browse() {
399 aBrowseDlg = new SUPERVGUI_BrowseNodeDlg(this);
400 aBrowseDlg->installEventFilter( this );
402 if ( !aBrowseDlg->isVisible() )
406 aBrowseDlg->setActiveWindow();
407 aBrowseDlg->setFocus();
411 bool SUPERVGUI_Node::eventFilter( QObject* o, QEvent* e )
413 if ( o == aBrowseDlg && e->type() == QEvent::Close )
415 return QFrame::eventFilter( o, e );
419 void SUPERVGUI_Node::setNodeName(QString aName) {
420 if ( myNode->SetName(aName.latin1())) {
421 setName(myNode->Name());
422 //myTitle->setText(aName);
424 QMessageBox::warning( QAD_Application::getDesktop(), tr( "ERROR" ), tr( "MSG_CANT_RENAMENODE" ) );
427 QStringList SUPERVGUI_Node::getPortsNamesIN(SUPERV_INode theNode, bool theInputPorts)
430 if (!SUPERV_isNull(theNode)) {
431 SUPERV_Ports aPorts = theNode->Ports();
432 for (int i=0; i<aPorts->length(); i++) {
434 if (aPorts[i]->IsInput()) aPNList.append(QString(aPorts[i]->Name()));
437 if (!aPorts[i]->IsInput()) aPNList.append(QString(aPorts[i]->Name()));
443 SUPERV_Port SUPERVGUI_Node::createInPort() {
444 SUPERV_INode aNode = getInlineNode();
445 if (SUPERV_isNull(aNode)) {
446 MESSAGE("SUPERVGUI_Node::createInPort: Node is wrong type");
450 SUPERVGUI_PortParamsDlg* aDlg = new SUPERVGUI_PortParamsDlg(getPortsNamesIN(aNode,true));
452 SUPERV_Port aPort = aNode->InPort(aDlg->getName().latin1(),
453 aDlg->getType().latin1());
462 SUPERV_Port SUPERVGUI_Node::createOutPort() {
463 SUPERV_INode aNode = getInlineNode();
464 if (SUPERV_isNull(aNode)) {
465 MESSAGE("SUPERVGUI_Node::createInPort: Node is wrong type");
469 SUPERVGUI_PortParamsDlg* aDlg = new SUPERVGUI_PortParamsDlg(getPortsNamesIN(aNode,false));
471 SUPERV_Port aPort = aNode->OutPort(aDlg->getName().latin1(),
472 aDlg->getType().latin1());
482 void SUPERVGUI_Node::addInputPort() {
487 void SUPERVGUI_Node::addOutputPort() {
492 void SUPERVGUI_Node::editFunction() {
493 if (getNodeType() == SUPERV::LoopNode) {
494 SUPERVGUI_EditPythonDlg* aDlg = new SUPERVGUI_EditPythonDlg(true);
495 SUPERV_LNode aLNode = getLoopNode();
496 aDlg->setInitFunction(aLNode->PyInit());
497 aDlg->setMoreFunction(aLNode->PyMore());
498 aDlg->setNextFunction(aLNode->PyNext());
500 aLNode->SetPyInit(aDlg->getInitFuncName().latin1(), (aDlg->getInitFunction()).in());
501 aLNode->SetPyMore(aDlg->getMoreFuncName().latin1(), (aDlg->getMoreFunction()).in());
502 aLNode->SetPyNext(aDlg->getNextFuncName().latin1(), (aDlg->getNextFunction()).in());
506 SUPERVGUI_EditPythonDlg* aDlg = new SUPERVGUI_EditPythonDlg();
507 SUPERV_INode aINode = getInlineNode();
508 aDlg->setFunction(aINode->PyFunction());
510 aINode->SetPyFunction(aDlg->getFuncName().latin1(), (aDlg->getFunction()).in());
522 * Port parameters dialog definition
525 static const char* MyTypeStrings[] =
526 {"string", "boolean", "char", "short", "int", "long", "float", "double", "objref"};
528 SUPERVGUI_PortParamsDlg::SUPERVGUI_PortParamsDlg(const QStringList& thePortsNames)
529 : QDialog(QAD_Application::getDesktop(), 0, true, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu ),
530 myPortsNames(thePortsNames)
532 setSizeGripEnabled( true );
533 setCaption("Port parameters");
535 QGridLayout* aBaseLayout = new QGridLayout( this );
536 aBaseLayout->setMargin( 11 ); aBaseLayout->setSpacing( 6 );
538 QLabel* aNameLbl = new QLabel("Port Name", this );
539 aBaseLayout->addWidget(aNameLbl, 0, 0);
541 myNameTxt = new QLineEdit( this );
542 aNameLbl->setBuddy( myNameTxt );
543 aBaseLayout->addWidget(myNameTxt, 0, 1);
545 QLabel* aTypeLbl = new QLabel("Value Type", this );
546 aBaseLayout->addWidget(aTypeLbl, 1, 0);
548 myTypeTxt = new QComboBox( this );
549 aTypeLbl->setBuddy( myTypeTxt );
550 myTypeTxt->insertStrList( MyTypeStrings );
551 aBaseLayout->addWidget(myTypeTxt, 1, 1);
553 QGroupBox* aBtnBox = new QGroupBox( this );
554 aBtnBox->setColumnLayout( 0, Qt::Vertical );
555 aBtnBox->layout()->setSpacing( 0 ); aBtnBox->layout()->setMargin( 0 );
556 QHBoxLayout* aBtnLayout = new QHBoxLayout( aBtnBox->layout() );
557 aBtnLayout->setAlignment( Qt::AlignTop );
558 aBtnLayout->setSpacing( 6 ); aBtnLayout->setMargin( 11 );
560 aBaseLayout->addMultiCellWidget( aBtnBox, 2, 2, 0, 1 );
562 QPushButton* aOKBtn = new QPushButton( tr( "BUT_OK" ), aBtnBox );
563 connect( aOKBtn, SIGNAL( clicked() ), this, SLOT( clickOnOk() ) );
564 aBtnLayout->addWidget( aOKBtn );
566 aBtnLayout->addStretch();
568 QPushButton* aCancelBtn = new QPushButton( tr("BUT_CANCEL"), aBtnBox );
569 connect( aCancelBtn, SIGNAL( clicked() ), this, SLOT( reject() ) );
570 aBtnLayout->addWidget( aCancelBtn );
573 void SUPERVGUI_PortParamsDlg::clickOnOk()
575 if (getName().isEmpty() || getType().isEmpty())
576 QMessageBox::warning( QAD_Application::getDesktop(), tr( "ERROR" ), tr( "MSG_CANT_CREATE_PORT" ) );
577 else if (myPortsNames.contains(getName()))
578 QMessageBox::warning( QAD_Application::getDesktop(), tr("ERROR"), tr("MSG_PORT_EXIST") );