X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2FSUPERVGUI%2FSUPERVGUI_Service.cxx;h=3afcebbf2ff55fe2c6be16c0feac03eb04271a4e;hb=ed517f645b65dc8cb51fb377598adb8a4d9319f8;hp=2b13b08f9d0f466ae2a8f7347aa5b00664b542c5;hpb=7467fa6b4d1c728084256fc2b9a143b25da98426;p=modules%2Fsuperv.git diff --git a/src/SUPERVGUI/SUPERVGUI_Service.cxx b/src/SUPERVGUI/SUPERVGUI_Service.cxx index 2b13b08..3afcebb 100644 --- a/src/SUPERVGUI/SUPERVGUI_Service.cxx +++ b/src/SUPERVGUI/SUPERVGUI_Service.cxx @@ -28,15 +28,22 @@ using namespace std; #include "SUPERVGUI_Service.h" #include "SUPERVGUI_Main.h" +#include "SUPERVGUI_Library.h" #include "SUPERVGUI.h" -#include "QAD_Tools.h" -#include "QAD_FileDlg.h" + +#include "CAM_Application.h" +#include "SUIT_Desktop.h" +#include "SUIT_FileDlg.h" +#include "SUIT_Session.h" +#include "SUIT_Tools.h" #include "SALOME_NamingService.hxx" #include CORBA_CLIENT_HEADER(SALOME_ModuleCatalog) +#include #include +#include #include - +#include static const char * ComponentIcon[] = { "20 20 2 1", @@ -93,8 +100,8 @@ static const char * InterfaceIcon[] = { SUPERVGUI_Service::SUPERVGUI_Service(SALOME_NamingService* ns): - QDialog(QAD_Application::getDesktop(), 0, false, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu), - naming(ns) + QDialog(SUIT_Session::session()->activeApplication()->desktop(), 0, false, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu), + naming(ns), myMFile(0) { setSizeGripEnabled( true ); setCaption(tr("TIT_SERVICES")); @@ -127,16 +134,16 @@ SUPERVGUI_Service::SUPERVGUI_Service(SALOME_NamingService* ns): //QHGroupBox* aAddBox = new QHGroupBox(tr("TIT_ADDNODE"), aCorbaPane); //!! //aAddBox->setInsideSpacing(20); //!! - QPushButton* aComputeCBtn = new QPushButton(tr("TIT_ADDCNODE"), aCorbaPane); //!! - connect(aComputeCBtn, SIGNAL(clicked()), this, SLOT(addComputeNode())); //!! - aComputeCBtn->setDefault(false); +//NRI QPushButton* aComputeCBtn = new QPushButton(tr("TIT_ADDCNODE"), aCorbaPane); //!! +//NRI connect(aComputeCBtn, SIGNAL(clicked()), this, SLOT(addComputeNode())); //!! +//NRI aComputeCBtn->setDefault(false); QPushButton* aComputeBtn = new QPushButton(tr("TIT_ADDFNODE"), aCorbaPane); connect(aComputeBtn, SIGNAL(clicked()), this, SLOT(addFactoryNode())); aComputeBtn->setDefault(true); aBaseLayout->addWidget(aComputeBtn); - aBaseLayout->addWidget(aComputeCBtn); //!! + //NRI aBaseLayout->addWidget(aComputeCBtn); //!! aBaseLayoutV->insertLayout(-1, aBaseLayout); myTabPane->addTab(aCorbaPane, tr("MODULES_PANE")); @@ -152,14 +159,13 @@ SUPERVGUI_Service::SUPERVGUI_Service(SALOME_NamingService* ns): QHGroupBox* aAddBox2 = new QHGroupBox(tr("TIT_ADDNODE"), aPythonPane); aAddBox2->setInsideSpacing(20); - QLabel* aTypeLbl = new QLabel(tr("LBL_NODETYPE"), aAddBox2); + /*QLabel* aTypeLbl = */new QLabel(tr("LBL_NODETYPE"), aAddBox2); myTypeCombo = new QComboBox(aAddBox2); - myTypeCombo->insertItem("Computation"); - myTypeCombo->insertItem("Switch"); - myTypeCombo->insertItem("Loop"); - myTypeCombo->insertItem("GoTo"); - //myTypeCombo->insertItem("Label"); + myTypeCombo->insertItem( tr( "INLINE_COMP" ) ); + myTypeCombo->insertItem( tr( "INLINE_SWTC" ) ); + myTypeCombo->insertItem( tr( "INLINE_LOOP" ) ); + myTypeCombo->insertItem( tr( "INLINE_GOTO") ); connect(myTypeCombo, SIGNAL(activated(int)), this, SLOT(typeNodeSelected(int))); aPythonLayout->addWidget(aAddBox2); @@ -168,18 +174,18 @@ SUPERVGUI_Service::SUPERVGUI_Service(SALOME_NamingService* ns): myStackWidget = new QWidgetStack(aPythonPane); // other pane - myScriptPane = new SUPERVGUI_PythonEditPane(myStackWidget); + myScriptPane = new SUPERVGUI_PythonEditPane( myStackWidget, true, myX, myY ); myOtherId = myStackWidget->addWidget(myScriptPane); // loop pane QTabWidget* aLoopTabPane = new QTabWidget(myStackWidget); - myInitPane = new SUPERVGUI_PythonEditPane(myStackWidget); + myInitPane = new SUPERVGUI_PythonEditPane( myStackWidget, true, myX, myY ); aLoopTabPane->addTab(myInitPane, "Init"); - myMorePane = new SUPERVGUI_PythonEditPane(myStackWidget); + myMorePane = new SUPERVGUI_PythonEditPane( myStackWidget, true, myX, myY ); aLoopTabPane->addTab(myMorePane, "More"); - myNextPane = new SUPERVGUI_PythonEditPane(myStackWidget); + myNextPane = new SUPERVGUI_PythonEditPane( myStackWidget, true, myX, myY ); aLoopTabPane->addTab(myNextPane, "Next"); myLoopId = myStackWidget->addWidget(aLoopTabPane); @@ -194,6 +200,43 @@ SUPERVGUI_Service::SUPERVGUI_Service(SALOME_NamingService* ns): myTabPane->addTab(aPythonPane, tr("INLINE_PANE")); + // Create Tab for Macro node only if environmental variable ENABLE_MACRO_NODE is set + if ( getenv( "ENABLE_MACRO_NODE" ) != NULL ) { + QWidget* aMacroPane = new QWidget(myTabPane); + QVBoxLayout* aMacroLayout = new QVBoxLayout(aMacroPane, 0, 4); + aMacroLayout->setMargin(5); + aMacroLayout->setSpacing(10); + + QHBoxLayout* aLoadLayout = new QHBoxLayout(aMacroPane); //!! + aLoadLayout->addStretch(); + + QPushButton* aLoadBtn = new QPushButton(tr("BUT_LOAD"), aMacroPane); + connect(aLoadBtn, SIGNAL(clicked()), this, SLOT(loadGraph())); + + aLoadLayout->addWidget(aLoadBtn); + + aMacroLayout->addLayout(aLoadLayout); + + myMacroPane = new QListView(aMacroPane); + myMacroPane->addColumn(tr("COL_COMPONENTS")); + myMacroPane->addColumn(tr("COL_PORTTYPE")); + myMacroPane->addColumn(tr("COL_PORTWAY")); + myMacroPane->setColumnAlignment(1, AlignLeft); + myMacroPane->setColumnAlignment(2, AlignLeft); + myMacroPane->setColumnAlignment(3, AlignLeft); + myMacroPane->setSelectionMode(QListView::Extended); + myMacroPane->setRootIsDecorated(true); + aMacroLayout->addWidget(myMacroPane); //!! + + QPushButton* aAddBtn = new QPushButton(tr("TIT_ADDFNODE"), aMacroPane); + connect(aAddBtn, SIGNAL(clicked()), this, SLOT(addMacroNode())); + aAddBtn->setDefault(true); + + aMacroLayout->addWidget(aAddBtn); + + myTabPane->addTab(aMacroPane, tr("MACRO_PANE")); + } + aMainLayout->addWidget(myTabPane); // Close button @@ -213,6 +256,23 @@ SUPERVGUI_Service::SUPERVGUI_Service(SALOME_NamingService* ns): } +char* getDataStreamParameterName(int aType) +{ + switch(aType) { + case 1: + return "integer"; + case 2: + return "float"; + case 3: + return "double"; + case 4: + return "string"; + case 6: + return "boolean"; + default: + return "unknown"; + } +} void SUPERVGUI_Service::initialise() { CORBA::Object_ptr obj = naming->Resolve("/Kernel/ModulCatalog"); @@ -223,20 +283,19 @@ void SUPERVGUI_Service::initialise() { return; } - QAD_ResourceMgr* aResMgr = QAD_Desktop::createResourceManager(); + SUIT_ResourceMgr* aResMgr = SUIT_Session::session()->resourceMgr(); SALOME_ModuleCatalog::ListOfComponents_var lComponents = (*aModuleCatalog)->GetComponentList(); long nbComp = lComponents->length(); for (int i=0; iGetComponent((char *)lComponents[i]); - QListViewItem* myComponentItem = new QListViewItem(components, (char*)lComponents[i]); + QListViewItem* myComponentItem = new QListViewItem(components, (char*)C->componentusername()); myComponentItem->setSelectable(false); QString aIconName = C->component_icone(); if (!aIconName.isEmpty()) { - QString resDir = aResMgr->findFile(aIconName, C->componentname()) ; - if (resDir) { - resDir = QAD_Tools::addSlash(resDir); - QPixmap aIcone(resDir + aIconName); + QString resFilePath = aResMgr->path(aResMgr->resSection(), C->componentname(), aIconName) ; + if ( resFilePath ) { + QPixmap aIcone(resFilePath); QIconSet aIconSet(aIcone); myComponentItem->setPixmap(0, aIconSet.pixmap(QIconSet::Small, QIconSet::Normal)); } else { @@ -258,19 +317,39 @@ void SUPERVGUI_Service::initialise() { SALOME_ModuleCatalog::Service* Service = &(Interface->interfaceservicelist[k]); QListViewItem* myServiceItem = new QListViewItem(myInterfaceItem, (char*)Service->ServiceName); myServiceItem->setSelectable(true); - components->ensureItemVisible(myServiceItem); + //components->ensureItemVisible(myServiceItem); long nbPortsOut = Service->ServiceoutParameter.length(); for (int m=0; mServiceoutParameter[m]); - QListViewItem* myPortOutItem = new QListViewItem(myServiceItem, (char*)PortOut->Parametername, (char*)PortOut->Parametertype, "Out"); + QListViewItem* myPortOutItem = + new QListViewItem(myServiceItem, (char*)PortOut->Parametername, (char*)PortOut->Parametertype, "Out"); + myPortOutItem->setSelectable(false); + } + + long nbStreamPortsOut = Service->ServiceoutDataStreamParameter.length(); + for (int m=0; mServiceoutDataStreamParameter[m]); + QListViewItem* myPortOutItem = + new QListViewItem(myServiceItem, (char*)PortOut->Parametername, + getDataStreamParameterName(PortOut->Parametertype), "DataStream Out"); myPortOutItem->setSelectable(false); } long nbPortsIn = Service->ServiceinParameter.length(); for (int l=0; lServiceinParameter[l]); - QListViewItem* myPortInItem = new QListViewItem(myServiceItem, (char*)PortIn->Parametername, (char*)PortIn->Parametertype, "In"); + QListViewItem* myPortInItem = + new QListViewItem(myServiceItem, (char*)PortIn->Parametername, (char*)PortIn->Parametertype, "In"); + myPortInItem->setSelectable(false); + } + + long nbStreamPortsIn = Service->ServiceinDataStreamParameter.length(); + for (int l=0; lServiceinDataStreamParameter[l]); + QListViewItem* myPortInItem = + new QListViewItem(myServiceItem, (char*)PortIn->Parametername, + getDataStreamParameterName(PortIn->Parametertype), "DataStream In"); myPortInItem->setSelectable(false); } } @@ -282,18 +361,31 @@ void SUPERVGUI_Service::initialise() { SUPERVGUI_Service::~SUPERVGUI_Service() { Trace("SUPERVGUI_Service::~SUPERVGUI_Service") + if (myMFile) delete myMFile; } void SUPERVGUI_Service::addComputeNode() { - SUPERVGUI_Main* aMain = Supervision.getMain(); + SUIT_Desktop* aDesktop = SUIT_Session::session()->activeApplication()->desktop(); + CAM_Application* anApp = ( CAM_Application* )(SUIT_Session::session()->activeApplication()); + if ( !anApp ) return; + + SUPERVGUI* aSupMod = SUPERVGUI::Supervision(); + if ( !aSupMod ) { + MESSAGE("NULL Supervision module!"); + return; + } + + SUPERVGUI_Main* aMain = aSupMod->getMain(); if (aMain==0) { - QMessageBox::warning(QAD_Application::getDesktop(), tr("WARNING"), tr("MSG_NO_SUPERVISION_WINDOW")); + QMessageBox::warning(aDesktop, tr("WARNING"), tr("MSG_NO_SUPERVISION_WINDOW")); + } else if (!aMain->isEditable()) { + QMessageBox::warning(aDesktop, tr("ERROR"), tr("MSG_CANT_CREATE_NODE")); } else { CORBA::Object_ptr obj = naming->Resolve("/Kernel/ModulCatalog"); SALOME_ModuleCatalog::ModuleCatalog_var* aModuleCatalog = new SALOME_ModuleCatalog::ModuleCatalog_var; *aModuleCatalog = SALOME_ModuleCatalog::ModuleCatalog::_narrow(obj); if (CORBA::is_nil(*aModuleCatalog)) { - QMessageBox::warning(0, tr("ERROR"), tr("MSG_CANT_CHOOSE_SERVICE")); + QMessageBox::warning(aDesktop, tr("ERROR"), tr("MSG_CANT_CHOOSE_SERVICE")); } else { QListViewItem* item; bool b = false; @@ -304,42 +396,53 @@ void SUPERVGUI_Service::addComputeNode() { const char* service = item->text(0).latin1(); const char* interface = item->parent()->text(0).latin1(); const char* component = item->parent()->parent()->text(0).latin1(); - SALOME_ModuleCatalog::Acomponent_ptr myComponent = (*aModuleCatalog)->GetComponent(component); - if (myComponent==NULL) { - QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), tr("MSG_CANT_CHOOSE_SERVICE")); - } else { + SALOME_ModuleCatalog::Acomponent_ptr myComponent = (*aModuleCatalog)->GetComponent(anApp->moduleName(component)); + if ( myComponent == NULL ) { + QMessageBox::warning(aDesktop, tr("ERROR"), tr("MSG_CANT_CHOOSE_SERVICE")); + } + else { const SALOME_ModuleCatalog::Service* myService = myComponent->GetService(interface, service); - b = true; - - SUPERV_CNode node = aMain->getDataflow()->CNode(*myService); - if (CORBA::is_nil(node)) { - QMessageBox::warning(0, tr("ERROR"), tr("MSG_CANT_CREATE_NODE")); + SUPERV_CNode aNode = aMain->getDataflow()->CNode(*myService); + if ( CORBA::is_nil( aNode ) ) { + QMessageBox::warning(aDesktop, tr("ERROR"), tr("MSG_CANT_CREATE_NODE")); return; } - node->Coords(myX, myY); - myX += NODE_DX; - myY += NODE_DY; - aMain->addComputeNode(SUPERV::CNode::_narrow(node)); + + SUPERV::INode_var aDummyEndNode; + addNode( aNode, aDummyEndNode, myX, myY ); + b = true; // at least one node was added } } } - if (!b) { - QMessageBox::warning(QAD_Application::getDesktop(), tr("WARNING"), tr("MSG_NONODE_TOADD")); + if ( !b ) { + QMessageBox::warning(aDesktop, tr("WARNING"), tr("MSG_NONODE_TOADD")); } } } } void SUPERVGUI_Service::addFactoryNode() { - SUPERVGUI_Main* aMain = Supervision.getMain(); + SUIT_Desktop* aDesktop = SUIT_Session::session()->activeApplication()->desktop(); + CAM_Application* anApp = ( CAM_Application* )(SUIT_Session::session()->activeApplication()); + if ( !anApp ) return; + + SUPERVGUI* aSupMod = SUPERVGUI::Supervision(); + if ( !aSupMod ) { + MESSAGE("NULL Supervision module!"); + return; + } + + SUPERVGUI_Main* aMain = aSupMod->getMain(); if (aMain==0) { - QMessageBox::warning(QAD_Application::getDesktop(), tr("WARNING"), tr("MSG_NO_SUPERVISION_WINDOW")); + QMessageBox::warning(aDesktop, tr("WARNING"), tr("MSG_NO_SUPERVISION_WINDOW")); + } else if (!aMain->isEditable()) { + QMessageBox::warning(aDesktop, tr("ERROR"), tr("MSG_CANT_CREATE_NODE")); } else { CORBA::Object_ptr obj = naming->Resolve("/Kernel/ModulCatalog"); SALOME_ModuleCatalog::ModuleCatalog_var* aModuleCatalog = new SALOME_ModuleCatalog::ModuleCatalog_var; *aModuleCatalog = SALOME_ModuleCatalog::ModuleCatalog::_narrow(obj); if (CORBA::is_nil(*aModuleCatalog)) { - QMessageBox::warning(0, tr("ERROR"), tr("MSG_CANT_CHOOSE_SERVICE")); + QMessageBox::warning(aDesktop, tr("ERROR"), tr("MSG_CANT_CHOOSE_SERVICE")); } else { QListViewItem* item; bool b = false; @@ -349,28 +452,40 @@ void SUPERVGUI_Service::addFactoryNode() { if (item->isSelected()) { const char* service = item->text(0).latin1(); const char* interface = item->parent()->text(0).latin1(); - const char* component = item->parent()->parent()->text(0).latin1(); - SALOME_ModuleCatalog::Acomponent_ptr myComponent = (*aModuleCatalog)->GetComponent(component); - if (myComponent==NULL) { - QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), tr("MSG_CANT_CHOOSE_SERVICE")); - } else { - const SALOME_ModuleCatalog::Service* myService = myComponent->GetService(interface, service); - b = true; - - SUPERV_FNode node = aMain->getDataflow()->FNode(component, interface, *myService); - if (CORBA::is_nil(node)) { - QMessageBox::warning(0, tr("ERROR"), tr("MSG_CANT_CREATE_NODE")); - return; + //const char* component = anApp->moduleName(item->parent()->parent()->text(0).latin1()); + if ( aSupMod->getInterfaceNameMap().contains(item->parent()->text(0)) ) { + const char* component = aSupMod->getInterfaceNameMap().find(item->parent()->text(0)).data(); + + SALOME_ModuleCatalog::Acomponent_ptr myComponent = (*aModuleCatalog)->GetComponent(component); + if (myComponent==NULL) { + QMessageBox::warning(aDesktop, tr("ERROR"), tr("MSG_CANT_CHOOSE_SERVICE")); + } + else { + const SALOME_ModuleCatalog::Service* myService = myComponent->GetService(interface, service); + SUPERV_CNode aNode; + if ( myService->TypeOfNode == 0 ) { // ComputeNode + aNode = aMain->getDataflow()->CNode(*myService); + if (CORBA::is_nil( aNode ) ) { + QMessageBox::warning(aDesktop, tr("ERROR"), tr("MSG_CANT_CREATE_NODE")); + return; + } + } + else { // Factory Node + aNode = aMain->getDataflow()->FNode(component, interface, *myService); + if ( CORBA::is_nil( aNode ) ) { + QMessageBox::warning(aDesktop, tr("ERROR"), tr("MSG_CANT_CREATE_NODE")); + return; + } + } + SUPERV::INode_var aDummyEndNode; + addNode( aNode, aDummyEndNode, myX, myY ); + b = true; } - node->Coords(myX, myY); - myX += NODE_DX; - myY += NODE_DY; - aMain->addComputeNode(SUPERV::CNode::_narrow(node)); } } } - if (!b) { - QMessageBox::warning(QAD_Application::getDesktop(), tr("WARNING"), tr("MSG_NONODE_TOADD")); + if ( !b ) { + QMessageBox::warning(aDesktop, tr("WARNING"), tr("MSG_NONODE_TOADD")); } } } @@ -378,67 +493,73 @@ void SUPERVGUI_Service::addFactoryNode() { void SUPERVGUI_Service::addInlineNode() { - SUPERVGUI_Main* aMain = Supervision.getMain(); + SUPERVGUI* aSupMod = SUPERVGUI::Supervision(); + if ( !aSupMod ) { + MESSAGE("NULL Supervision module!"); + return; + } + + SUPERVGUI_Main* aMain = aSupMod->getMain(); if (aMain==0) { - QMessageBox::warning(QAD_Application::getDesktop(), tr("WARNING"), tr("MSG_NO_SUPERVISION_WINDOW")); - } else { + QMessageBox::warning(SUIT_Session::session()->activeApplication()->desktop(), tr("WARNING"), tr("MSG_NO_SUPERVISION_WINDOW")); + } + else if (!aMain->isEditable()) { + QMessageBox::warning(SUIT_Session::session()->activeApplication()->desktop(), tr("ERROR"), tr("MSG_CANT_CREATE_NODE")); + } + else { int aSel = myTypeCombo->currentItem(); switch (aSel) { case 0: // Computation - if (myScriptPane->isDefined()) { - SUPERV_INode aNode = aMain->getDataflow()->INode(myScriptPane->getFuncName().latin1(), - (myScriptPane->getFunction()).in()); + { + SUPERV_CNode aNode = + aMain->getDataflow()->INode(myScriptPane->getFuncName().isEmpty() ? "" : myScriptPane->getFuncName().latin1(), + (myScriptPane->getFunction()).in()); if (CORBA::is_nil(aNode)) { QMessageBox::warning(0, tr("ERROR"), tr("MSG_CANT_CREATE_NODE")); return; } - aNode->Coords(myX, myY); - myX += NODE_DX; - myY += NODE_DY; - aMain->addComputeNode(SUPERV::CNode::_narrow(aNode)); + SUPERV::INode_var aDummyEndNode; + addNode( aNode, aDummyEndNode, myX, myY ); } break; case 1: // Switch - if (myScriptPane->isDefined()) { + { SUPERV_INode aEndNode; - SUPERV_SNode aStartNode = aMain->getDataflow()->SNode(myScriptPane->getFuncName().latin1(), - (myScriptPane->getFunction()).in(), - aEndNode); + SUPERV_CNode aStartNode = + aMain->getDataflow()->SNode(myScriptPane->getFuncName().isEmpty() ? "" : myScriptPane->getFuncName().latin1(), + (myScriptPane->getFunction()).in(), + aEndNode); if (CORBA::is_nil(aStartNode) || CORBA::is_nil(aEndNode)) { QMessageBox::warning(0, tr("ERROR"), tr("MSG_CANT_CREATE_NODE")); return; } - aStartNode->Coords(myX, myY); - aEndNode->Coords(myX + LABEL_WIDTH*2, myY); - myX += NODE_DX; - myY += NODE_DY; - aMain->addControlNode(SUPERV::CNode::_narrow(aStartNode), SUPERV::CNode::_narrow(aEndNode), true); + addNode( aStartNode, aEndNode, myX, myY ); } break; case 2: // Loop { SUPERV_INode aEndNode; - SUPERV_LNode aStartNode = aMain->getDataflow()->LNode(myInitPane->getFuncName().latin1(), (myInitPane->getFunction()).in(), - myMorePane->getFuncName().latin1(), (myMorePane->getFunction()).in(), - myNextPane->getFuncName().latin1(), (myNextPane->getFunction()).in(), - aEndNode); + SUPERV_CNode aStartNode = + aMain->getDataflow()->LNode(myInitPane->getFuncName().isEmpty() ? "" : myInitPane->getFuncName().latin1(), + (myInitPane->getFunction()).in(), + myMorePane->getFuncName().isEmpty() ? "" : myMorePane->getFuncName().latin1(), + (myMorePane->getFunction()).in(), + myNextPane->getFuncName().isEmpty() ? "" : myNextPane->getFuncName().latin1(), + (myNextPane->getFunction()).in(), + aEndNode); if (CORBA::is_nil(aStartNode) || CORBA::is_nil(aEndNode)) { QMessageBox::warning(0, tr("ERROR"), tr("MSG_CANT_CREATE_NODE")); return; } - aStartNode->Coords(myX, myY); - aEndNode->Coords(myX + LABEL_WIDTH*2, myY); - myX += NODE_DX; - myY += NODE_DY; - aMain->addControlNode(SUPERV::CNode::_narrow(aStartNode), SUPERV::CNode::_narrow(aEndNode), true); + addNode( aStartNode, aEndNode, myX, myY ); } break; case 3: // GoTo { - SUPERV_GNode aGotoNode; + SUPERV_CNode aGotoNode; if (myScriptPane->isDefined()) aGotoNode = aMain->getDataflow()->GNode(myScriptPane->getFuncName().latin1(), (myScriptPane->getFunction()).in(), ""); @@ -448,17 +569,97 @@ void SUPERVGUI_Service::addInlineNode() { QMessageBox::warning(0, tr("ERROR"), tr("MSG_CANT_CREATE_NODE")); return; } - aGotoNode->Coords(myX, myY); - myX += NODE_DX; - myY += NODE_DY; - aMain->addGOTONode(SUPERV::GNode::_narrow(aGotoNode)); + SUPERV::INode_var aDummyEndNode; + addNode( aGotoNode, aDummyEndNode, myX, myY ); } break; } } } +void SUPERVGUI_Service::addMacroNode() { + SUPERVGUI* aSupMod = SUPERVGUI::Supervision(); + if ( !aSupMod ) { + MESSAGE("NULL Supervision module!"); + return; + } + + SUPERVGUI_Main* aMain = aSupMod->getMain(); + if (aMain==0) { + QMessageBox::warning(SUIT_Session::session()->activeApplication()->desktop(), tr("WARNING"), tr("MSG_NO_SUPERVISION_WINDOW")); + } + else if (!aMain->isEditable()) { + QMessageBox::warning(SUIT_Session::session()->activeApplication()->desktop(), tr("ERROR"), tr("MSG_CANT_CREATE_NODE")); + } + else { + if ( myMFile ) { + SUPERV_CNode aNode; + if (aMain->getDataflow()->IsStreamGraph()) { + SUPERV_StreamGraph aSGraph = aMain->getDataflow()->ToStreamGraph(); + if (!SUPERV_isNull(aSGraph)) + aNode = aSGraph->StreamMNode(myMFile->name().latin1()); + // TMP: while stream macro nodes doesn't impemented + if (CORBA::is_nil(aNode)) { + aNode = aSGraph->MNode(myMFile->name().latin1()); + } + } + else + aNode = aMain->getDataflow()->MNode(myMFile->name().latin1()); + if (CORBA::is_nil(aNode)) { + QMessageBox::warning(0, tr("ERROR"), tr("MSG_CANT_CREATE_NODE")); + return; + } + + SUPERV::INode_var aDummyEndNode; + addNode( aNode, aDummyEndNode, myX, myY ); + } + else { + QMessageBox::warning(SUIT_Session::session()->activeApplication()->desktop(), tr("WARNING"), tr("MSG_NONODE_TOADD")); + } + } +} + +void SUPERVGUI_Service::loadGraph() { + if ( getenv( "ENABLE_MACRO_NODE" ) == NULL ) + // error! if ENABLE_MACRO_NODE is set - we should NOT get here by any means.. + { + //MESSAGE("Error: ENABLE_MACRO_NODE is not set, but loadGraph() was called!"); + return; + } + + QString aFileName = SUIT_FileDlg::getFileName(SUIT_Session::session()->activeApplication()->desktop(), + "", + "*.xml", + tr("MSG_GRAPH_INSERT"), + true); + if (aFileName.isEmpty()) return; + + myMacroPane->clear(); + + myMFile = new QFile(aFileName); + if (!myMFile->open(IO_ReadOnly)) { + QMessageBox::warning(SUIT_Session::session()->activeApplication()->desktop(), tr("ERROR"), + tr("MSG_CANT_LOADSCRIPT")); + delete myMFile; myMFile = 0; + return; + } + + QTextStream* aStream = new QTextStream(myMFile); + if (aStream->atEnd()) { + QMessageBox::warning(SUIT_Session::session()->activeApplication()->desktop(), tr("ERROR"), + tr("MSG_EMTY_FILE")); + delete aStream; + myMFile->close(); + delete myMFile; myMFile = 0; + return; + } + // read graph info + // temporary display only file name + QFileInfo anInfo(*myMFile); + QListViewItem* anItem = new QListViewItem(myMacroPane, anInfo.baseName()); + anItem->setSelectable(true); +} void SUPERVGUI_Service::typeNodeSelected(int theRow) { if (theRow == 2) @@ -477,9 +678,16 @@ void SUPERVGUI_Service::choose() { void SUPERVGUI_Service::showEvent(QShowEvent* theEvent) { - SUPERVGUI_Main* aMain = Supervision.getMain(); + SUPERVGUI* aSupMod = SUPERVGUI::Supervision(); + if ( !aSupMod ) { + MESSAGE("NULL Supervision module!"); + return; + } + + SUPERVGUI_Main* aMain = aSupMod->getMain(); if (aMain && (!aMain->isArrayShown())) { - aMain->getGraph()->viewportToContents(0, 0, myX, myY); + aMain->getArrayView()->viewportToContents(0, 0, myX, myY); + //aMain->getGraph()->viewportToContents(0, 0, myX, myY); } QDialog::showEvent(theEvent); } @@ -494,173 +702,271 @@ void SUPERVGUI_Service::tabChanged(QWidget* theWidget) { //***************************************************** // Pane for Python script editing //***************************************************** -SUPERVGUI_PythonEditPane::SUPERVGUI_PythonEditPane(QWidget* theParent) - : QFrame(theParent), - myIStream(0) +SUPERVGUI_PythonEditPane::SUPERVGUI_PythonEditPane( QWidget* theParent, const bool isNodeCreation, int& theX, int& theY ) + : myIsWithLibrary( isNodeCreation ), + QFrame( theParent ), + myX( theX ), myY( theY ) { - QGridLayout* aEditLayout = new QGridLayout(this, 2, 4); + QGridLayout* aEditLayout = new QGridLayout( this, 2, 8, 0, 6 ); // First row + if ( myIsWithLibrary ) { + QPushButton* aLibBtn = new QPushButton(tr("BUT_LIBRARY"), this); + connect(aLibBtn, SIGNAL(clicked()), this, SLOT(library())); + aEditLayout->addMultiCellWidget( aLibBtn, 0, 0, 1, 2 ); + } + QPushButton* aLoadBtn = new QPushButton(tr("BUT_LOAD"), this); connect(aLoadBtn, SIGNAL(clicked()), this, SLOT(loadFile())); - aEditLayout->addWidget(aLoadBtn, 0, 2); + aEditLayout->addMultiCellWidget( aLoadBtn, 0, 0, 3, 4 ); - myNextBtn = new QPushButton(tr("BUT_NEXT"), this); - myNextBtn->setEnabled(false); - connect(myNextBtn, SIGNAL(clicked()), this, SLOT(readFunction())); + myFunctionsCombo = new QComboBox( this ); + connect( myFunctionsCombo, SIGNAL( activated( int ) ), this, SLOT( readFunction( int ) ) ); - aEditLayout->addWidget(myNextBtn, 0, 3); + aEditLayout->addMultiCellWidget( myFunctionsCombo, 0, 0, 5, 7 ); //Second row myText = new QTextEdit(this); - myText->setWordWrap(QTextEdit::FixedColumnWidth); - myText->setWrapColumnOrWidth(80); + myText->setTextFormat( Qt::PlainText ); // NOT rich text, so text() returns plain text + myText->setWordWrap( QTextEdit::FixedColumnWidth ); + myText->setWrapColumnOrWidth( 80 ); + connect( myText, SIGNAL( returnPressed() ), this, SLOT( autoIndentLine() ) ); - aEditLayout->addMultiCellWidget(myText, 1, 1, 0, 3); + aEditLayout->addMultiCellWidget( myText, 1, 1, 0, 7 ); + //aEditLayout->setColStretch( 3, 1 ); // to allow myFunctionsCombo be larger when needed +} + +/** + * Return a text between "def" and "(" + * "def" must begin with position 0, which means that only global function definitions are possible + */ +QString getFunctionName( const QString& aLine ) { + int aDefPos = aLine.find("def"); + if ( aDefPos == 0 ) { // only global function definitions! + int aStart = aLine.find(" ", aDefPos); + int aEnd = aLine.find("(", aStart); + QString aName = aLine.mid(aStart, (aEnd-aStart)); + return aName.stripWhiteSpace(); + } + return QString(); } +/** + * Searches for text beginning with "def" and ending with any meanful character at + * beginning of line. Starts searching with current position of given stream. + * Fills the myPyFunctions with strings corresponding to found fucntions. + */ +void SUPERVGUI_PythonEditPane::initPyFunctions( QTextStream& theStream ) { + + if ( theStream.atEnd() ) + return; + + QString aPyFunction; + QString aLine = theStream.readLine(); + + while ( !theStream.atEnd() ) { // not EOF + + // asv : 23.11.04 : fix for PAL6870 : skip empty lines in the beginning or between functions + // find("def)==0 -> analizing only global function definitions which start with 0 indentation + while ( !aLine.isNull() && aLine.find( "def" ) != 0 ) + aLine = theStream.readLine(); + + if ( !aLine.isNull() && aLine.find("def") == 0 ) { + myFunctionsCombo->insertItem( getFunctionName( aLine ) ); // aLine now == function name + + aPyFunction += aLine; + aPyFunction += '\n'; + + // read function body + aLine = theStream.readLine(); + // asv : 23.11.04 : added "|| aLine.isEmpty()" - fix for PAL6870. readLine() returns an empty + // string for "\n" string, it trails \n caracter. but we accept such lines.. + // asv : 22.12.04 : aLine[0].isSpace() || aLine[0]=='#' -> line must begin with space or tab + // (a normal code with indentation) or comment sign. + while ( !aLine.isNull() && ( aLine.isEmpty() || aLine[0].isSpace() || aLine[0] == '#' ) ) { + aPyFunction += aLine; + aPyFunction += '\n'; + aLine = theStream.readLine(); + } + + myPyFunctions << aPyFunction; + aPyFunction.setLength( 0 ); + } + } +} /** * Load existing Python script */ void SUPERVGUI_PythonEditPane::loadFile() { - QString aFileName = QAD_FileDlg::getFileName(QAD_Application::getDesktop(), - "", - "*.py", - tr("TIT_LOADSCRIPT"), - true); + QString aFileName = SUIT_FileDlg::getFileName(SUIT_Session::session()->activeApplication()->desktop(), + "", + "*.py", + tr("TIT_LOADSCRIPT"), + true); if (aFileName.isEmpty()) return; - myFile = new QFile(aFileName); - if (!myFile->open(IO_ReadOnly)) { - QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), + QFile aFile( aFileName ); + if (!aFile.open(IO_ReadOnly)) { + QMessageBox::warning(SUIT_Session::session()->activeApplication()->desktop(), tr("ERROR"), tr("MSG_CANT_LOADSCRIPT")); return; } - myIStream = new QTextStream(myFile); - if (myIStream->atEnd()) { - QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), - tr("MSG_EMTY_FILE")); - myNextBtn->setEnabled(false); - delete myIStream; - myIStream = 0; - myFile->close(); - delete myFile; + myPyFunctions.clear(); + myFunctionsCombo->clear(); + myText->clear(); + + QTextStream aFileReader(&aFile); + if ( aFileReader.atEnd() ) { + QMessageBox::warning(SUIT_Session::session()->activeApplication()->desktop(), tr("ERROR"), tr("MSG_EMTY_FILE")); + aFile.close(); return; } - myNextBtn->setEnabled(true); - readFunction(); + + initPyFunctions( aFileReader ); + + if ( myPyFunctions.size() ) + readFunction( 0 ); } - /** * Finds and Reads a function from current position in the opened file + * asv : Comment above is old! Present model: just take an already read string = PyFunction + * from the list which is filled in loadFile(). */ -void SUPERVGUI_PythonEditPane::readFunction() { - if (!myIStream) return; - - while (!myIStream->atEnd()) { - QString aLine = myIStream->readLine(); - if (aLine.isNull()) return; - - // find first function - int aDefPos = aLine.find("def"); - if (aDefPos == 0) { // only not a class members - myText->clear(); - // find name - /*int aStart = aLine.find(" ", aDefPos); - int aEnd = aLine.find("(", aStart); - QString aName = aLine.mid(aStart, (aEnd-aStart)); - aName = aName.stripWhiteSpace(); - myNameEdt->setText(aName);*/ - - // find input params - /*aStart = aEnd+1; - aEnd = aLine.find(")", aStart); - QString aParams = aLine.mid(aStart, (aEnd-aStart)); - aParams = aParams.stripWhiteSpace(); - myParamEdt->setText(aParams);*/ - - myText->append(aLine); - // read body - QString aBodyLine = myIStream->readLine(); - while ((!aBodyLine.isNull()) && aBodyLine[0].isSpace()) { - myText->append(aBodyLine); - aBodyLine = myIStream->readLine(); - } - return; - } - } - QMessageBox::warning(QAD_Application::getDesktop(), tr("WARNING"), - tr("MSG_NOMORE_FUNCTIONS")); - delete myIStream; - myIStream = 0; - myNextBtn->setEnabled(false); - myFile->close(); - delete myFile; +void SUPERVGUI_PythonEditPane::readFunction( int i ) { + myText->clear(); + if ( i != -1 && myPyFunctions.size() && myPyFunctions.size() > i ) + myText->append( myPyFunctions[ i ] ); + + // asv : 30.11.04 : 2.7 - Inline node function editor improvement + // 2.7.1 - set focus to editor widget on editor window opening + // 2.7.2 - scroll to the beginning of function on editor window opening + myText->setFocus(); + myText->ensureVisible( 0,0 ); } - +/** + * Returns the text after "def" and before "(" -- first defined function name + */ QString SUPERVGUI_PythonEditPane::getFuncName() { - QString aName(""); for (int i=0; i < myText->paragraphs(); i++) { - QString aLine = myText->text(i); - int aDefPos = aLine.find("def"); - if (aDefPos == 0) { - int aStart = aLine.find(" ", aDefPos); - int aEnd = aLine.find("(", aStart); - QString aName = aLine.mid(aStart, (aEnd-aStart)); - return aName.stripWhiteSpace(); - } + QString aName = getFunctionName( myText->text(i) ); + if ( !aName.isEmpty() ) + return aName; } - return aName; + return QString(); } - +/** + * Returns the contents of the myText widget without trailing spacing + */ SUPERV_Strings SUPERVGUI_PythonEditPane::getFunction() { SUPERV_Strings aStrings = new SUPERV::ListOfStrings(); aStrings->length(myText->paragraphs()); for (int i=0; i < myText->paragraphs(); i++) { - aStrings[i] = CORBA::string_dup(myText->text(i).latin1()); + QString aLine = myText->text(i); + // asv : 30.11.04 - why do we have to remove trailing spaces?? + // it's user's responsibility to enter correct Python code, we don't do anything with it. + // if (..) -- initial, while(..) -- my improvement, but also commented out -- needless. + //if (!aLine.right(1).compare(" ")) // replaced with the line below -- loop + //while (aLine.at(aLine.length()-1).isSpace()) // remove trailing spaces + // aLine = aLine.remove(aLine.length()-1,1); + aStrings[i] = CORBA::string_dup(aLine.latin1()); } return aStrings._retn(); } void SUPERVGUI_PythonEditPane::setFunction(SUPERV_Strings theStr) { - int aLen = theStr->length(); - for (int i=0; i < aLen; i++) + myText->clear(); + for ( int i=0, aLen = theStr->length(); i < aLen; i++ ) myText->append(QString(theStr[i])); + + // asv : 30.11.04 : 2.7 - Inline node function editor improvement + // 2.7.1 - set focus to editor widget on editor window opening + // 2.7.2 - scroll to the beginning of function on editor window opening + myText->setFocus(); + myText->ensureVisible( 0,0 ); } +/** + * Automatic indentation rule: if a previous line ended with + * ':', then add N additional spaces in the current line. If no ':' found, then + * the same amount of spaces as in the previous line is added. Connected to + * "returnPressed" signal of myText text edit. +*/ +void SUPERVGUI_PythonEditPane::autoIndentLine() { + const int N = 4; // width of indentation "tab" + if ( myText && myText->paragraphs() ) { + + // get current cursor position and previous line (the one to be analized) + int pos, para, i; + QString spacesStr; + myText->getCursorPosition( ¶, &pos ); // pos==0, beginning of line + if ( myText->paragraphLength(para-1) > 0 ) { // mkr : IPAL9817 + QString line = myText->text( para-1 ); // previous paragraph line + + // construct a string containing all leading space characters of previous line (tabs, etc.) + i = -1; + while ( line[++i].isSpace() ) // append all isSpace() characters at beginning of line to spacesStr + spacesStr += line[i]; + + // if ':' was found -- add more spaces to spacesStr + line = line.stripWhiteSpace(); + if ( line[ line.length()-1 ] == ':' ) { + i = 0; + while ( i++ < N ) + spacesStr += ' '; + } + } + // ok, append spacesStr at the beginning of the current line = make indentation + myText->insertAt( spacesStr, para, pos ); + myText->setCursorPosition( para, pos+spacesStr.length() ); + } +} + +/** + * Create a node by loading it from an external XML library file + * This slot opens a dialog box which then "lives" by itself.. + */ +void SUPERVGUI_PythonEditPane::library() { + // if CanImport() returns false, it displays an error message box, so there is no need to + // display such message here ("library file not found", etc.). + if ( SUPERVGUI_Library::getLibrary()->CanImport() ) { + SUPERVGUI_LibDlg* aDlg = new SUPERVGUI_LibDlg( this, myX, myY ); + aDlg->exec(); + } +} /*! * Edit Python dialog */ -SUPERVGUI_EditPythonDlg::SUPERVGUI_EditPythonDlg(bool isLoop) - :QDialog(QAD_Application::getDesktop(), 0, true, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu) +SUPERVGUI_EditPythonDlg::SUPERVGUI_EditPythonDlg( bool isLoop ) + :QDialog(SUIT_Session::session()->activeApplication()->desktop(), 0, true, WStyle_Customize | WStyle_NormalBorder | WStyle_Title | WStyle_SysMenu) { setSizeGripEnabled( true ); setCaption(tr("TIT_FUNC_PYTHON")); resize( 500, 250 ); QVBoxLayout* aMainLayout = new QVBoxLayout(this, 7, 4); + int a,b; // dummies for PythonEditPane, not used, since library = false and myX, myY are not used in PythonEditPane if (isLoop) { QTabWidget* aLoopTabPane = new QTabWidget(this); - myInitPane = new SUPERVGUI_PythonEditPane(this); + myInitPane = new SUPERVGUI_PythonEditPane( this, false, a, b ); // library == false, since no creation of a node is needed here aLoopTabPane->addTab(myInitPane, "Init"); - myMorePane = new SUPERVGUI_PythonEditPane(this); + myMorePane = new SUPERVGUI_PythonEditPane( this, false, a, b ); aLoopTabPane->addTab(myMorePane, "More"); - myNextPane = new SUPERVGUI_PythonEditPane(this); + myNextPane = new SUPERVGUI_PythonEditPane( this, false, a, b ); aLoopTabPane->addTab(myNextPane, "Next"); aMainLayout->addWidget(aLoopTabPane); } else { - myEditPane = new SUPERVGUI_PythonEditPane(this); + myEditPane = new SUPERVGUI_PythonEditPane( this, false, a, b ); aMainLayout->addWidget(myEditPane); } QGroupBox* aBtnBox = new QGroupBox( this ); @@ -671,7 +977,7 @@ SUPERVGUI_EditPythonDlg::SUPERVGUI_EditPythonDlg(bool isLoop) aBtnLayout->setSpacing( 6 ); aBtnLayout->setMargin( 11 ); QPushButton* aOKBtn = new QPushButton( tr( "BUT_OK" ), aBtnBox ); - connect( aOKBtn, SIGNAL( clicked() ), this, SLOT( accept() ) ); + connect( aOKBtn, SIGNAL( clicked() ), this, SLOT( clickOnOk() ) ); aBtnLayout->addWidget( aOKBtn ); aBtnLayout->addStretch(); @@ -682,3 +988,61 @@ SUPERVGUI_EditPythonDlg::SUPERVGUI_EditPythonDlg(bool isLoop) aMainLayout->addWidget(aBtnBox); } + +// mkr : IPAL9817 : to avoid a SIGSEGV when INode_Impl::SetPyFunction(...) +// will call with null python function name +void SUPERVGUI_EditPythonDlg::clickOnOk() +{ + if ( getFuncName().isEmpty() ) + QMessageBox::warning( SUIT_Session::session()->activeApplication()->desktop(), tr( "ERROR" ), tr( "MSG_INCORRECT_INDENT" ) ); + else + accept(); +} + +/** + * Do the following actions for newly created Engine's CNode: + * 1. Create a presentation for it (CanvasNode) + * 2. Place the CanvasNode to the current top-left corner or the current viewport + * 3. Increment the coordinates of the next CanvasNode (new nodes are "cascaded" when several of them are created at once) + * PS theEndNode is passed only for Loop and Switch nodes (EndLoop and EndSwitch) + */ +void SUPERVGUI_Service::addNode( SUPERV::CNode_var theNode, SUPERV::INode_var theEndNode, int& theX, int& theY ) { + SUPERVGUI* aSupMod = SUPERVGUI::Supervision(); + if ( !aSupMod ) { + MESSAGE("NULL Supervision module!"); + return; + } + + SUPERVGUI_Main* aMain = aSupMod->getMain(); + + if ( !CORBA::is_nil( theNode ) && aMain ) { + + aMain->Editing(); // PAL6170: GUI->Engine: setting "Editing" flag, why here? -> PAL7960 + + int cx, cy; //to appear a new node in the top-left corner of the current viewport + + //2.8 point of improvements: Adding node to graph window with taking into account zoom factor + QWMatrix aWM = aMain->getCanvasView()->worldMatrix(); + aMain->getCanvasView()->viewportToContents(theX, theY, cx, cy); + + //2.8 point of improvements: + cx = (int)((double)cx/aWM.m11()); + cy = (int)((double)cy/aWM.m22()); + theNode->Coords(cx, cy); + if ( !CORBA::is_nil( theEndNode ) ) + theEndNode->Coords(cx + LABEL_WIDTH*2, cy); + theX += (int)(NODE_DX*aWM.m11()); + theY += (int)(NODE_DY*aWM.m22()); + + if ( theNode->IsGOTO() ) + aMain->addGOTONode( theNode ); + else if ( theNode->IsMacro() ) + aMain->addMacroNode( theNode ); + else if ( theNode->IsLoop() || theNode->IsSwitch() ) + aMain->addControlNode( theNode, SUPERV::CNode::_narrow( theEndNode ), true ); + else + aMain->addComputeNode( theNode ); + aSupMod->nullifyInitialVF(); + } +} +