Salome HOME
31f8af1efb9af7fc75568d4e3ee884e2841a3aa8
[modules/yacs.git] / src / pyqt / gui / Items.py
1 # Copyright (C) 2006-2023  CEA/DEN, EDF R&D
2 #
3 # This library is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU Lesser General Public
5 # License as published by the Free Software Foundation; either
6 # version 2.1 of the License, or (at your option) any later version.
7 #
8 # This library is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 # Lesser General Public License for more details.
12 #
13 # You should have received a copy of the GNU Lesser General Public
14 # License along with this library; if not, write to the Free Software
15 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 #
17 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 #
19
20 import sys
21 import pilot
22 import SALOMERuntime
23 from . import Item
24 from . import adapt
25 from qt import *
26 from qtcanvas import *
27 from . import Editor
28 from . import CItems
29 import pygraphviz
30 import traceback
31 from . import CONNECTOR
32 from . import graph
33 from . import panels
34
35 class DataLinkItem(Item.Item):
36   def __init__(self,pin,pout):
37     Item.Item.__init__(self)
38     self.pin=pin
39     self.pout=pout
40     self.label= pout.getNode().getName()+":"+pout.getName()+"->"+pin.getNode().getName()+":"+pin.getName()
41
42   def getIconName(self):
43     return "datalink.png"
44
45 class StreamLinkItem(Item.Item):
46   def __init__(self,pin,pout):
47     Item.Item.__init__(self)
48     self.pin=pin
49     self.pout=pout
50     self.label= pout.getNode().getName()+":"+pout.getName()+"->"+pin.getNode().getName()+":"+pin.getName()
51
52   def getIconName(self):
53     return "streamlink.png"
54
55 class ControlLinkItem(Item.Item):
56   def __init__(self,nodeup,nodedown):
57     Item.Item.__init__(self)
58     self.nodedown=nodedown
59     self.nodeup=nodeup
60     self.label= nodeup.getName()+"->"+nodedown.getName()
61
62   def getIconName(self):
63     return "controllink.png"
64
65 class ControlLinksItem(Item.Item):
66   """Item for all control links of a composed node"""
67   def __init__(self,item):
68     Item.Item.__init__(self)
69     self.item=item
70     self.label="Control Links"
71
72   def getIconName(self):
73     return "folder"
74   def isExpandable(self):
75     return True
76
77   def getChildren(self):
78     sublist=[]
79     for n in self.item.node.edGetDirectDescendants():
80       for p in n.getOutNodes():
81         sublist.append(ControlLinkItem(n,p))
82     return sublist
83
84   def addLink(self,link):
85     CONNECTOR.Emit(self,"add",link)
86
87 class DataLinksItem(Item.Item):
88   """Item for all data links of a composed node"""
89   def __init__(self,item):
90     Item.Item.__init__(self)
91     self.item=item
92     self.label="Data Links"
93
94   def getIconName(self):
95     return "folder"
96   def isExpandable(self):
97     return True
98
99   def getChildren(self):
100     sublist=[]
101     for pout,pin in self.item.node.getSetOfInternalLinks():
102       if pout.getNode().getFather() != self.item.node and pin.getNode().getFather() != self.item.node:
103         continue
104       if isinstance(pin,pilot_InputDataStreamPort):
105         sublist.append(StreamLinkItem(pin,pout))
106       else:
107         sublist.append(DataLinkItem(pin,pout))
108     #for pout,pin in self.item.node.getSetOfLinksLeavingCurrentScope():
109     #  sublist.append(DataLinkItem(pin,pout))
110     #for pin,pout in self.item.node.getSetOfLinksComingInCurrentScope():
111     #  sublist.append(DataLinkItem(pin,pout))
112     return sublist
113
114   def addLink(self,link):
115     CONNECTOR.Emit(self,"add",link)
116
117 class ItemComposedNode(Item.Item):
118   """Item pour les noeuds composes"""
119   n=0
120   def __init__(self,node):
121     #node is an instance of YACS::ENGINE::ComposedNode
122     Item.Item.__init__(self)
123     self.node=node
124     self.graph=None
125     self.label=node.getName()
126     self.datalinks=DataLinksItem(self)
127     self.controllinks=ControlLinksItem(self)
128
129   def isExpandable(self):
130     return True
131
132   def getChildren(self):
133     #liste des noeuds fils
134     liste=self.node.edGetDirectDescendants()
135     #On les adapte en item avant de les retourner
136     sublist=[]
137     for n in liste:
138       try:
139         sublist.append(Item.adapt(n))
140       except:
141         #print n
142         #traceback.print_exc()
143         raise
144     sublist.append(self.datalinks)
145     sublist.append(self.controllinks)
146     return sublist
147
148   def dblselected(self):
149     #print "ItemComposedNode dblselected"
150     root=self.node.getRootNode()
151     rootItem=Item.adapt(root)
152     if not self.emitting:
153       self.emitting=1
154       CONNECTOR.Emit(rootItem,"dblselected",self)
155       self.emitting=0
156
157   def selected(self):
158     #print "ItemComposedNode selected"
159     root=self.node.getRootNode()
160     rootItem=Item.adapt(root)
161     if not self.emitting:
162       self.emitting=1
163       CONNECTOR.Emit(rootItem,"selected",self)
164       self.emitting=0
165
166   def getIconName(self):
167     return "green-los"
168
169   def panel(self,parent):
170     """Retourne un tab widget pour browser/editer la proc"""
171     tabWidget = QTabWidget( parent )
172     for name,method in self.panels:
173       tabWidget.addTab( method(self,tabWidget), name )
174     return tabWidget
175
176   def addNode(self,service):
177     print("Composed.addNode",service)
178     #add node service in the parent self which is a ComposedNode
179     new_node=service.clone(None)
180     ItemComposedNode.n=ItemComposedNode.n+1
181     name=service.getName()+"_%d" % ItemComposedNode.n
182     new_node.setName(name)
183     self.node.edAddChild(new_node)
184     item=Item.adapt(new_node)
185     CONNECTOR.Emit(self,"add",item)
186
187   def panel1(self,parent):
188     qvbox=QVBox(parent)
189     self.graph=graph.Graph(self,qvbox)
190     return qvbox
191
192   def layout(self,rankdir):
193     if self.graph:
194       self.graph.layout(rankdir)
195
196   panels=[("Panel1",panel1)]
197
198   def addLink(self,link):
199     print("Composed.addLink",link)
200     if isinstance(link,DataLinkItem):
201       self.datalinks.addLink(link)
202     elif isinstance(link,StreamLinkItem):
203       self.datalinks.addLink(link)
204     else:
205       self.controllinks.addLink(link)
206
207
208 class ItemForLoop(ItemComposedNode):
209   def box(self,parent):
210     return panels.PanelForLoop(parent,self)
211
212   def addNode(self,service):
213     new_node=service.clone(None)
214     ItemComposedNode.n=ItemComposedNode.n+1
215     name=service.getName()+"_%d" % ItemComposedNode.n
216     new_node.setName(name)
217     #replace the old node (if it exists) with the new one
218     nodes=self.node.edGetDirectDescendants()
219     if nodes:
220       old_item=Item.adapt(nodes[0])
221       CONNECTOR.Emit(old_item,"remove")
222     self.node.edSetNode(new_node)
223     item=Item.adapt(new_node)
224     CONNECTOR.Emit(self,"add",item)
225     CONNECTOR.Emit(self,"changed")
226
227 class ItemWhile(ItemForLoop):
228   pass
229
230 class ItemForEach(ItemForLoop):
231   pass
232
233 class ItemSwitch(ItemComposedNode):
234   def addNode(self,service):
235     return
236
237 class ItemProc(ItemComposedNode):
238   """Item pour la procedure"""
239   def connecting(self,item):
240     print("ItemProc.connecting",item)
241     self._connecting=item
242
243 class ItemPort(Item.Item):
244   """Item pour les ports """
245   panels=[]
246   def __init__(self,port,root=None):
247     Item.Item.__init__(self)
248     self.port=port
249     self.label=port.getName()
250     if root:
251       self.root=root
252     elif self.port.getNode().getFather():
253       root=self.port.getNode().getRootNode()
254       self.root=Item.adapt(root)
255     else:
256       self.root=None
257
258   def selected(self):
259     #print "ItemPort selected"
260     if not self.root:
261       return
262     if not self.emitting:
263       self.emitting=1
264       CONNECTOR.Emit(self.root,"selected",self)
265       self.emitting=0
266
267   def getIconName(self):
268     return "port.png"
269
270   def panel(self,parent):
271     """Retourne un tab widget pour browser/editer l'item"""
272     tabWidget = QTabWidget( parent )
273     for name,method in self.panels:
274       tabWidget.addTab( method(self,tabWidget), name )
275     return tabWidget
276   box=panel
277
278   def link(self,other):
279     print("ItemPort.link:",self,other)
280
281   def connect(self):
282     print("ItemPort.connect:")
283     self.root.connecting(self)
284
285 class ItemInPort(ItemPort):
286   def getIconName(self):
287     return "inport.png"
288
289   def panel1(self,parent):
290     return panels.PanelInPort(parent,self)
291
292   panels=[("Panel1",panel1)]
293
294 class ItemOutPort(ItemPort):
295   def getIconName(self):
296     return "outport.png"
297
298   def panel1(self,parent):
299     return panels.PanelOutPort(parent,self)
300
301   panels=[("Panel1",panel1)]
302
303   def link(self,other):
304     nodeS=self.port.getNode()
305     nodeE=other.port.getNode()
306     father=nodeS.getFather()
307     if father != nodeE.getFather():
308       #not same father : do nothing for the moment
309       return
310     try:
311       #cflink=nodeS.getOutGate().isAlreadyInSet(nodeE.getInGate())
312       cflink= nodeE.getInGate() in nodeS.getOutGate().edSetInGate()
313       father.edAddDFLink(self.port,other.port)
314       l=DataLinkItem(other.port,self.port)
315       fitem=Item.adapt(father)
316       fitem.addLink(l)
317       if not cflink:
318         #add also a control flow link
319         fitem.addLink(ControlLinkItem(nodeS,nodeE))
320     except ValueError as ex:
321       traceback.print_exc()
322       QMessageBox.warning(None,"YACS error",str(ex))
323       return
324
325 class ItemInStream(ItemPort):
326   def getIconName(self):
327     return "instream.png"
328
329 class ItemOutStream(ItemPort):
330   def getIconName(self):
331     return "outstream.png"
332
333   def link(self,other):
334     father=self.port.getNode().getFather()
335     if father != other.port.getNode().getFather():
336       #not same father : not for the moment
337       return
338     try:
339       father.edAddLink(self.port,other.port)
340       l=StreamLinkItem(other.port,self.port)
341       fitem=Item.adapt(father)
342       fitem.addLink(l)
343     except ValueError as ex:
344       traceback.print_exc()
345       QMessageBox.warning(None,"YACS error",str(ex))
346       return
347
348 class ItemInGate(ItemPort):
349   """Item for InGate"""
350   def __init__(self,port):
351     Item.Item.__init__(self)
352     self.port=port
353 class ItemOutGate(ItemPort):
354   """Item for OutGate"""
355   def __init__(self,port):
356     Item.Item.__init__(self)
357     self.port=port
358
359 class ItemNode(Item.Item):
360   """Item pour les noeuds elementaires
361      Il n a pas de fils
362   """
363   #attr donnant la liste des panels du noeud (nom,method)
364   panels=[]
365   def __init__(self,node):
366     Item.Item.__init__(self)
367     self.node=node
368     self.label=node.getName()
369     self.father=Item.adapt(node.getFather())
370
371   def selected(self):
372     #print "ItemNode selected"
373     root=self.node.getRootNode()
374     rootItem=Item.adapt(root)
375     if not self.emitting:
376       self.emitting=1
377       #for those that have subscribed to item level
378       CONNECTOR.Emit(self,"selected",self)
379       #for those that have subscribed to rootItem level
380       CONNECTOR.Emit(rootItem,"selected",self)
381       self.emitting=0
382
383   def isExpandable(self):
384     return True
385
386   def getChildren(self):
387     sublist=[]
388     for n in self.node.getSetOfInputPort():
389       sublist.append(Item.adapt(n))
390     for n in self.node.getSetOfOutputPort():
391       sublist.append(Item.adapt(n))
392     for n in self.node.getSetOfInputDataStreamPort():
393       sublist.append(Item.adapt(n))
394     for n in self.node.getSetOfOutputDataStreamPort():
395       sublist.append(Item.adapt(n))
396     return sublist
397
398   def panel(self,parent):
399     """Retourne un tab widget pour browser/editer l'item"""
400     tabWidget = QTabWidget( parent )
401     for name,method in self.panels:
402       tabWidget.addTab( method(self,tabWidget), name )
403     return tabWidget
404   box=panel
405
406 class ItemScriptNode(ItemNode):
407
408   def panel1(self,parent):
409     return panels.PanelScript(parent,self)
410
411   panels=[("Panel1",panel1)]
412
413   def getIconName(self):
414     return "green-ball"
415
416 class ItemFuncNode(ItemNode):
417   def panel1(self,parent):
418     return panels.PanelFunc(parent,self)
419
420   panels=[("Panel1",panel1)]
421
422   def getIconName(self):
423     return "green-ball"
424
425   def FuncChanged(self, newText ):
426     self.myFunc=str(newText)
427
428 class ItemService(ItemNode):
429   def panel1(self,parent):
430     """Retourne un widget pour browser/editer l'item"""
431     self.myName=self.node.getName()
432
433     qvbox=QVBox(parent)
434     qvbox.layout().setAlignment(Qt.AlignTop|Qt.AlignLeft)
435     qvbox.setSpacing( 5 )
436
437     row0=QHBox(qvbox)
438     label=QLabel("Name: ",row0)
439     self.lined0 = QLineEdit(self.node.getName(),row0)
440     qvbox.connect( self.lined0, SIGNAL("textChanged(const QString &)"), self.NameChanged )
441     qvbox.connect( self.lined0, SIGNAL("returnPressed()"), self.NameReturn )
442     QToolTip.add( self.lined0, "Node name" )
443
444     row1=QHBox(qvbox)
445     label1=QLabel("Ref: ",row1)
446     self.lined1 = QLineEdit(row1)
447     if self.node.getComponent():
448       self.lined1.setText(self.node.getComponent().getName())
449     else:
450       self.lined1.setText("NO_COMPONENT_NAME")
451
452     row2=QHBox(qvbox)
453     label2=QLabel("Method: ",row2)
454     self.lined2 = QLineEdit(row2)
455     self.lined2.setText(self.node.getMethod())
456
457     row3=QHBox(qvbox)
458     but1=QPushButton( "Save", row3 )
459     but2=QPushButton( "Cancel", row3 )
460     qvbox.connect( but1, SIGNAL("clicked()"), self.handleSave )
461     qvbox.connect( but2, SIGNAL("clicked()"), self.handleCancel )
462
463     return qvbox
464
465   panels=[("Panel1",panel1)]
466
467   def NameChanged(self, newText ):
468     self.myName=str(newText)
469
470   def NameReturn(self):
471     pass
472
473   def getIconName(self):
474     return "green-square"
475
476   def handleSave(self):
477     self.node.setRef(str(self.lined1.text()))
478     self.node.setMethod(str(self.lined2.text()))
479   def handleCancel(self):
480     self.lined0.setText(self.node.getName())
481     self.lined1.setText(self.node.getComponent().getName())
482     self.lined2.setText(self.node.getMethod())
483
484 def adapt_Proc_to_Item(obj, protocol, alternate):
485   return ItemProc(obj)
486
487 def adapt_Node_to_Item(obj, protocol, alternate):
488   return ItemNode(obj)
489
490 def adapt_ComposedNode_to_Item(obj, protocol, alternate):
491   return ItemComposedNode(obj)
492
493 def adapt_ForLoop_to_Item(obj, protocol, alternate):
494   return ItemForLoop(obj)
495
496 def adapt_Switch_to_Item(obj, protocol, alternate):
497   return ItemSwitch(obj)
498
499 def adapt_While_to_Item(obj, protocol, alternate):
500   return ItemWhile(obj)
501
502 def adapt_ForEach_to_Item(obj, protocol, alternate):
503   return ItemForEach(obj)
504
505 def adapt_InlineFuncNode_to_Item(obj, protocol, alternate):
506   return ItemFuncNode(obj)
507
508 def adapt_InlineScriptNode_to_Item(obj, protocol, alternate):
509   return ItemScriptNode(obj)
510
511 def adapt_ServiceNode_to_Item(obj, protocol, alternate):
512   return ItemService(obj)
513
514 def adapt_Port_to_Item(obj, protocol, alternate):
515   return ItemPort(obj)
516
517 def adapt_InPort_to_Item(obj, protocol, alternate):
518   return ItemInPort(obj)
519
520 def adapt_OutPort_to_Item(obj, protocol, alternate):
521   return ItemOutPort(obj)
522
523 def adapt_InStream_to_Item(obj, protocol, alternate):
524   return ItemInStream(obj)
525
526 def adapt_OutStream_to_Item(obj, protocol, alternate):
527   return ItemOutStream(obj)
528
529 def adapt_InGate_to_Item(obj, protocol, alternate):
530   return ItemInGate(obj)
531
532 def adapt_OutGate_to_Item(obj, protocol, alternate):
533   return ItemOutGate(obj)
534
535 if hasattr(pilot,"ProcPtr"):
536   #SWIG 1.3.24
537   adapt.registerAdapterFactory(pilot.ProcPtr, Item.Item, adapt_Proc_to_Item)
538   adapt.registerAdapterFactory(pilot.BlocPtr, Item.Item, adapt_ComposedNode_to_Item)
539   adapt.registerAdapterFactory(pilot.ForLoopPtr, Item.Item, adapt_ComposedNode_to_Item)
540   adapt.registerAdapterFactory(pilot.WhileLoopPtr, Item.Item, adapt_ComposedNode_to_Item)
541   adapt.registerAdapterFactory(pilot.ForEachLoopPtr, Item.Item, adapt_ComposedNode_to_Item)
542   adapt.registerAdapterFactory(pilot.SwitchPtr, Item.Item, adapt_ComposedNode_to_Item)
543   adapt.registerAdapterFactory(pilot.ComposedNodePtr, Item.Item, adapt_ComposedNode_to_Item)
544
545   adapt.registerAdapterFactory(pilot.ServiceNodePtr, Item.Item, adapt_ServiceNode_to_Item)
546   #adapt.registerAdapterFactory(pilot.ServiceNodeNodePtr, Item.Item, adapt_Node_to_Item)
547   adapt.registerAdapterFactory(pilot.InlineNodePtr, Item.Item, adapt_InlineScriptNode_to_Item)
548   adapt.registerAdapterFactory(pilot.InlineFuncNodePtr, Item.Item, adapt_InlineFuncNode_to_Item)
549   adapt.registerAdapterFactory(pilot.NodePtr, Item.Item, adapt_Node_to_Item)
550
551   adapt.registerAdapterFactory(pilot.OutputPortPtr, Item.Item, adapt_OutPort_to_Item)
552   adapt.registerAdapterFactory(pilot.InputPortPtr, Item.Item, adapt_InPort_to_Item)
553   adapt.registerAdapterFactory(pilot.OutputDataStreamPortPtr, Item.Item, adapt_OutStream_to_Item)
554   adapt.registerAdapterFactory(pilot.InputDataStreamPortPtr, Item.Item, adapt_InStream_to_Item)
555
556   pilot_InputDataStreamPort=pilot.InputDataStreamPortPtr
557
558 else:
559   #SWIG 1.3.29
560   adapt.registerAdapterFactory(pilot.Proc, Item.Item, adapt_Proc_to_Item)
561   adapt.registerAdapterFactory(SALOMERuntime.SalomeProc, Item.Item, adapt_Proc_to_Item)
562   adapt.registerAdapterFactory(pilot.Bloc, Item.Item, adapt_ComposedNode_to_Item)
563   adapt.registerAdapterFactory(pilot.ForLoop, Item.Item, adapt_ForLoop_to_Item)
564
565   adapt.registerAdapterFactory(pilot.WhileLoop, Item.Item, adapt_While_to_Item)
566   adapt.registerAdapterFactory(pilot.ForEachLoop, Item.Item, adapt_ForEach_to_Item)
567   adapt.registerAdapterFactory(pilot.Switch, Item.Item, adapt_Switch_to_Item)
568   adapt.registerAdapterFactory(pilot.ComposedNode, Item.Item, adapt_ComposedNode_to_Item)
569
570   adapt.registerAdapterFactory(pilot.ServiceNode, Item.Item, adapt_ServiceNode_to_Item)
571   adapt.registerAdapterFactory(SALOMERuntime.CORBANode, Item.Item, adapt_ServiceNode_to_Item)
572   adapt.registerAdapterFactory(SALOMERuntime.SalomeNode, Item.Item, adapt_ServiceNode_to_Item)
573   #adapt.registerAdapterFactory(pilot.ServiceNodeNode, Item.Item, adapt_Node_to_Item)
574   adapt.registerAdapterFactory(pilot.InlineNode, Item.Item, adapt_InlineScriptNode_to_Item)
575   adapt.registerAdapterFactory(SALOMERuntime.PythonNode, Item.Item, adapt_InlineScriptNode_to_Item)
576   adapt.registerAdapterFactory(pilot.InlineFuncNode, Item.Item, adapt_InlineFuncNode_to_Item)
577   adapt.registerAdapterFactory(SALOMERuntime.PyFuncNode, Item.Item, adapt_InlineFuncNode_to_Item)
578   adapt.registerAdapterFactory(pilot.Node, Item.Item, adapt_Node_to_Item)
579
580   adapt.registerAdapterFactory(pilot.OutputPort, Item.Item, adapt_OutPort_to_Item)
581   adapt.registerAdapterFactory(SALOMERuntime.OutputPyPort, Item.Item, adapt_OutPort_to_Item)
582   adapt.registerAdapterFactory(SALOMERuntime.OutputCorbaPort, Item.Item, adapt_OutPort_to_Item)
583   adapt.registerAdapterFactory(pilot.InputPort, Item.Item, adapt_InPort_to_Item)
584   adapt.registerAdapterFactory(SALOMERuntime.InputPyPort, Item.Item, adapt_InPort_to_Item)
585   adapt.registerAdapterFactory(SALOMERuntime.InputCorbaPort, Item.Item, adapt_InPort_to_Item)
586   adapt.registerAdapterFactory(pilot.OutputDataStreamPort, Item.Item, adapt_OutStream_to_Item)
587   adapt.registerAdapterFactory(pilot.InputDataStreamPort, Item.Item, adapt_InStream_to_Item)
588   adapt.registerAdapterFactory(pilot.OutGate, Item.Item, adapt_OutGate_to_Item)
589   adapt.registerAdapterFactory(pilot.InGate, Item.Item, adapt_InGate_to_Item)
590
591   pilot_InputDataStreamPort=pilot.InputDataStreamPort