root/ossiedev/trunk/tools/alf/connectTool.py @ 9590

Revision 9590, 24.8 KB (checked in by cdietric, 4 years ago)

fixed path in connectTool.py

Line 
1## Copyright 2005, 2006, 2007, 2008 Virginia Polytechnic Institute and State University
2##
3## This file is part of the OSSIE ALF Waveform Application Visualization Environment
4##
5## ALF is free software; you can redistribute it and/or modify
6## it under the terms of the GNU General Public License as published by
7## the Free Software Foundation; either version 2 of the License, or
8## (at your option) any later version.
9##
10## ALF is distributed in the hope that it will be useful, but WITHOUT ANY
11## WARRANTY; without even the implied warranty of
12## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13## GNU General Public License for more details.
14##
15## You should have received a copy of the GNU General Public License
16## along with OSSIE Waveform Developer; if not, write to the Free Software
17## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
19import wx
20
21import re
22import sys       # for system commands (e.g., argv and argc stuff)
23import CosNaming   # narrowing naming context stuff
24import random   # for generating random connection id
25
26try:   #mac / older OSSIE versions
27    import standardInterfaces__POA
28    import CF, CF__POA    # core framework stuff
29except ImportError:   #0.6.2
30    import ossie.standardinterfaces.standardInterfaces__POA as standardInterfaces__POA
31    import ossie.cf.CF as CF
32    import ossie.cf.CF__POA as CF__POA   
33
34from wx.lib.anchors import LayoutAnchors  # used by splitter window
35
36import loadAutomationFile
37import importWaveform
38
39def create(parent):
40    ''' returns a wx frame representing the connect tool'''
41    win = MainFrame(parent, -1)
42    win.CenterOnParent()
43    return win
44
45
46
47def errorMsg(self,msg):
48    ''' Brings up a wx error message that says msg (first argument)'''
49    dlg = wx.MessageDialog(self,msg,'Error', wx.OK | wx.ICON_INFORMATION)
50    try:
51        dlg.ShowModal()
52    finally:
53        dlg.Destroy()
54    return
55
56
57
58class MainFrame(wx.Frame):
59    ''' The main window where all of the connect tool's wx stuff resides'''
60
61    def __init__(self, parent, id):
62        self.alfFrameRef = parent
63
64        self._init_ctrls(self.alfFrameRef)   # initialize the wx stuff
65       
66        if __name__ != '__main__':      # this statement allows me to run the tool
67                                        # as a standalone without OSSIE to do
68                                        # design work
69         self.refreshDisplay()
70
71        # This argument sets a default value for the automations file
72        #self.automationFileEditor.write('/sdr/automation_files/AM_FM_router.xml')
73        self.automationFileEditor.write('automationFileExamples')
74
75        self.parent = parent
76
77        if False:       
78         # Now Create the menu bar and items
79         self.mainmenu = wx.MenuBar()
80
81         menu = wx.Menu()
82         menu.Append(205, 'E&xit', 'Enough of this already!')
83         self.Bind(wx.EVT_MENU, self.OnFileExit, id=205)
84         self.mainmenu.Append(menu, '&File')
85       
86         menu = wx.Menu()
87         menu.Append(300, '&About', 'About this thing...')
88         self.Bind(wx.EVT_MENU, self.OnHelpAbout, id=300)
89         self.mainmenu.Append(menu, '&Help')
90
91         self.SetMenuBar(self.mainmenu)
92
93         # Bind the close event so we can disconnect the ports
94         self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
95
96        self.Show(True)
97       
98    def _init_ctrls(self, prnt):
99        ''' Initialize the wx controls'''
100
101        frame_size = wx.Size(770, 350)
102
103        wx.Frame.__init__(self, id=-1, name='', parent=prnt,
104                          pos=wx.Point(10, 20), size=frame_size,
105                          style=wx.DEFAULT_FRAME_STYLE,
106                          title='Connection Tool')
107
108
109        panel = wx.Panel(self, -1)
110
111
112        # --------------------------------------------------------------------
113        # create the top sizer
114
115
116        # Static Texts (labels)
117        self.blankLabel  = wx.StaticText(id=-1, label='',
118                                        name='blankLabel', parent=panel,
119                                        size=wx.Size(150, 30), style=0)
120        #self.blankLabel2  = wx.StaticText(id=-1, label='',
121        #                                name='blankLabel2', parent=panel,
122        #                                size=wx.Size(150, 30),
123        #                                style=wx.ALIGN_RIGHT)
124        self.appLabel  = wx.StaticText(id=-1, label='Application: ',
125                                        name='appLabel', parent=panel,
126                                        size=wx.Size(150, 30),
127                                        style=wx.ALIGN_RIGHT)
128        self.compLabel = wx.StaticText(id=-1, label='Component: ',
129                                        name='compLabel', parent=panel,
130                                        size=wx.Size(150, 30),
131                                        style=wx.ALIGN_RIGHT)
132        self.portLabel = wx.StaticText(id=-1, label='Port:',
133                                        name='portLabel', parent=panel,
134                                        size=wx.Size(150, 30),
135                                        style=wx.ALIGN_RIGHT)
136        self.usesLabel = wx.StaticText(id=-1, label='Uses Port:',
137                                        name='usesLabel', parent=panel,
138                                        size=wx.Size(250, 30),
139                                        style=wx.ALIGN_CENTER)
140        self.providesLabel = wx.StaticText(id=-1, label='Provides Port:',
141                                        name='providesLabel', parent=panel,
142                                        size=wx.Size(250, 30),
143                                        style = wx.ALIGN_CENTER)
144       
145        # wx choices
146        # application choices
147        self.uAppChoice = wx.Choice(choices=[' '], id=-1,
148                                    name=u'uAppChoice',
149                                    parent=panel,
150                                    size=wx.Size(250, 30), style=0)
151        self.uAppChoice.Bind(wx.EVT_CHOICE, self.OnUAppSelection, id =-1)
152
153        self.pAppChoice = wx.Choice(choices=[' '], id=-1,
154                                    name=u'pAppChoice',
155                                    parent=panel,
156                                    size=wx.Size(250, 30), style=0)
157        self.pAppChoice.Bind(wx.EVT_CHOICE, self.OnPAppSelection, id =-1)
158
159        # component choices
160        self.uCompChoice = wx.Choice(choices=[' '], id=-1,
161                                    name=u'uCompChoice',
162                                    parent=panel,
163                                    size=wx.Size(250, 30), style=0)
164        self.uCompChoice.Bind(wx.EVT_CHOICE, self.OnUCompSelection, id =-1)
165        self.pCompChoice = wx.Choice(choices=[' '], id=-1,
166                                    name=u'pCompChoice',
167                                    parent=panel,
168                                    size=wx.Size(250, 30), style=0)
169        self.pCompChoice.Bind(wx.EVT_CHOICE, self.OnPCompSelection, id =-1)
170
171
172        # port choices
173        self.uPortChoice = wx.Choice(choices=[' '], id=-1,
174                                    name=u'uPortChoice',
175                                    parent=panel,
176                                    size=wx.Size(250, 30), style=0)
177        self.pPortChoice = wx.Choice(choices=[' '], id=-1,
178                                    name=u'pPortChoice',
179                                    parent=panel,
180                                    size=wx.Size(250, 30), style=0)
181
182        # connect button
183        self.ConnectBtn = wx.Button(id = -1, label='Connect',
184                                    parent=panel)
185        self.ConnectBtn.Bind(wx.EVT_BUTTON, self.OnConnectBtn, id=-1)
186        blankLabel3 = wx.StaticText(label = '', parent = panel)
187        blankLabel4 = wx.StaticText(label = '', parent = panel)
188
189
190        flexSizer1 = wx.FlexGridSizer(cols=3, hgap=6, vgap = 6)
191        flexSizer1.AddMany([self.blankLabel, self.usesLabel, self.providesLabel,
192                  self.appLabel, self.uAppChoice, self.pAppChoice,
193                  self.compLabel, self.uCompChoice, self.pCompChoice,
194                  self.portLabel, self.uPortChoice, self.pPortChoice,
195                  blankLabel3, self.ConnectBtn, blankLabel4])
196        # --------------------------------------------------------------------
197
198       
199        # --------------------------------------------------------------------
200        # second sizer
201        vSizer1 = wx.BoxSizer(wx.VERTICAL)
202        self.connectionsLabel = wx.StaticText(parent = panel,
203                                            label = "Connections:")
204        self.connectionsListBox = wx.ListBox(parent=panel,
205                                            size=wx.Size(700,150),
206                                            style=wx.LB_MULTIPLE,
207                                            )
208        self.DisconnectBtn = wx.Button(parent=panel,
209                                            label='Disconnect')
210        self.DisconnectBtn.Bind(wx.EVT_BUTTON, self.OnDisconnectBtn)
211        vSizer1.Add(self.connectionsLabel, 0, wx.ALL, 5)
212        vSizer1.Add(self.connectionsListBox, 0, wx.ALL, 5)
213        vSizer1.Add(self.DisconnectBtn, 0, wx.ALL, 5)
214        # --------------------------------------------------------------------
215
216
217        # --------------------------------------------------------------------
218        # third sizer
219        hSizer1 = wx.BoxSizer(wx.HORIZONTAL)
220        self.automationFileEditor = wx.TextCtrl(id=-1,
221                                        name=u'automationFileEditor',
222                                        parent=panel,
223                                        size=wx.Size(350, 30),
224                                        style=0, value=u'')
225        self.browseAutomationBtn = wx.Button(id = -1,
226                                           label='Browse',
227                                    parent=panel,
228                                    size=wx.Size(80, 30))
229        self.browseAutomationBtn.Bind(wx.EVT_BUTTON,
230                                    self.onBrowseAutomationButton,
231                                    id=-1)
232        self.loadAutomationBtn = wx.Button(id = -1,
233                                           label='Load Automation File',
234                                    parent=panel,
235                                    size=wx.Size(180, 30))
236        self.loadAutomationBtn.Bind(wx.EVT_BUTTON,
237                                    self.onLoadAutomationFileButton,
238                                    id=-1)
239        hSizer1.Add(self.automationFileEditor, 0, wx.ALL, 5)
240        hSizer1.Add(self.browseAutomationBtn, 0, wx.ALL, 5)
241        hSizer1.Add(self.loadAutomationBtn, 0, wx.ALL, 5)
242        # --------------------------------------------------------------------
243
244
245
246        # --------------------------------------------------------------------
247        # assemble main sizer from other sizers
248
249        # topLabel = wx.StaticText(label = 'Connect Tool.  OSSIE 0.6.2',
250        #                         parent = panel)
251
252        mainSizer = wx.BoxSizer(wx.VERTICAL)
253        # mainSizer.Add(topLabel, 0 , wx.ALL, 5)
254        # mainSizer.Add(wx.StaticLine(panel), 0 , wx.EXPAND|wx.TOP|wx.BOTTOM, 5)
255
256        mainSizer.Add(flexSizer1, 0 , wx.EXPAND|wx.ALL, 10)
257        mainSizer.Add(wx.StaticLine(panel), 0 , wx.EXPAND|wx.TOP|wx.BOTTOM, 5)
258        mainSizer.Add(vSizer1, 0, wx.EXPAND|wx.ALL, 10)
259        mainSizer.Add(wx.StaticLine(panel), 0 , wx.EXPAND|wx.TOP|wx.BOTTOM, 5)
260        mainSizer.Add(hSizer1, 0, wx.EXPAND|wx.ALL, 10)
261
262        panel.SetSizer(mainSizer)
263        mainSizer.Fit(self)
264        # --------------------------------------------------------------------
265       
266
267    def refreshDisplay(self):
268        self.getAvailableConnections()
269        self.setAvailableApplications()
270        self.connectionsListBox.SetItems([x['display'] for x in self.alfFrameRef.connections[self.alfFrameRef.namingservice[0]]])
271
272
273    def getAvailableConnections(self):
274        ''' Get a list of objects I can potentially connect to'''
275
276        # Initialize my dictionary
277        self.avail_connects = {}
278
279        dom_obj = self.alfFrameRef.rootContext.resolve(
280                           [CosNaming.NameComponent("DomainName1","")])
281        dom_context = dom_obj._narrow(CosNaming.NamingContext)
282        if dom_context is None:
283            return
284
285        # get a list of applications running in the domain
286        appSeq =  self.alfFrameRef.domMgr._get_applications()
287        apps = {}
288        for app in appSeq:
289            sadfile = app._get_profile()
290            sadfile = sadfile.replace('//','')
291# NOTE:  Use CF::FileManager to obtain location
292            sadpath = '/sdr/dom/' + sadfile
293
294            waveform = importWaveform.getWaveform(sadpath, self.alfFrameRef, self.alfFrameRef.Available_Ints)
295            for comp in waveform.components:
296                for port in comp.ports:
297                    if apps.has_key(waveform.name):
298                        if apps[waveform.name].has_key(comp.name):
299                            apps[waveform.name][comp.name][port.name] = port.type
300                        else:
301                            apps[waveform.name][comp.name] = {port.name: port.type}
302                    else:
303                        apps[waveform.name] = {comp.name: {port.name: port.type}}
304
305        p = re.compile("^(OSSIE::.+)_\d+$")
306        members = dom_context.list(1000)
307        for m in members[0]:
308            wav_name = str(m.binding_name[0].id)
309
310            wav_obj = dom_context.resolve(
311                                [CosNaming.NameComponent(wav_name,"")])
312            wav_context = wav_obj._narrow(CosNaming.NamingContext)
313            if wav_context is None:
314                continue
315
316            m = p.match(wav_name)
317            if m:
318                if apps[m.group(1)]:
319                    self.avail_connects[wav_name] = apps[m.group(1)]
320                else:
321                    print "Could not find associated application for: " + wav_name
322                    continue
323
324    def setAvailableApplications(self):
325        ''' Assumes that I have a list of available applications.  Sets the
326            application wx.choice to list "choose waveform" followed by
327            a list of the available applications'''
328
329        # Set the application selection to an instruction:
330        self.uAppChoice.Clear(); self.uAppChoice.Append("(Choose Application)")
331        self.pAppChoice.Clear(); self.pAppChoice.Append("(Choose Application)")
332         
333        # add all of the available waveforms to my wx.choice
334        for w in self.avail_connects.keys():
335            self.uAppChoice.Append(w)
336            self.pAppChoice.Append(w)
337
338        # Set the choice to display 0th choice "(Choose Application)"
339        self.uAppChoice.SetSelection(0)
340        self.pAppChoice.SetSelection(0)
341
342        self.uCompChoice.Clear();
343        self.pCompChoice.Clear();
344        self.uPortChoice.Clear();
345        self.pPortChoice.Clear();
346         
347
348    def OnPAppSelection(self, event):
349        ''' Should occur when the user has selected a provides application.
350            Adds a list of the available components in the selected application
351            to the wx.choice for provides components.'''
352
353        choice = str(self.pAppChoice.GetStringSelection())
354        self.pCompChoice.Clear()
355        self.pPortChoice.Clear()
356        if choice != '(Choose Application)':
357            self.pCompChoice.Append('(Choose Component)')
358            for c in self.avail_connects[choice].keys():
359                self.pCompChoice.Append(c)
360            self.pCompChoice.SetSelection(0)
361
362        event.Skip()
363   
364    def OnUAppSelection(self,event):
365        ''' Should occur when the user has selected a uses application.
366            Adds a list of the available components in the selected application
367            to the wx.choice for uses components.'''
368
369        choice = str(self.uAppChoice.GetStringSelection())
370        self.uCompChoice.Clear()
371        self.uPortChoice.Clear()
372        if choice != '(Choose Application)':
373            self.uCompChoice.Append('(Choose Component)')
374            for c in self.avail_connects[choice].keys():
375                self.uCompChoice.Append(c)
376            self.uCompChoice.SetSelection(0)
377
378        event.Skip()
379
380    def OnPCompSelection(self, event):
381        ''' Should occur when the user has selected a provides component.
382            Adds a list of the available ports in the selected proviedes
383            component to the wx.choice for provides ports.'''
384
385        app_choice = str(self.pAppChoice.GetStringSelection())
386        comp_choice = str(self.pCompChoice.GetStringSelection())
387        self.pPortChoice.Clear()
388        if comp_choice != '(Choose Component)':
389            self.pPortChoice.Append('(Choose Port)')
390            for p,type in self.avail_connects[app_choice][comp_choice].iteritems():
391                if type == "Provides":
392                    self.pPortChoice.Append(p)
393            self.pPortChoice.SetSelection(0)
394
395        event.Skip()
396
397    def OnUCompSelection(self, event):
398        ''' Should occur when the user has selected a uses component.
399            Adds a list of the usesavailable ports in the selected
400            component to the wx.choice for uses ports.'''
401
402        app_choice = str(self.uAppChoice.GetStringSelection())
403        comp_choice = str(self.uCompChoice.GetStringSelection())
404        self.uPortChoice.Clear()
405        if comp_choice != '(Choose Component)':
406            self.uPortChoice.Append('(Choose Port)')
407            for p,type in self.avail_connects[app_choice][comp_choice].iteritems():
408                if type == "Uses":
409                    self.uPortChoice.Append(p)
410            self.uPortChoice.SetSelection(0)
411
412        event.Skip()
413
414    def OnConnectBtn(self,event):
415        ''' This is what happens when you press the connect button.
416            Retrieves the selected apps, components, and ports.
417            Then calls connect method.'''
418
419        uPortName = str(self.uPortChoice.GetStringSelection())
420        pPortName = str(self.pPortChoice.GetStringSelection())
421        uAppInstName = str(self.uAppChoice.GetStringSelection())
422        pAppInstName = str(self.pAppChoice.GetStringSelection())
423        uCompInstName = str(self.uCompChoice.GetStringSelection())
424        pCompInstName = str(self.pCompChoice.GetStringSelection())
425
426        if not uPortName or not pPortName:
427            dial = wx.MessageDialog(self, 'Please select both a uses port and provides port to make a connection.', 'Ports Not Selected', wx.OK)
428            dial.ShowModal()
429        else:
430           self.Connect( uAppInstName, uCompInstName, uPortName,
431                          pAppInstName, pCompInstName, pPortName)
432   
433        event.Skip()
434
435
436    def Connect(self, uAppInstName, uCompInstName, uPortName,
437                      pAppInstName, pCompInstName, pPortName):
438 
439        rootContext = self.GetParent().rootContext
440        if rootContext is None:
441            print "Failed to narrow the root naming context"
442            sys.exit(1)
443
444        # get a reference to the provides port:
445        # don't forget OSSIE:: in waveform name
446        pname = [CosNaming.NameComponent('DomainName1',''),
447                 CosNaming.NameComponent(pAppInstName,''),
448                 CosNaming.NameComponent(pCompInstName,'')]
449       
450        try:
451            pResourceRef = rootContext.resolve(pname)
452        except:
453            print "provides resource not found"
454            sys.exit(1)
455     
456        pResourceHandle = pResourceRef._narrow(CF.Resource)
457        pPortReference = pResourceHandle.getPort(pPortName)
458       
459
460        # get a reference to the uses port:
461        # don't forget OSSIE:: in waveform name
462        uname = [CosNaming.NameComponent('DomainName1',''),
463                 CosNaming.NameComponent(uAppInstName,''),
464                 CosNaming.NameComponent(uCompInstName,'')]
465        try:
466            uResourceRef = rootContext.resolve(uname)
467     
468        except:
469            print "uses resource not found"
470            sys.exit(1)
471     
472        uResourceHandle = uResourceRef._narrow(CF.Resource)
473
474        # get a reference to the uses port
475        uPortReference = uResourceHandle.getPort(uPortName)
476        if uPortReference is None:
477            print "Failed to get Port reference"
478            return
479        uPortHandle = uPortReference._narrow(CF.Port)
480         
481
482        # connect to the Uses port by passing a ref to my provides port
483        # make up some arbitrary connectionid that will be used for
484        # disconnectPort later
485        try:
486            connection_id = str(random.randint(100000,999999)) + "_" + uPortName
487            uPortHandle.connectPort(pPortReference, connection_id)
488           
489            connection_display = uAppInstName + ":" + uCompInstName + ":" + uPortName + "-->" + pAppInstName + ":" + pCompInstName + ":" + pPortName
490            connection = {
491                    'name': uname,
492                    'port': uPortName,
493                    'id': connection_id,
494                    'appNames': [uAppInstName, pAppInstName],
495                    'display': connection_display,
496                }
497            self.alfFrameRef.connections[self.alfFrameRef.namingservice[0]].append(connection)
498            self.connectionsListBox.Append(connection['display'])
499        except e:
500            print e
501            dial = wx.MessageDialog(self, 'Connection failed.', 'Failed', wx.OK)
502            dial.ShowModal()
503
504    def OnDisconnectBtn(self,event):
505        for x in reversed(self.connectionsListBox.GetSelections()):
506            connection = self.alfFrameRef.connections[self.alfFrameRef.namingservice[0]][x]
507            try:
508                rootContext = self.GetParent().rootContext
509                resourceRef = rootContext.resolve(connection['name'])
510                resourceHandle = resourceRef._narrow(CF.Resource)
511                portReference = resourceHandle.getPort(connection['port'])
512                if portReference is None:
513                    print "Failed to get port reference for disconnect."
514                    return
515                portHandle = portReference._narrow(CF.Port)
516                portHandle.disconnectPort(connection['id'])
517                del self.alfFrameRef.connections[self.alfFrameRef.namingservice[0]][x]
518                self.connectionsListBox.Delete(x)
519            except e:
520                print e
521                dial = wx.MessageDialog(self, 'Disconnect failed.', 'Failed', wx.OK)
522                dial.ShowModal()
523
524    def onBrowseAutomationButton(self,event):
525        ''' This is what happens when the Browse button is pressed.
526            Will load a file dialog and allow the user to browse for an
527            automation file.'''
528        dlg = wx.FileDialog(self, "Choose automation file", "", "", "XML Files (*.xml)|*.xml|All Files|*", wx.FD_OPEN)
529        if dlg.ShowModal() == wx.ID_OK:
530            filename = dlg.GetFilename()
531            directory = dlg.GetDirectory()
532            self.automationFileEditor.Clear()
533            self.automationFileEditor.write(directory + filename)
534        dlg.Destroy()
535
536    def onLoadAutomationFileButton(self,event):
537        ''' This is what happens when the Load Automation File button is pressed.
538            Will get the filename from the GUI and then start up the loadAutomationFile
539            modue '''
540
541        # get the name of the file
542        automations_file = self.automationFileEditor.GetLineText(0)
543        self.automation = loadAutomationFile.automation(self, automations_file)
544        event.Skip()
545
546    def pushPacket(self, I , Q):
547        ''' Other ports in the Domain can call push packet on me.  I will forward the
548            packet to the instance of loadAutomationFile'''
549        self.automation.pushPacket(I,Q)
550
551
552    def pushPacketMetaData(self, I, Q, metadata):
553        ''' Other ports in the Domain can call push packet on me.  I will forward the
554            packet to the instance of loadAutomationFile'''
555
556        # depeding on how metadata is defined, this method might change !!
557
558        self.automation.pushPacketMetaData(I,Q, metadata)
559
560
561
562    # --------------------------------------------------------------
563    # Wx details:
564
565    def OnFileExit(self, event):
566        ''' This is what will happen when you select File -> Exit
567            in the menu bar'''
568        self.Close()      #close the frame
569 
570    def OnHelpAbout(self, event):
571        '''Stuff that gets displayed when you select Help -> About in the menu bar'''
572        from wx.lib.dialogs import ScrolledMessageDialog
573        about = ScrolledMessageDialog(self, "Connection Tool.\nA product of Wireless@VT.\n\nOSSIE 0.6.2.", "About...")
574        about.ShowModal()
575
576    def OnCloseWindow(self,event):
577        '''This is what happens when you close the GUI'''
578        if hasattr(self.parent, 'removeToolFrame'):
579            self.parent.removeToolFrame(self)
580        self = None
581        event.Skip()
582
583
584class MyApp(wx.App):
585    '''for development purposes only'''
586    def OnInit(self):
587        frame = create(None)
588        self.SetTopWindow(frame)
589        return True
590
591
592if __name__ == '__main__':
593    '''for development and debugging purposes only'''
594    print "WARNING:  Running this tool in the command line is intended for testing new GUI layouts only.  For this tool to function properly, it must be called from ALF"
595    app= MyApp(0)
596    app.MainLoop()
597
598
599
600
601
602
603
Note: See TracBrowser for help on using the browser.