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_Clipboard.cxx
25 // Author : Alexander SLADKOV
29 #include "SUPERVGUI_Clipboard.h"
30 #include "SUPERVGUI_CanvasNode.h"
31 #include "SUPERVGUI.h"
34 SUPERVGUI_Clipboard* SUPERVGUI_Clipboard::myCB = 0;
38 * Compute the next valid name for a Python function (add "_N" if a function with given name already exists)
40 QString getNewName( QStringList& allNames, const QString& oldName ) {
42 int id = 1; //increment index
43 newName = oldName + QString("_") + QString::number( id );
44 while ( allNames.contains( newName ) )
45 newName = oldName + QString("_") + QString::number( ++id );
51 * Replaces "def*origName*" string with "def*newName*" string
53 bool replaceName( SUPERV::ListOfStrings_var& theFunc, const QString& origName, const QString& newName ) {
54 // asv : 30.12.04 : it's a mistake to replace all function_name-s in all function_strings.
55 // must be only in "def XXX():", with "do-while" I want to skip all empty and comment lines..
56 int i( 0 ), index( -1 );
58 QString aLine( theFunc[i] );
59 index = aLine.find(origName);
60 if ( index >= 0 && aLine.startsWith( "def" ) ) { // looking for "def*origName*"
61 theFunc[i] = aLine.replace( index, origName.length(), newName ).latin1();
66 while ( i < theFunc->length() );
71 * "Copies" all ports from fromNode to toNode: creates the sames ports in toNode in fact
73 void copyPorts( const SUPERV::CNode_var& fromNode, const SUPERV::INode_var& toNode ) {
74 if ( CORBA::is_nil( fromNode ) || CORBA::is_nil( toNode ) )
76 SUPERV::ListOfPorts_var aPList = fromNode->Ports();
78 for (int i = 0; i < aPList->length(); i++) {
79 aName = aPList[i].in()->Name();
80 aType = aPList[i].in()->Type();
81 if ( aPList[i].in()->IsInput() )
82 toNode->InPort( aName.latin1(), aType.latin1() );
84 toNode->OutPort( aName.latin1(), aType.latin1() );
89 * Called on Paste Node command. Inserts a new node to the dataflow equal to the copied node.
90 * For InLine nodes the Python function name is changed ("_N" added).
92 void SUPERVGUI_Clipboard::pasteNode() {
93 Trace("SUPERVGUI_Main::pasteNode");
94 SUPERV::CNode_var aNode = getCopyNode();
95 if ( !CORBA::is_nil( aNode ) ) {
97 //collect all python functions names of allready exist InLine nodes
98 //in QStringList for automatic change of function's name on Paste of InLine node
99 QStringList aFuncNames;
100 SUPERV::Graph_var dataflow = Supervision.getMain()->getDataflow();
101 SUPERV::ListOfNodes_var nodes = dataflow->Nodes();
103 for(int i = 0; i < nodes->INodes.length(); i++)
104 aFuncNames.append(nodes->INodes[i]->PyFuncName());
106 for(int i = 0; i < nodes->LNodes.length(); i++) {
107 aFuncNames.append(nodes->LNodes[i]->PyInitName());
108 aFuncNames.append(nodes->LNodes[i]->PyMoreName());
109 aFuncNames.append(nodes->LNodes[i]->PyNextName());
112 for(int i = 0; i < nodes->SNodes.length(); i++)
113 aFuncNames.append(nodes->SNodes[i]->PyFuncName());
115 for(int i = 0; i < nodes->GNodes.length(); i++)
116 aFuncNames.append(nodes->GNodes[i]->PyFuncName());
119 QString aOriginalName;
121 // automatic change of function_name and function_strings ( +"_N" )
122 QString aFName, aInitFName, aMoreFName, aNextFName;
123 SUPERV::ListOfStrings_var aFunc, aInitFunc, aMoreFunc, aNextFunc;
125 const int aKind = aNode->Kind();
127 if ( aKind == SUPERV::InLineNode || aKind == SUPERV::GOTONode || aKind == SUPERV::SwitchNode ) {
128 // "fix" Main function_name and Main function_strings
129 aOriginalName = SUPERV::INode::_narrow(aNode)->PyFuncName();
130 if ( !aOriginalName.isEmpty() ) {
131 aFName = getNewName( aFuncNames, aOriginalName );
132 aFunc = SUPERV::INode::_narrow(aNode)->PyFunction();
133 replaceName( aFunc, aOriginalName, aFName );
136 else if (aNode->Kind() == SUPERV::LoopNode) {
138 // "fix" Init function_name and Init function_strings
139 aOriginalName = SUPERV::LNode::_narrow(aNode)->PyInitName();
140 if (!aOriginalName.isEmpty()) {
141 aInitFName = getNewName( aFuncNames, aOriginalName );
142 aInitFunc = SUPERV::LNode::_narrow(aNode)->PyInit();
143 replaceName( aInitFunc, aOriginalName, aInitFName );
146 // "fix" More function_name and More function_strings
147 aOriginalName = SUPERV::LNode::_narrow(aNode)->PyMoreName();
148 if (!aOriginalName.isEmpty()) {
149 aMoreFName = getNewName( aFuncNames, aOriginalName );
150 aMoreFunc = SUPERV::LNode::_narrow(aNode)->PyMore();
151 replaceName( aMoreFunc, aOriginalName, aMoreFName );
154 // "fix" Next function_name and Next function_strings
155 aOriginalName = SUPERV::LNode::_narrow(aNode)->PyNextName();
156 if (!aOriginalName.isEmpty()) {
157 aNextFName = getNewName( aFuncNames, aOriginalName );
158 aNextFunc = SUPERV::LNode::_narrow(aNode)->PyNext();
159 replaceName( aNextFunc, aOriginalName, aNextFName );
164 //2.8 point of improvements: Adding node to graph window with taking into account zoom factor
165 SUPERVGUI_CanvasView* aCanvasView = Supervision.getMain()->getCanvasView();
166 QWMatrix aWM = aCanvasView->worldMatrix();
167 switch (aNode->Kind()) {
168 case SUPERV::FactoryNode :
170 SUPERV::FNode_var aFNode = dataflow->FNode( SUPERV::FNode::_narrow(aNode)->GetComponentName(),
171 SUPERV::FNode::_narrow(aNode)->GetInterfaceName(),
172 *SUPERV::FNode::_narrow(aNode)->Service() );
173 if (CORBA::is_nil(aFNode)) {
174 QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), tr("MSG_CANT_CREATE_NODE"));
178 SUPERV::INode_var aDummyEndNode;
179 Supervision.getBrowser()->addNode(SUPERV::CNode::_narrow(aFNode), aDummyEndNode, myXCopyNode, myYCopyNode);
182 case SUPERV::ComputingNode :
184 SUPERV::CNode_var aCNode = dataflow->CNode(*SUPERV::CNode::_narrow(aNode)->Service());
185 if (CORBA::is_nil(aCNode)) {
186 QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), tr("MSG_CANT_CREATE_NODE"));
190 SUPERV::INode_var aDummyEndNode;
191 Supervision.getBrowser()->addNode(aCNode, aDummyEndNode, myXCopyNode, myYCopyNode);
194 case SUPERV::InLineNode :
196 SUPERV::INode_var aINode = dataflow->INode( aFName, aFunc );
198 if (CORBA::is_nil(aINode)) {
199 QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), tr("MSG_CANT_CREATE_NODE"));
202 copyPorts( aNode, aINode );
204 SUPERV::INode_var aDummyEndNode;
205 Supervision.getBrowser()->addNode(SUPERV::CNode::_narrow(aINode), aDummyEndNode, myXCopyNode, myYCopyNode);
208 case SUPERV::LoopNode :
210 SUPERV::INode_var aEndNode;
211 SUPERV::LNode_var aStartNode = dataflow->LNode(aInitFName, aInitFunc, aMoreFName, aMoreFunc, aNextFName, aNextFunc, aEndNode);
212 if (CORBA::is_nil(aStartNode) || CORBA::is_nil(aEndNode)) {
213 QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), tr("MSG_CANT_CREATE_NODE"));
216 copyPorts( aNode, SUPERV::INode::_narrow( aStartNode ) );
218 Supervision.getBrowser()->addNode(SUPERV::CNode::_narrow(aStartNode), aEndNode, myXCopyNode, myYCopyNode);
221 case SUPERV::SwitchNode :
223 SUPERV::INode_var aEndNode;
224 SUPERV::SNode_var aStartNode = dataflow->SNode(aFName, aFunc, aEndNode);
225 if (CORBA::is_nil(aStartNode) || CORBA::is_nil(aEndNode)) {
226 QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), tr("MSG_CANT_CREATE_NODE"));
229 copyPorts( aNode, SUPERV::INode::_narrow( aStartNode ) );
230 SUPERV::INode_var aNodeEnd = SUPERV::SNode::_narrow(aNode)->Coupled();
231 copyPorts( SUPERV::CNode::_narrow( aNodeEnd ), aEndNode );
233 Supervision.getBrowser()->addNode(SUPERV::CNode::_narrow(aStartNode), aEndNode, myXCopyNode, myYCopyNode);
236 case SUPERV::GOTONode :
238 SUPERV::GNode_var aGNode = dataflow->GNode(aFName, aFunc, "");
239 if (CORBA::is_nil(aGNode)) {
240 QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), tr("MSG_CANT_CREATE_NODE"));
243 copyPorts( aNode, SUPERV::INode::_narrow( aGNode ) );
245 SUPERV::INode_var aDummyEndNode;
246 Supervision.getBrowser()->addNode(SUPERV::CNode::_narrow(aGNode), aDummyEndNode, myXCopyNode, myYCopyNode);
249 case SUPERV::MacroNode :
251 /* to implement in the future */
253 //get SubGraph from MacroNode
254 SUPERV::Graph_var aMacro = SUPERV::Graph::_narrow(aNode);
255 SUPERV::Graph_var aGraph;
256 if (aMacro->IsStreamMacro())
257 aGraph = aMacro->StreamObjRef();
259 aGraph = aMacro->FlowObjRef();
260 SUPERV::Graph_var aMacroNode = dataflow->GraphMNode(aGraph);
262 if (CORBA::is_nil(aMacroNode)) {
263 QMessageBox::warning(QAD_Application::getDesktop(), tr("ERROR"), tr("MSG_CANT_CREATE_NODE"));
267 SUPERV::INode_var aDummyEndNode;
268 Supervision.getBrowser()->addNode(SUPERV::CNode::_narrow(aMacroNode), aDummyEndNode, myXCopyNode, myYCopyNode);
278 * Called from CanvasNode on "Paste port" command of popup menu
280 void SUPERVGUI_Clipboard::pastePort( SUPERVGUI_CanvasNode* node )
282 SUPERV::Port_var aPort = getCopyPort();
283 if ( !CORBA::is_nil(aPort) ) {
284 SUPERV::INode_var aNode = node->getInlineNode();
285 if (!CORBA::is_nil(aNode)) {
286 QString aName = aPort->Name();
287 QString aType = aPort->Type();
288 SUPERV::Port_var aPastePort;
289 if (aPort->IsInput()) {
290 //check if port with such name is alredy exists
291 QStringList aNames = node->getPortsNamesIN(aNode, true);
292 if (aNames.contains(aName))
293 QMessageBox::warning( QAD_Application::getDesktop(), tr("ERROR"), tr("MSG_PORT_EXIST") );
295 aPastePort = aNode->InPort(aName.latin1(), aType.latin1());
298 //check if port with such name is already exists
299 QStringList aNames = node->getPortsNamesIN(aNode, false);
300 if (aNames.contains(aName))
301 QMessageBox::warning( QAD_Application::getDesktop(), tr("ERROR"), tr("MSG_PORT_EXIST") );
303 aPastePort = aNode->OutPort(aName.latin1(), aType.latin1());
305 if ( !CORBA::is_nil(aPastePort) )
306 node->createPort( aPastePort.in() );