root/ossiedev/trunk/tools/wavedash/src/WavedashView.py @ 10915

Revision 10915, 57.0 KB (checked in by Snyder.Jason, 20 months ago)

changed labels on port boxes to include uses or provides

Line 
1## Copyright 2005, 2006, 2007, 2008 Virginia Polytechnic Institute and State University
2##
3## This file is part of the OSSIE Waveform Application Visualization Environment
4##
5## WaveDash 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## WaveDash 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 WaveDash; if not, write to the Free Software
17## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
19import wx
20import os
21import WaveformModel
22import WavedashUtils as utils
23from wx.lib import scrolledpanel
24from WaveformModel import WaveformListener
25from ComponentModel import ComponentListener
26from PropertyModel import PropertyListener
27from WavedashButton import WavedashButton
28from WavedashController import Controller
29from WavedashPreferencePage import WavedashPreferencePage
30from NSChoiceDialog import NSChoiceDialog
31from NodeBooterDialog import NodeBooterDialog
32from alf_plugins.plot import plot
33from alf import ALFutils
34
35OSSIE_WAVEAPP_DIMENSION = (600,600)                                                   
36OSSIE_TITLE = 'WaveDash Waveform Dashboard - OSSIE Waveform Workshop'
37START_ICON_FILE = "/resources/start.png"
38STOP_ICON_FILE = "/resources/stop.png"
39UNINSTALL_ICON_FILE = "/resources/LET-U.jpg"
40NAMINGSERVICE_ICON_FILE = "/resources/network.png"
41REFRESH_ICON_FILE = "/resources/refresh.png"
42NODEBOOTER_ICON_FILE = "/resources/nbstart.png"
43
44
45class WavedashView(wx.Frame, WaveformListener,
46                   ComponentListener, PropertyListener):
47    """ This is top level frame that acts as primary UI """
48    def __init__(self, controller, amodel):
49        wx.Frame.__init__(self, parent=None, id=-1, title=OSSIE_TITLE )
50#                          size = OSSIE_WAVEAPP_DIMENSION)
51        #Create the model and register the frame to the listeners of
52        #Waveform, Component and Property Models.
53       
54        self.controller = controller
55        self.model = amodel
56        self.model.addWaveformListener(self)
57        self.model.addComponentListener(self)
58        self.model.addPropertyListener(self)
59       
60        tooldir = __import__('alf_plugins').__file__
61        if os.path.islink (tooldir):
62            tooldir = os.path.realpath (tooldir)
63        tooldir = os.path.dirname (os.path.abspath (tooldir))
64        self.tools = ALFutils.ToolList(tooldir)
65       
66        self.toolbar = None
67        self.createToolBar()
68       
69        #notebook to hold the waveform panels
70        self.mainPanel = wx.Panel(self)
71        self.notebook = wx.Notebook(self.mainPanel)
72        #bind notebook to page changed event
73        self.notebook.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, self.OnNbPageChange, self.notebook)
74       
75        #sizers to manage the notebook
76        self.nbSizer = wx.BoxSizer()
77        self.nbSizer.Add(self.notebook, 1, wx.EXPAND)
78        self.mainPanel.SetSizer(self.nbSizer)
79       
80        self.statusBar = None
81        self.createMenus()
82       
83       
84       
85       
86        self.wpanels = [] # this list holds the panel objects of the installed waveforms
87        self.prpPopupMenus = {} #this dict is of the form {'wPanelRef':{window, popUpMenu}}
88        self.compPopupMenus = {}
89        self.tempProp = None
90        self.tempComp = None
91       
92        self.configureButtons = []
93       
94        self.trueValues = ["t", "true", "yes", "on", "1"]
95       
96           
97        self.Bind(wx.EVT_CLOSE, self.OnClose)
98       
99        self.SetSize(OSSIE_WAVEAPP_DIMENSION)
100        self.Center()
101        self.Show()
102       
103        if not self.controller.namingServiceIsRunning():
104            nscd = NSChoiceDialog(self)       
105   
106         
107    def createToolBar(self):
108        self.toolbar = self.CreateToolBar()
109        rsize = (20, 20)
110        refreshImg = wx.ArtProvider.GetBitmap(wx.ART_REDO, wx.ART_TOOLBAR, rsize)
111        refresh = self.toolbar.AddSimpleTool(-1,refreshImg ,shortHelpString="Refresh")
112        self.Bind(wx.EVT_TOOL, self.OnRefresh, refresh)
113       
114        root = self.getRoot()
115       
116        selectNSIcon = wx.Image(root + NAMINGSERVICE_ICON_FILE, wx.BITMAP_TYPE_ANY).ConvertToBitmap()
117        selectNS = self.toolbar.AddSimpleTool(-1, selectNSIcon, shortHelpString="Configure Naming Service address")
118       
119        startIcon = wx.Image(root + START_ICON_FILE, wx.BITMAP_TYPE_ANY).ConvertToBitmap()
120        stopIcon = wx.Image(root + STOP_ICON_FILE, wx.BITMAP_TYPE_ANY).ConvertToBitmap()
121        uninstallIcon = wx.Image(root + UNINSTALL_ICON_FILE, wx.BITMAP_TYPE_ANY).ConvertToBitmap()
122        start = self.toolbar.AddSimpleTool(-1, startIcon, shortHelpString="Start waveform")
123        stop = self.toolbar.AddSimpleTool(-1, stopIcon, shortHelpString="Stop Waveform")
124        uninstall = self.toolbar.AddSimpleTool(-1, uninstallIcon, shortHelpString="Uninstall waveform")
125       
126        startNodeBooterIcon = wx.Image(root + NODEBOOTER_ICON_FILE, wx.BITMAP_TYPE_ANY).ConvertToBitmap()
127        startNodeBooter = self.toolbar.AddSimpleTool(-1, startNodeBooterIcon, shortHelpString="Start NodeBooter")
128       
129       
130        self.Bind(wx.EVT_TOOL, self.OnStart, start)
131        self.Bind(wx.EVT_TOOL, self.OnStop, stop)
132        self.Bind(wx.EVT_TOOL, self.OnUninstall, uninstall)
133        self.Bind(wx.EVT_TOOL, self.OnSelectNS, selectNS)
134        self.Bind(wx.EVT_TOOL, self.OnStartNodeBooter, startNodeBooter)
135   
136    def OnStart(self, event):
137        activeWform = self.model.getActiveWaveform()
138        if activeWform is None:
139                utils.showMessage("Start Failed!!! No waveform is running now",
140                                    utils.NON_FATAL)
141                return
142        status = self.controller.startWaveform(activeWform.getName())
143   
144    def OnStop(self, event):
145        activeWform = self.model.getActiveWaveform()
146        if activeWform is None:
147            utils.showMessage("Stop Failed!!! No waveform is running now",
148                               utils.NON_FATAL)
149            return
150        status = self.controller.stopWaveform(activeWform.getName())
151   
152    def OnUninstall(self, event):   
153        selWform = self.model.getActiveWaveform()
154        if selWform is None:
155                utils.showMessage("Uninstall Failed!!! No waveform is running now",
156                                   utils.NON_FATAL)
157                return
158
159        #iterate through a slice of the whole list rather than
160        #the list itself so prevent errors
161        for button in self.configureButtons[:]:
162            if(button.isWaveformButton == True and button.getParentName() == selWform.getName()):
163                self.configureButtons.remove(button)
164
165        for button in self.configureButtons[:]:
166            if(button.isComponentButton == True and button.getGrandParentName() == selWform.getName()):
167                self.configureButtons.remove(button)
168                 
169        success = self.model.removeWaveform(selWform)
170           
171    def OnSelectNS(self, event):
172        self.controller.selectNS()
173       
174    def OnStartNodeBooter(self, event):
175        nbd = NodeBooterDialog(self)
176       
177        if nbd.GetReturnCode() == 0:
178            self.controller.CORBAutils.setNamingService('127.0.0.1')
179            self.controller.CORBAutils.init_CORBA()
180            self.controller.refresh()
181
182    def createMenus(self):
183        menuBar = wx.MenuBar()
184        #These features are not yet implemented in 0.7.3
185#        fileMenu = wx.Menu()
186#        openLayout = fileMenu.Append(-1, '&Open Layout')
187#        saveLayout = fileMenu.Append(-1, '&Save Layout')
188#        saveLayoutAs = fileMenu.Append(-1, 'S&ave Layout As')
189#        exit = fileMenu.Append(-1, 'E&xit\tCtrl-Q')
190#       
191#        self.Bind(wx.EVT_MENU, self.OnOpenLayout, openLayout)
192#        self.Bind(wx.EVT_MENU, self.OnSaveLayout, saveLayout)
193#        self.Bind(wx.EVT_MENU, self.OnSaveLayoutAs, saveLayoutAs)
194#        self.Bind(wx.EVT_MENU, self.OnExit, exit)   
195#       
196        waveformsMenu = wx.Menu()     
197        componentsMenu = wx.Menu()
198        optionsMenu = wx.Menu()
199        self.updateOnRefresh = optionsMenu.Append(501, 'Update Properties on Refresh', 'Update Properties on Refresh', kind=wx.ITEM_CHECK)
200        self.preferences = optionsMenu.Append(502, 'Wavedash Preferences', 'Wavedash Preferences', kind=wx.ITEM_NORMAL)
201        self.updateOnRefresh.Check(False)
202        self.Bind(wx.EVT_MENU, self.OnUpdateOnRefreshCheck, self.updateOnRefresh)
203        self.Bind(wx.EVT_MENU, self.OpenPreferences, self.preferences)
204       
205#        preferencesMenu = wx.Menu()
206#        widgetSettings = preferencesMenu.Append(-1, '&Widget Settings')
207#        self.Bind(wx.EVT_MENU, self.OnWidgetSettings,widgetSettings)
208#       
209        helpMenu = wx.Menu()
210        about = helpMenu.Append(-1,'&About')
211        self.Bind(wx.EVT_MENU, self.OnAbout, about)
212       
213#        menuBar.Append(fileMenu, '&File')
214        menuBar.Append(waveformsMenu, '&Waveforms')
215        #waveformsMenu.AppendSeparator()
216        menuBar.Append(componentsMenu, '&Components')
217        #menuBar.Append(preferencesMenu, '&Preferences')
218        menuBar.Append(optionsMenu, '&Options')
219        menuBar.Append(helpMenu, '&Help')
220       
221        self.SetMenuBar(menuBar)
222   
223    def createWaveformPanel(self, parent, waveform, preview = False):
224       # if(waveform.name == "w1_1"):
225            #print "in createWaveform Panel"
226            #for comp in waveform.components:
227             #   for prop in comp.properties:
228              #      print str(prop.id) + ": "  + str(prop.getValue())
229       
230        wPanel = scrolledpanel.ScrolledPanel(parent, -1, name=waveform.getName())
231        wSizer = wx.BoxSizer(wx.VERTICAL)
232        componentList = waveform.getAllComponents()
233       
234       
235                   
236        for component in componentList:
237            cPanel = self.createComponentPanel(wPanel,component, preview)
238            wSizer.Add(cPanel, 0, wx.ALIGN_LEFT | wx.GROW, 10)
239           
240        wSizer.AddSpacer(10)
241       
242        root = self.getRoot()
243        refreshIcon = wx.Image(root + REFRESH_ICON_FILE, wx.BITMAP_TYPE_ANY).ConvertToBitmap()
244
245        updateWaveformButton = WavedashButton(wPanel, wx.NewId(), refreshIcon)
246        updateWaveformButton.setParentName(waveform.getName())
247        updateWaveformButton.setGrandParentName("none")
248        updateWaveformButton.setIsWaveformButton()
249        updateWaveformButton.Enable(self.updateOnRefresh.IsChecked())
250        wPanel.Bind(wx.EVT_BUTTON, self.OnUpdateWaveformClicked, updateWaveformButton)
251
252        self.configureButtons.append(updateWaveformButton)
253        wSizer.Add(updateWaveformButton, flag=wx.ALIGN_RIGHT)
254       
255           
256        wPanel.SetSizer(wSizer)
257        wPanel.SetupScrolling(True, True, 20, 20)
258       
259        #No need to add the panels to the wpanels list when preview is On
260        if preview is False:
261            self.wpanels.append(wPanel)
262       
263        wSizer.Fit(wPanel)
264        return wPanel
265               
266    def createComponentPanel(self, wPanel, component, preview = False):
267        cPanel = wx.Panel(wPanel, -1, name=component.getName())
268        component.setPanel(cPanel)
269        sbox = wx.StaticBox(cPanel, -1, component.getName())
270        sboxSizer = wx.StaticBoxSizer(sbox, wx.VERTICAL)
271        prpWidgetList = []
272
273        root = self.getRoot()
274
275        if not component.isVisible():
276            cPanel.Hide()
277       
278        propertyList = component.getAllProperties()
279        #properites of a component are laid on the component panel using a gridbag sizer
280        #Each widget takes one cell except a Slider which spans across multiple columns
281       # if(component.parent.name == "w1_1"):
282        #    print "in addComponentPanel"
283         #   for prop in component.properties:
284          #      print str(prop.id) + ": "  + str(prop.getValue())
285       
286        for property in propertyList:
287            widget = property.getWidget()
288           
289            plabel = wx.StaticText(cPanel, -1, property.getName(), name = property.getName())
290            pWindow = self.mapWidgetToWindow(cPanel, property, widget)
291            pWindow.SetToolTipString(property.getDesc())
292            property.setWindow(pWindow)
293           
294            if not property.isVisible():
295                plabel.Hide()
296                pWindow.Hide()
297           
298            if preview is True:
299                #Don't allow any manipulation on properties in Preview form.
300                pWindow.Enable(False)
301               
302            #Create a popup menu for this property
303            self.attachPopupMenuToProp(wPanel, pWindow, property)
304           
305            windowType = pWindow.__class__
306            eventType = wx.EVT_KILL_FOCUS
307           
308            #Find the type of event corresponding to the window in use
309            if windowType is wx.TextCtrl or windowType is wx.SpinCtrl:
310                pWindow.Bind(wx.EVT_TEXT_ENTER, self.OnPropValueChanged, pWindow)
311                pWindow.Bind(wx.EVT_KILL_FOCUS, self.OnPropValueChanged, pWindow)
312            elif windowType is wx.Slider:
313                pWindow.Bind(wx.EVT_COMMAND_SCROLL, self.OnPropValueChanged, pWindow)
314            elif windowType is wx.CheckBox:
315                pWindow.Bind(wx.EVT_CHECKBOX, self.OnPropValueChanged, pWindow)
316           
317            #checkbox has a label associated with itself. so no need to add separate label
318            if pWindow.__class__ is wx.CheckBox:
319                plabel.SetLabel("")
320               
321   
322           
323            prpWidgetList.append(plabel)
324            prpWidgetList.append(pWindow)
325       
326        #prpWidgetList contains the label and widgets for all the properties of this component
327        #addPropToCompSizer creates a new gridbagsizer and adds the labels and widgets contained
328        #in the prpWidgetList
329       
330        gbagSizer = self.addPropToCompSizer(prpWidgetList)
331       
332       
333       
334        sboxSizer.SetMinSize(gbagSizer.GetMinSize())
335        sboxSizer.Add(gbagSizer, 1, wx.ALIGN_CENTER | wx.EXPAND, 10)
336       
337        refreshIcon = wx.Image(root + REFRESH_ICON_FILE, wx.BITMAP_TYPE_ANY).ConvertToBitmap()
338       
339        portsSizer = wx.BoxSizer(wx.HORIZONTAL)
340   
341        if len(component.providesPorts) > 0:
342            providesPortsBox = self.createPortBox(component.providesPorts, component, cPanel, sboxSizer, 'Input (Provides) Ports')
343            portsSizer.Add(providesPortsBox)
344            portsSizer.AddSpacer(wx.Size(10, 10))
345        if len(component.usesPorts) > 0:
346            usesPortsBox = self.createPortBox(component.usesPorts, component, cPanel, sboxSizer, 'Output (Uses) Ports')
347            portsSizer.Add(usesPortsBox)
348        sboxSizer.AddSpacer(wx.Size(10, 10))
349        sboxSizer.Add(portsSizer)
350       
351       
352        updateComponentButton = WavedashButton(cPanel, wx.NewId(), refreshIcon )
353        updateComponentButton.setParentName(component.getName())
354        updateComponentButton.setGrandParentName(component.getParent().getName())
355        updateComponentButton.setIsComponentButton()
356        updateComponentButton.Enable(self.updateOnRefresh.IsChecked())
357        cPanel.Bind(wx.EVT_BUTTON, self.OnUpdateComponentClicked, updateComponentButton)
358        self.configureButtons.append(updateComponentButton)
359        sboxSizer.Add(updateComponentButton, flag=wx.ALIGN_RIGHT) 
360       
361       
362       
363        cPanel.SetSizer(sboxSizer)
364     
365        #After layingout the widgets (labels & controls) for all the properties,
366        #attach a popupmenu at component level. i.e. for each component panel
367       
368        self.attachPopupToComponent(component, cPanel)
369        return cPanel
370   
371    def createPortBox(self, portList, component, panel, sizer, portType):
372        portsBox = wx.StaticBox(panel, wx.NewId(), portType)
373        portsBoxSizer = wx.StaticBoxSizer(portsBox, wx.VERTICAL)
374       
375        for port in portList:
376            portLabel = wx.StaticText(panel, wx.NewId(), label=port.name)
377            availableTools = self.tools.getSupportedTools(port.interface.nameSpace, port.interface.name)
378            toolList = []
379           
380            if availableTools:
381                for tool in availableTools:
382                    toolList.append(tool.name)
383                portToolCombo = wx.ComboBox(panel, wx.NewId(), value='Available Tools', choices=toolList, style=wx.CB_READONLY)
384                portToolCombo.SetToolTipString(port.interface.name)
385                portToolCombo.port = port
386                portToolCombo.supportedTools = availableTools
387                panel.Bind(wx.EVT_COMBOBOX, self.openTool, portToolCombo)
388            else:
389                portToolCombo = wx.ComboBox(panel, wx.NewId(), value='No Available Tools', choices=toolList, style=wx.CB_READONLY)
390               
391            portsBoxSizer.Add(portLabel)
392            portsBoxSizer.Add(portToolCombo)
393        return portsBoxSizer
394       
395       
396    def addPropToCompSizer(self, propList):
397        #IMPORTANT NOTE: proplist should have items in the following way.
398        #[label, window, label, window, label, window, .... ]
399        index = 0
400        gridSizer = wx.GridSizer(2,4,5,5)
401       
402        while (index < len(propList) ):
403            plabel = propList[index]
404            pWindow = propList[index+1]
405           
406            #if the windows are hidden, don't add them to the sizer.
407            #They will be added when the user select the properties again.
408            if (not plabel.IsShown()) or (not pWindow.IsShown()):
409                index = index + 2
410                continue
411            gridSizer.Add(plabel, 0)
412            gridSizer.Add(pWindow, 0)
413            index = index + 2
414        return gridSizer
415     
416    def attachPopupToComponent(self, component, cPanel):
417        cPopup = wx.Menu(title='')
418        moveUp = cPopup.Append(wx.NewId(), 'Move up')
419        moveDown = cPopup.Append(wx.NewId(), 'Move Down')
420        save = cPopup.Append(wx.NewId(), 'Save')
421        saveAs = cPopup.Append(wx.NewId(), 'Save As')
422       
423        #save and saveAs will be implemented in next release.disable for now
424        save.Enable(False)
425        saveAs.Enable(False)
426       
427        prpMenu = wx.Menu()
428        #All properties are enabled by default.
429        prpList = component.getAllProperties()
430        for prp in prpList:
431            chkMenuItem = prpMenu.AppendCheckItem(wx.NewId(), prp.getName())
432            chkMenuItem.Check(True)
433            self.Bind(wx.EVT_MENU, self.OnPropertySelect, chkMenuItem)
434           
435        cPopup.AppendMenu(wx.NewId(), 'Properties', prpMenu)
436       
437        wPanel = cPanel.GetParent()
438       
439        if self.compPopupMenus.has_key(wPanel):
440            cPanelDict = self.compPopupMenus[wPanel]
441            if cPanelDict.has_key(cPanel.GetName()) is False:
442                cPanelDict[str(cPanel.GetName())] = cPopup
443        else:
444            self.compPopupMenus[wPanel] = {cPanel.GetName():cPopup}
445       
446        self.Bind(wx.EVT_MENU, self.OnComponentMoveUp, moveUp)
447        self.Bind(wx.EVT_MENU, self.OnComponentMoveDown, moveDown)
448       
449        cPanel.Bind(wx.EVT_RIGHT_DOWN, self.OnComponentRightClick)
450       
451   
452    def OnComponentRightClick(self, event):
453        src = event.GetEventObject()
454        curWPanel = self.getCurrentPanel()
455        #Storing the reference to current component panel in a temp variable
456        #This temp will be used to map the context menu and the component menu in
457        #the event handler for PropertySelect and other items in Context menu also.
458       
459        self.tempComp = src
460        for wpanel in self.compPopupMenus.keys():
461            if wpanel is curWPanel:
462                windowDict = self.compPopupMenus[wpanel]
463                src.PopupMenu(windowDict[str(src.GetName())])
464   
465    def attachPopupMenuToProp(self, wPanel, window, property):
466        pSubMenu = wx.Menu(title='')
467        #default = property.getWidget()
468        default = self.controller.getDefaultWidget(property.getType())
469        optList = self.controller.getOptionalWidgets(property.getType())
470       
471        mItem = pSubMenu.AppendRadioItem(wx.NewId(), default.type)
472        self.Bind(wx.EVT_MENU, self.PropPopupHandler, id = mItem.GetId())
473        for optWidget in optList:
474            mItem = pSubMenu.AppendRadioItem(wx.NewId(), optWidget.type)
475            self.Bind(wx.EVT_MENU, self.PropPopupHandler, id = mItem.GetId())
476            if property.getWidget().type == optWidget.type:
477                mItem.Check(True)
478           
479        pSubMenu.AppendSeparator()
480        configure = pSubMenu.Append(wx.NewId(), 'Configure')
481        self.Bind(wx.EVT_MENU, self.PropConfigureHandler, id = configure.GetId())
482       
483        #Configure shuold be enabled only for slider and spin buttons.
484        #If other options are enabled, then disable the Configure Menu Item
485        self.propPopUpUpdate(pSubMenu)
486       
487        chgMenu = wx.Menu(title='')
488        chgMenuItem = wx.MenuItem(chgMenu, wx.NewId(), 'Change To', subMenu = pSubMenu)
489        chgMenu.AppendItem(chgMenuItem)
490       
491        #Associate the pop Menu with the window
492        cpRef = property.getParent().getName() + '/' + property.getName()
493       
494        if self.prpPopupMenus.has_key(wPanel):
495            subDict = self.prpPopupMenus[wPanel]
496            if subDict.has_key(cpRef) is False:
497                subDict[cpRef] = chgMenu
498        else:
499            self.prpPopupMenus[wPanel] = {cpRef:chgMenu}
500       
501        window.Bind(wx.EVT_RIGHT_DOWN, self.OnPropRightClick)
502       
503    def OnPropRightClick(self, event):
504        src = event.GetEventObject()
505        curPanel = self.getCurrentPanel()
506        #The widget(actual wxPython windows) on which the Popupmenu is invoked is
507        #stored in a temp variable to access it later during the events generated
508        #by PopUpMenu
509       
510        self.tempProp = src
511        for wpanel in self.prpPopupMenus.keys():
512            if wpanel is curPanel:
513 
514        #===============================================================================
515        #  A pop-up menu is associated with each property. the member variable prpPopupMenus
516        #  is a hash object indexed by waveform names. Value of a hash object points to another
517        #  hash which indexes the popup menus by component_name/property_name.
518        #===============================================================================
519
520                windowDict = self.prpPopupMenus[wpanel]
521                cpRef = src.GetParent().GetName() + '/' + src.GetName()
522                src.GetParent().PopupMenu(windowDict[cpRef])
523           
524   
525    def PropPopupHandler(self, event):
526        srcId = event.GetId()
527        mItems = event.GetEventObject().GetMenuItems()
528       
529        #Enable the configure option only slider and spin box to set their min and
530        #max values.
531       
532        self.propPopUpUpdate(event.GetEventObject())
533       
534        for mItem in mItems:
535            if mItem.GetId() == srcId:       
536                #self.tempProp is set to identify the property when Popupmenu is invoked.   
537                property = self.tempProp
538                component = property.GetParent()
539                wform = component.GetParent()
540                wformRef = self.model.getActiveWaveform()
541                compRef = wformRef.getComponent(component.GetName())
542                propRef = compRef.findPropertyByName(property.GetName())
543                self.model.changePropertyWidget(component.GetName(),
544                                                property.GetName(), mItem.GetItemLabel())
545               
546
547    def PropConfigureHandler(self, event):
548        propertyCtrl = self.tempProp
549        cPanel = propertyCtrl.GetParent()
550        wPanel = cPanel.GetParent()
551       
552        #Get reference to the property thruogh its compnent and waveform.
553        #Then, get the widget reference from the property
554        wform = self.model.getActiveWaveform()
555        component = wform.getComponent(cPanel.GetName())
556        property = component.findPropertyByName(propertyCtrl.GetName())
557       
558        widget = property.getWidget()
559       
560        if propertyCtrl.__class__ is wx.SpinCtrl \
561            or propertyCtrl.__class__ is wx.Slider:
562            curMin, curMax = property.getRange()
563            curValue = property.getValue()
564            #curMin = widget.getMin()
565            #curMax = widget.getMax()
566            title = 'Widget Configuration'
567            confDialog = utils.ConfigureWidget(self, title, curValue)
568            confDialog.setMin(curMin)
569            confDialog.setMax(curMax)
570           
571            confDialog.ShowModal()
572           
573            #Get the new min and max once the dialog is destroyed in the
574            #event handlers of Ok and Cancel defined in ConfigureWidget
575            newMin = confDialog.getMin()
576            newMax = confDialog.getMax()
577                       
578            #No need to udpate the model if the values are not changed
579            if (newMin == curMin) and (newMax == curMax):
580                return
581            else:
582                # the newMin and newMax values will be updated to the range attribute of the property
583                status = self.model.configurePropertyWidget(cPanel.GetName(), propertyCtrl.GetName(), newMin, newMax)
584                if status is False:
585                    utils.showMessage("Invalid range of values (" + str(newMin) + "," + str(newMax) + ")" , utils.NON_FATAL)
586                return
587   
588    def propPopUpUpdate(self, menu):     
589        menuItems = menu.GetMenuItems()
590        confItemId = menu.FindItem('Configure')
591        confItem = menu.FindItemById(confItemId)
592        confItem.Enable(False)
593       
594        for mItem in menuItems:
595            if mItem.GetItemLabel() == "spin" or mItem.GetItemLabel() == "slider":
596                if mItem.IsChecked():
597                    confItem.Enable(True)
598       
599    def mapWidgetToWindow(self, parent, property, widget):
600        window = None
601        label = None
602        pValue = property.getValue()
603
604        widgetType = widget.type
605       
606        if widgetType == "text":                   
607            window = wx.TextCtrl(parent, -1, str(pValue), style = wx.TE_PROCESS_ENTER)
608        elif widgetType == "spin":
609            minV, maxV = property.getRange()
610            window = wx.SpinCtrl(parent, -1, str(pValue), min = minV, max = maxV, style = wx.TE_PROCESS_ENTER)
611        elif widgetType == "slider":
612            minV, maxV = property.getRange()
613            if widget.parameters["style"] == "HORIZONTAL":
614                styleV = wx.SL_HORIZONTAL | wx.SL_LABELS
615            elif widget.parameters["style"] == "VERTICAL":
616                styleV = wx.SL_VERTICAL | wx.SL_LABELS
617            window = wx.Slider(parent, -1, int(pValue), minValue = minV, maxValue = maxV, style = styleV, size=(120,35))
618        elif widgetType == "checkbox":
619            window = wx.CheckBox(parent, -1, property.getName())
620        elif widgetType == "listbox":
621            if (pValue is not None) and (type(pValue) is list):
622                window = wx.TextCtrl(parent, -1, str(pValue))
623            else:
624                window = wx.TextCtrl(parent, -1, str(None))
625        else:
626            window = wx.TextCtrl(parent, -1, str(pValue))
627       
628        if window is not None:
629            window.SetName(property.getName())   
630        return window
631   
632    def OnPropValueChanged(self, event):
633        if(self.updateOnRefresh.IsChecked()):
634            return
635        src = event.GetEventObject()
636        prp = src.GetName()
637        comp = src.GetParent().GetName()
638        wName = src.GetParent().GetParent().GetName()
639        wform = self.model.getWaveform(wName, WaveformModel.INSTANCE_WAVEFORM)
640        #This event is triggered whenever a property widget loses its focus.
641        #A widget loses its focus when the user switch to another widget in the same window
642        #or select a different waveform.
643        if wform is None:
644            #if event triggered as a result of object destroy or from Waveform Preview Dialog
645            #then no need to update the value. Just return
646            return
647       
648        compRef = wform.getComponent(comp)
649        prpRef = compRef.findPropertyByName(prp)
650       
651        curVal = self.formatWidgetToModel(src.GetValue(), prpRef.getType())
652        preVal = prpRef.getValue()
653       
654
655        if curVal is not None:
656           
657            #if both the values are equal then no need to call configure()
658            if preVal == curVal:
659                #in cases where a boolean property was changed to a different
660                #text value but the same boolean value (ie True changed to 1)
661                #the model won't configure since the actual value didnt change
662                #so we have to call formatModelToWidget to change the text back
663                # to True or False
664                if(prpRef.type[1] == "boolean"):
665                    self.formatModelToWidget(src, curVal)
666                return
667            else:
668                #print "configuring: wName = " + str(wName) + ", comp = " + str(comp) + ", prp = " + str(prp) + ", curVal = " + str(curVal)
669                status = self.model.configure(wName, comp, prp, curVal)
670
671                #leave the text box as it is if status is True
672                #if the configure operation failed, revert the text value to the value stored in
673                #the model.
674                if status is False:
675                    msg = "Could not configure " + prp
676                    utils.showMessage(msg, utils.NON_FATAL)
677                    self.formatModelToWidget(src, preVal)
678                    #src.SetValue(str(preVal))
679                elif prpRef.type[1] == "boolean":
680                    self.formatModelToWidget(src, curVal)
681               
682        else:
683            msg = "Invalid value for %s/%s" % (comp, prp) + "\nEnter only '" + prpRef.getType()[1] + "' values"
684            msg = msg + "\nFor sequence types, enter values separated by comma"
685            msg = msg + " and enclosed within [] e.g. [10,20,30]"
686           
687            utils.showMessage(msg, utils.NON_FATAL)
688            self.formatModelToWidget(src, preVal)     
689            self.Layout()   
690           
691   
692    def formatModelToWidget(self, widget, value):
693        if widget.__class__ is wx.TextCtrl:
694            widget.SetValue(str(value))
695        elif widget.__class__ is wx.SpinCtrl:           
696            widget.SetValue(int(value))
697        elif widget.__class__ is wx.Slider:
698            widget.SetValue(int(value))
699        elif widget.__class__ is wx.CheckBox:
700            if value == "True" or value == 1:
701                widget.SetValue(True)
702            else:
703                widget.SetValue(False)
704       
705               
706         
707    def formatWidgetToModel(self, curVal, propType):
708        """ Converts the string literal into the suitable data type
709        as configured for the property"""
710        val = None
711        #propType is a tuple containing the (xmlType,datatype)
712        #e.g. ('simple','short')
713        xmlType = propType[0]
714        dtype = propType[1]
715
716        try:
717            if (xmlType == "simple"):
718                if dtype == "short" or dtype == "ushort":
719                    val = int(curVal)
720                elif dtype == "int" or dtype == "uint":
721                    val = int(curVal)
722                elif dtype == "long" or dtype == "ulong":
723                    val = long(curVal)
724                elif dtype == "double" or dtype == "float":
725                    val = float(curVal)
726                elif dtype == "char":
727                    val = str(curVal)
728                elif dtype == "boolean":
729                    if str(curVal).lower() in self.trueValues:
730                        val = True
731                    else:
732                        val = False
733                elif dtype == "string":
734                    val = str(curVal)
735                else:
736                    val = None
737            #sequence values are represented as list of values separated
738            #by a comma. e.g. '[10,20,30]'
739           
740            elif (xmlType == "simplesequence"):
741                if dtype == "float":
742                    val = []
743                    #strip the open and close bracket
744                    listVal = curVal.lstrip('[')
745                    listVal = listVal.rstrip(']')
746                    for lVal in listVal.split(','):
747                        val.append(float(lVal))
748                if dtype == "string":
749                    val = []
750                    #strip the open and close bracket
751                    listVal = curVal.lstrip('[')
752                    listVal = listVal.rstrip(']')
753                    for lVal in listVal.split(','):
754                        val.append(str(lVal))
755                if dtype == "short" or dtype == "int":
756                    val = []
757                    #strip the open and close bracket
758                    listVal = curVal.lstrip('[')
759                    listVal = listVal.rstrip(']')
760                    for lVal in listVal.split(','):
761                        val.append(int(lVal))
762                   
763        except(ValueError):
764            val = None
765       
766        return val
767       
768    def AddToWaveformsMenu(self, newWaveform, type):
769        wMenu = self.FindMenuInMenuBar('Waveforms')
770       
771        if type == WaveformModel.SYSTEM_WAVEFORM:
772            wSubMenu = wx.Menu()
773            install = wSubMenu.Append(-1, 'Install')
774            installAndStart = wSubMenu.Append(-1, 'Install and Start')
775            viewWform = wSubMenu.Append(-1, 'Preview')
776            properties = wSubMenu.Append(-1, 'Properties')
777           
778            wMenu.InsertMenu(0,-1, newWaveform, wSubMenu) #insert at the start of the list
779           
780            self.Bind(wx.EVT_MENU, self.OnWaveformInstall, install)
781            self.Bind(wx.EVT_MENU, self.OnWaveformInstallAndStart, installAndStart)
782            self.Bind(wx.EVT_MENU, self.OnWaveformPreview, viewWform)
783            self.Bind(wx.EVT_MENU, self.OnWaveformProperties, properties)
784               
785    def AddToComponentsMenu(self, newComponent, isVisible):
786        cMenu = self.FindMenuInMenuBar('Components')
787        citem = cMenu.AppendCheckItem(-1, newComponent)
788        self.Bind(wx.EVT_MENU, self.OnComponentMenuClick, citem)
789       
790        if isVisible:
791            citem.Check(True)
792   
793    def OnWaveformInstall(self, event):
794        chosenMenu = event.GetEventObject()
795        parent = chosenMenu.GetParent()
796       
797        for mItem in parent.GetMenuItems():
798            if mItem.GetSubMenu() is chosenMenu:
799                self.controller.installWaveform(mItem.GetItemLabel(), False)
800                break
801   
802    def OnWaveformInstallAndStart(self, event):
803        chosenMenu = event.GetEventObject()
804        parent = chosenMenu.GetParent()
805       
806        for mItem in parent.GetMenuItems():
807            if mItem.GetSubMenu() is chosenMenu:
808                self.controller.installWaveform(mItem.GetItemLabel(), True)
809                break
810   
811    def OnPropertySelect(self, event):
812        srcId = event.GetId()
813        pMenu = event.GetEventObject()
814        mItemList = pMenu.GetMenuItems()
815        for mItem in mItemList:
816            if srcId == mItem.GetId():
817                propName = mItem.GetItemLabel()
818                #self.tempComp has the reference to the component panel on which
819                #the context menu is invoked in ComponentRightClick Handler
820                compName = self.tempComp.GetName()
821                self.model.updatePropertyState(compName, propName, mItem.IsChecked())
822                break
823   
824    def OnComponentMoveUp(self, event):       
825        compName = self.tempComp.GetName()
826        wformName = self.tempComp.GetParent().GetName()
827        self.model.moveComponentUp(wformName, compName)
828   
829    def OnComponentMoveDown(self, event):
830        compName = self.tempComp.GetName()
831        wformName = self.tempComp.GetParent().GetName()
832        self.model.moveComponentDown(wformName, compName)
833           
834   
835    def OnWaveformPreview(self, event):
836        chosenMenu = event.GetEventObject()
837        parent = chosenMenu.GetParent()
838       
839        for mItem in parent.GetMenuItems():
840            if mItem.GetSubMenu() is chosenMenu:
841                wformName = mItem.GetItemLabel()
842                waveform = self.model.getWaveform(wformName, WaveformModel.SYSTEM_WAVEFORM)
843                title = 'Preview - ' + wformName
844               
845                previewFrame = wx.Frame(self, -1, title, OSSIE_WAVEAPP_DIMENSION)
846                wPanel = self.createWaveformPanel(previewFrame, waveform, preview = True)
847                wPanel.Show()
848                previewFrame.Show()
849                break
850   
851    def OnWaveformProperties(self, event):
852        chosenMenu = event.GetEventObject()
853        parent = chosenMenu.GetParent()
854       
855        for mItem in parent.GetMenuItems():
856            if mItem.GetSubMenu() is chosenMenu:
857                wformName = mItem.GetItemLabel()
858                wformObj = self.model.getWaveform(wformName, WaveformModel.SYSTEM_WAVEFORM)
859                print str(wformObj)
860                title = wformName + " - Properties"
861                wformProperties = str(wformObj)
862                dlg = wx.MessageDialog(None, wformProperties, title, wx.OK | wx.ICON_INFORMATION)
863                try:
864                    dlg.ShowModal()
865                finally:
866                    dlg.Destroy()
867   
868    #Event Handler for page change. Update the active waveform on each page change
869    def OnNbPageChange(self, event):
870        pageId = event.GetSelection()
871        #GetPage() returns the reference to waveform panel object
872        wPanel = self.notebook.GetPage(pageId)
873        #update active waveform in the model
874        self.model.setActiveWaveform(wPanel.GetName())
875   
876    def OnComponentMenuClick(self, event):
877        cMenu = event.GetEventObject()
878        mItemList = cMenu.GetMenuItems()
879        for mItem in mItemList:
880            self.model.updateComponentState(mItem.GetItemLabel(), mItem.IsChecked())
881       
882    def UpdateComponentMenu(self, wform):
883       
884        componentList = wform.getAllComponents()
885        compMenu = self.FindMenuInMenuBar('Components')
886        #clear the existing items in Component Menu
887        for mItem in compMenu.GetMenuItems():
888            compMenu.DeleteItem(mItem)
889           
890        #Now update the component Menu wit the components of currently selected waveform
891        for component in componentList:
892            self.AddToComponentsMenu(component.getName(), component.isVisible())
893       
894    #listeners of WaveformListener interface
895    def waveformAdded(self, event):
896        wform = event.getSource()
897        #if(wform.name == "w1"):
898         #   print "in waveform Added"
899          #  for comp in wform.components:
900           #     for prop in comp.properties:
901                #        print str(prop.id) + ": "  + str(prop.getValue())
902                   
903                   
904       
905        #create the panel only if it is a instance waveform.
906        #For system waveform, just add it to the menu
907        wType = wform.getType()
908        if wType == WaveformModel.INSTANCE_WAVEFORM:
909            wPanel = self.createWaveformPanel(self.notebook, wform)
910            self.notebook.AddPage(wPanel, wform.getName())
911           
912        self.AddToWaveformsMenu(wform.getName(), wType)
913   
914    def waveformRemoved(self, event):
915       
916        srcWform = event.getSource()
917        #if waveform removed is a SYSTEM_WAVEFORM, i.e. the one found in /sdr/dom/waveforms,
918        #remove the waveform from the Waveforms Menu
919        if srcWform is not None and srcWform.getType() == WaveformModel.SYSTEM_WAVEFORM:
920            wformsMenu = self.FindMenuInMenuBar('Waveforms')
921            menuItems = wformsMenu.GetMenuItems()
922            for mItem in menuItems:
923                if mItem.GetItemLabel() == srcWform.getName():
924                    wformsMenu.DeleteItem(mItem)
925                    break
926            return
927     
928        curPanelId = self.notebook.GetSelection()
929        curPanel = self.notebook.GetCurrentPage()
930        wformName = curPanel.GetName()
931        self.wpanels.remove(curPanel)
932        #remove the panel from the notebook
933        self.notebook.RemovePage(curPanelId)
934        #destroy the waveform panel object
935        curPanel.Destroy()
936       
937        msg = ("%s Uninstalled !" % wformName)
938        utils.showMessage(msg, utils.INFO)
939       
940        #AdvanceSelection() sets the next available page active
941        #and trigger EVT_NOTEBOOK_PAGE_CHANGED event. The event
942        #handler OnNbPageChange() would be called that sets the
943        #active waveform thruogh model.SetActiveWaveform()
944       
945        self.notebook.AdvanceSelection(True)
946       
947        #if no running waveforms on the system?
948        if self.notebook.GetPageCount() == 0:
949            compMenu = self.FindMenuInMenuBar('Components')
950            #clear the existing items in Component Menu
951            for mItem in compMenu.GetMenuItems():
952                compMenu.DeleteItem(mItem)
953            self.model.setActiveWaveform(None)
954            self.SetSize(OSSIE_WAVEAPP_DIMENSION)
955        #notebook.AdvanceSelection() will not trigger PAGE_CHANGED event if there is
956        #only one panel left. Hence, set the active form explicitly.
957        elif self.notebook.GetPageCount() == 1:
958            nextActiveWform = self.notebook.GetCurrentPage().GetName()
959            self.model.setActiveWaveform(nextActiveWform)
960       
961    def waveformSelected(self, event):
962        wform = event.getSource()
963        #If no waveform is there, just update the title and status Bar and return
964        if wform is None:
965            self.SetTitle(OSSIE_TITLE)
966            #self.updateStatusBar()
967            return   
968        self.SetTitle(OSSIE_TITLE + ' (' + wform.getName() + ')')
969        #Component menu needs to be updated per waveform basis.       
970        self.UpdateComponentMenu(wform)
971        self.Layout()
972       
973    def componentStateChanged(self, cEvent):
974        """ A listener method of ComponentListener class that is triggerred
975        whenever a component is selected/deselected in the Component Menu"""
976
977        wPanel = self.getCurrentPanel()
978        cPanelList = wPanel.GetChildren()
979        wPanelSizer = wPanel.GetSizer()     
980        componentList = self.model.getActiveWaveform().getAllComponents()
981       
982        #Detach all the existing panels from the sizer
983        for cPanel in cPanelList:
984            if wPanelSizer.GetItem(cPanel) != None:
985                wPanelSizer.Detach(cPanel)
986                cPanel.Hide()
987       
988        #Update the sizer to be inline with the order of components in Waveform Model
989        for cmp in componentList:
990            if cmp.isVisible():
991                #print cmp.getPosition()
992                for cPanel in cPanelList:
993                    if cPanel.GetName() == cmp.getName():
994                        wPanelSizer.Add(cPanel, 0, wx.ALL | wx.EXPAND, 5)
995                        cPanel.Show()
996                        break
997       
998        wPanelSizer.Layout()
999        wPanel.Refresh()
1000   
1001    def propertyStateChanged(self, event):
1002        property = event.getSource()
1003        component = property.getParent()
1004        wPanel = self.getCurrentPanel()
1005        cPanel = wPanel.FindWindowByName(component.getName())
1006        cPanelSizer = cPanel.GetSizer()
1007        #Component Panel sizer is a static box sizer. ACtual widgets are contained in a
1008        #gridbag sizer which in turn contained in this static box sizer
1009       
1010        cgsizer = cPanelSizer.GetChildren()[0].GetSizer()
1011        propWidgetsList = cgsizer.GetChildren()
1012       
1013        #propWidgetsList stores the list of labels and widgets of properties in SizerItem format.
1014        #Get the actual window from the SizerItem object before acting on the window
1015       
1016        #removing all the widgets contained in the sizer
1017        for prpWid in propWidgetsList:
1018            #prpWid is of type wx.SizerItem. Use GetWindow() to get the window tracked by this SizerItem
1019            actW = prpWid.GetWindow()
1020            if cgsizer.GetItem(actW) != None:
1021                cgsizer.Detach(actW)
1022                actW.Hide()
1023       
1024        prpList = component.getAllProperties()
1025        propWidgetsList = cPanel.GetChildren()
1026     
1027        #NOTE: The while loop inside the for loop iterates over the children of
1028        #the component panel. Since StaticBoxSizer is used to layout the properties,
1029        #the first child of the component panel (cPanel) will always be the StaticBox
1030        #object which should not be added to the gridbagsizer in addPropToCompSizer
1031        #method. Hence, iterating from 1 to length of the propWidgetsList.
1032        # (see the value of index )
1033       
1034        newPrpList = []
1035        index = 1
1036        for prp in prpList:
1037            if prp.isVisible():
1038                index = 1
1039                while ( index < (len(propWidgetsList)) ):
1040                    actW = propWidgetsList[index]
1041                   
1042                    if actW.GetName() == prp.getName():
1043                        newPrpList.append(actW)
1044                        actW.Show()
1045                    index = index + 1   
1046       
1047        newCgSizer = self.addPropToCompSizer(newPrpList)
1048        cPanelSizer.Remove(cgsizer)
1049        cPanelSizer.Add(newCgSizer, 1, wx.ALIGN_CENTER | wx.EXPAND, 10)
1050        cPanelSizer.Layout()
1051        wPanel.GetSizer().Layout()
1052                     
1053           
1054    def propertyWidgetChanged(self, event):
1055        property = event.getSource()
1056        compRef = property.getParent()
1057        wPanel = self.getCurrentPanel()
1058       
1059       
1060        # DO NOT CALL replaceComponentPanel() DIRECTLY FROM HERE AS IT INVOLVES
1061        # A CALL TO window.Destroy() METHOD. THIS METHOD IS STILL IN THE CONTEXT
1062        # OF EVENT HANDLER INVOKED AS A RESULT OF RIGHT CLICK ON PROPERTY WIDGET.
1063        # CALLING replaceComponentPanel() DIRECTLY FROM HERE WOULD **CRASH** THE
1064        # APPLICATION.
1065       
1066        wx.CallAfter(self.replaceComponentPanel, wPanel, compRef )
1067   
1068    def propertyRangeChanged(self, event):
1069        propertyCtrl = self.tempProp
1070        propRef = event.getSource()
1071        newMin, newMax = propRef.getRange()
1072        propertyCtrl.SetRange(newMin, newMax)
1073       
1074        #if GUI widget's current value is changed because new min, max values
1075        #we have to update the new value to the model as well.
1076        curWidVal = self.formatWidgetToModel(propertyCtrl.GetValue(), propRef.getType())
1077        preVal = propRef.getValue()
1078        if preVal == curWidVal:
1079            pass
1080        else:
1081            pName = propertyCtrl.GetName()
1082            cName = propertyCtrl.GetParent().GetName()
1083            wName = propertyCtrl.GetParent().GetParent().GetName()
1084       
1085            status = self.model.configure(wName, cName, pName, curWidVal)
1086            #leave the text box as it is if status is True
1087            #if the configure operation failed, revert the text value to the value stored in
1088            #the model.
1089            if status is False:
1090                msg = "Could not configure " + pName
1091                utils.showMessage(msg, utils.NON_FATAL)
1092                self.formatModelToWidget(propertyCtrl, preVal)
1093           
1094        return
1095#        if propertyCtrl.__class__ is wx.SpinCtrl:
1096#            propertyCtrl.SetRange(newMin, newMax)
1097#        if propertyCtrl.__class__ is wx.Slider:
1098#            propertyCtrl.SetMin(newMin)
1099#            propertyCtrl.SetMax(newMax)
1100   
1101    def FindMenuInMenuBar(self, title):
1102        pos = self.GetMenuBar().FindMenu(title)
1103        return self.GetMenuBar().GetMenu(pos)
1104   
1105    def getCurrentPanel(self):
1106        return self.notebook.GetCurrentPage()
1107   
1108    def replaceComponentPanel(self, wPanel, component):
1109       
1110#        Find the component to be replaced from the children list of current
1111#        active waveform panel. Replace the Old component panel in the waveform
1112#        panel's sizer with the compnent panel created new and then destroy the
1113#        old component panel
1114#       
1115        for button in self.configureButtons:
1116            if button.isComponentButton and button.getParentName() == component.getName():
1117                self.configureButtons.remove(button)
1118       
1119        oldCPanel = wPanel.FindWindowByName(component.getName())
1120        newCPanel = self.createComponentPanel(wPanel, component)
1121        wSizer = wPanel.GetSizer()         
1122        wSizer.Replace(oldCPanel, newCPanel)
1123     
1124        wSizer.Fit(wPanel)       
1125        wPanel.SetSizer(wSizer)
1126        wSizer.Layout()
1127        oldCPanel.Destroy()
1128       
1129    def OnRefresh(self, event):
1130        self.controller.refresh()
1131       
1132    def waveformRefresh(self, event):
1133        wformsTobeRemoved = event.getSource()
1134        wformMenu = self.FindMenuInMenuBar('Waveforms')
1135           
1136        for wformName in wformsTobeRemoved:
1137            wPanel = self.getWaveformPanel(wformName)
1138            self.wpanels.remove(wPanel)
1139            self.compPopupMenus.pop(wPanel)
1140            self.prpPopupMenus.pop(wPanel)
1141            wPanel.Destroy()
1142                   
1143            #update the menu display
1144            menuItems = wformMenu.GetMenuItems()
1145               
1146            #remove the selected waveform from the menu list
1147            for mItem in menuItems:
1148                if mItem.GetItemLabel() == wformName :
1149                    wformMenu.RemoveItem(mItem)
1150                    mItem.Destroy()
1151                    break
1152       
1153        for wPanel in self.wpanels:
1154            cPanelList = wPanel.GetChildren()
1155            wformRef = self.model.getWaveform(wPanel.GetName(), WaveformModel.INSTANCE_WAVEFORM)
1156            print wformRef
1157            for cPanel in cPanelList:
1158                compRef = wformRef.getComponent(cPanel.GetName())
1159                if compRef is not None:
1160                    prpList = compRef.getAllProperties()
1161                    prpWidgetList = cPanel.GetChildren()
1162               
1163                    for prpW in prpWidgetList:
1164                        if type(prpW) is wx.TextCtrl:
1165                            prpW.SetValue(str(compRef.findPropertyByName(prpW.GetName()).getValue()))
1166                        elif type(prpW) is wx.SpinCtrl:
1167                            prpW.SetValue(int(compRef.findPropertyByName(prpW.GetName()).getValue()))
1168                        elif type(prpW) is wx.Slider:
1169                            prpW.SetValue(int(compRef.findPropertyByName(prpW.GetName()).getValue()))
1170           
1171        if (self.model.getActiveWaveform() is None):
1172            nextActiveWform = None
1173            #make the first available waveform active
1174            menuItems = wformMenu.GetMenuItems()
1175            for mItem in menuItems:
1176                if mItem.IsCheckable():
1177                    mItem.Check()
1178                    nextActiveWform = mItem.GetItemLabel()
1179                    break
1180           
1181            #no running waveforms on the system
1182            if nextActiveWform is None:
1183                self.SetSize(OSSIE_WAVEAPP_DIMENSION)
1184                return
1185            self.model.setActiveWaveform(nextActiveWform)
1186                   
1187    def getWaveformPanel(self, wformName):
1188        for wPanel in self.wpanels:
1189            if (wformName == wPanel.GetName()):
1190                return wPanel
1191               
1192     
1193    def OnOpenLayout(self, event):
1194        pass
1195    def OnSaveLayout(self, event):
1196        self.model.waveformToXML()
1197        pass
1198    def OnSaveLayoutAs(self, event):
1199        pass
1200    def OnClose(self, event):
1201        if self.controller.nodeBooterProcess != None:
1202            dlg = wx.MessageDialog(self,
1203                                   "NodeBooter was started by WaveDash.\n" +
1204                                   "Would you like to terminate it?",
1205                                   "Confirm NodeBooter Termination", wx.YES | wx.NO | wx.ICON_QUESTION)
1206            result = dlg.ShowModal()
1207            if result == wx.ID_YES:
1208                print "Terminating nodeBooter"
1209                self.controller.nodeBooterProcess.terminate()
1210        self.Destroy()
1211
1212    def OnWidgetSettings(self, event):
1213        pass
1214    def OnAbout(self, event):
1215        dlg = wx.MessageDialog(self, "WaveDash\nPart of the OSSIE Toolset",
1216                               "About WaveDash")
1217        dlg.ShowModal()
1218       
1219    def OnUpdateOnRefreshCheck(self, event):
1220        for button in self.configureButtons:
1221            button.Enable(self.updateOnRefresh.IsChecked())
1222           
1223    def OpenPreferences(self, event):
1224        PreferencePage = WavedashPreferencePage(self, self.controller)
1225        PreferencePage.Show()
1226           
1227    def OnUpdateComponentClicked(self, event):
1228        src = event.GetEventObject()
1229        compName = src.GetParent().GetName()
1230        wName = src.GetParent().GetParent().GetName()
1231        self.updateComponent(compName, wName)
1232       
1233    def OnUpdateWaveformClicked(self, event):
1234        src = event.GetEventObject()
1235        wName = src.GetParent().GetName()
1236        self.updateWaveform(wName)
1237       
1238    def OnPlotPort(self, event):
1239        src = event.GetEventObject()
1240        compName = src.GetParent().GetName()
1241        waveformName = src.GetParent().GetParent().GetName()
1242        waveform = self.model.getWaveform(waveformName, WaveformModel.INSTANCE_WAVEFORM)
1243        component = waveform.getComponent(compName)
1244        port = component.getPort(src.GetLabelText())
1245        if port:
1246            context = ("DomainName1", str('OSSIE::' + waveformName), str(compName))
1247            frame = plot.create(self, port.interface.nameSpace , port.interface.name, context , port.name)
1248   
1249    def openTool(self, event):
1250        src = event.GetEventObject()
1251        toolName = src.GetValue()
1252        if toolName == 'Available Tools':
1253            return
1254        compName = src.GetParent().GetName()
1255        waveformName = src.GetParent().GetParent().GetName()
1256        waveform = self.model.getWaveform(waveformName, WaveformModel.INSTANCE_WAVEFORM)
1257        component = waveform.getComponent(compName)
1258        port = src.port
1259        for t in src.supportedTools:
1260            if t.name == toolName:
1261                tool = t
1262                break
1263           
1264        if tool.module == None:
1265            # NOTE: alf_plugins is now the package that contains all tools
1266            exec_string = "from alf_plugins." + tool.packagename + " import "
1267            exec_string += tool.modulename + " as tool_module"
1268            exec exec_string
1269
1270            tool.module = tool_module
1271        else:
1272            tool_module = tool.module
1273            reload(tool_module)
1274           
1275        if port:
1276            context = ("DomainName1", str('OSSIE::' + waveformName), str(compName))
1277            try:
1278                newframe = tool_module.create(self, str(port.interface.nameSpace),
1279                                          str(port.interface.name), context, str(port.name))
1280                newframe.Show(True)
1281                src.SetValue('Available Tools')
1282            except Exception as val:
1283                print val
1284                msg = "Exception caught launching " + toolName + "\n" + str(val)
1285                utils.showMessage(msg, utils.NON_FATAL)
1286       
1287    def updateWaveform(self, waveformName):
1288        wform = self.model.getWaveform(waveformName, WaveformModel.INSTANCE_WAVEFORM)
1289        for component in wform.getAllComponents():
1290            self.updateComponent(component.getName(), wform.getName())
1291               
1292    def updateComponent(self, componentName, waveformName):
1293        wform = self.model.getWaveform(waveformName, WaveformModel.INSTANCE_WAVEFORM)
1294        compRef = wform.getComponent(componentName)
1295        for property in compRef.getAllProperties():
1296            curVal = self.formatWidgetToModel(property.getWindow().GetValue(), property.getType())
1297            preVal = property.getValue()
1298         
1299   
1300            if curVal is not None:
1301           
1302            #if both the values are equal then no need to call configure()
1303                if preVal == curVal:
1304                    pass
1305                else:
1306                    status = self.model.configure(waveformName, componentName, property.getName(), curVal)
1307                    #leave the text box as it is if status is True
1308                    #if the configure operation failed, revert the text value to the value stored in
1309                    #the model.
1310                    if status is False:
1311                        msg = "Could not configure " + property.getName()
1312                        utils.showMessage(msg, utils.NON_FATAL)
1313                        self.formatModelToWidget(property.getWindow(), preVal)
1314                        #src.SetValue(str(preVal))
1315                    elif property.type[1] == "boolean":
1316                        self.formatModelToWidget(property.getWindow(), curVal)
1317               
1318            else:
1319                msg = "Invalid value for %s/%s" % (componentName, property.getName()) + "\nEnter only '" + property.getType()[1] + "' values"
1320                msg = msg + "\nFor sequence types, enter values separated by comma"
1321                msg = msg + " and enclosed within [] e.g. [10,20,30]"
1322           
1323                utils.showMessage(msg, utils.NON_FATAL)
1324                self.formatModelToWidget(property.getWindow(), preVal)     
1325                self.Layout()
1326           
1327    def getRoot(self):
1328        root = __file__
1329        if os.path.islink (root):
1330            root = os.path.realpath (root)
1331        root = os.path.dirname (os.path.abspath (root))
1332        return root
1333
1334def main():
1335    app = wx.App()
1336    ctrlr = Controller()
1337    ctrlr.createWidgetContainer()
1338   
1339    frame = WavedashView(ctrlr, ctrlr.model)
1340
1341    ctrlr.CORBAutils.init_CORBA()
1342    ctrlr.buildModel()
1343
1344    app.MainLoop()
1345       
1346if __name__ == '__main__':
1347    main()
1348
1349   
Note: See TracBrowser for help on using the browser.