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

Revision 10905, 56.6 KB (checked in by Snyder.Jason, 20 months ago)

added support for alf tools to wavedash

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 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 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.port = port
385                portToolCombo.supportedTools = availableTools
386                panel.Bind(wx.EVT_COMBOBOX, self.openTool, portToolCombo)
387            else:
388                portToolCombo = wx.ComboBox(panel, wx.NewId(), value='No Available Tools', choices=toolList, style=wx.CB_READONLY)
389               
390            portsBoxSizer.Add(portLabel)
391            portsBoxSizer.Add(portToolCombo)
392        return portsBoxSizer
393       
394       
395    def addPropToCompSizer(self, propList):
396        #IMPORTANT NOTE: proplist should have items in the following way.
397        #[label, window, label, window, label, window, .... ]
398        index = 0
399        gridSizer = wx.GridSizer(2,4,5,5)
400       
401        while (index < len(propList) ):
402            plabel = propList[index]
403            pWindow = propList[index+1]
404           
405            #if the windows are hidden, don't add them to the sizer.
406            #They will be added when the user select the properties again.
407            if (not plabel.IsShown()) or (not pWindow.IsShown()):
408                index = index + 2
409                continue
410            gridSizer.Add(plabel, 0)
411            gridSizer.Add(pWindow, 0)
412            index = index + 2
413        return gridSizer
414     
415    def attachPopupToComponent(self, component, cPanel):
416        cPopup = wx.Menu(title='')
417        moveUp = cPopup.Append(wx.NewId(), 'Move up')
418        moveDown = cPopup.Append(wx.NewId(), 'Move Down')
419        save = cPopup.Append(wx.NewId(), 'Save')
420        saveAs = cPopup.Append(wx.NewId(), 'Save As')
421       
422        #save and saveAs will be implemented in next release.disable for now
423        save.Enable(False)
424        saveAs.Enable(False)
425       
426        prpMenu = wx.Menu()
427        #All properties are enabled by default.
428        prpList = component.getAllProperties()
429        for prp in prpList:
430            chkMenuItem = prpMenu.AppendCheckItem(wx.NewId(), prp.getName())
431            chkMenuItem.Check(True)
432            self.Bind(wx.EVT_MENU, self.OnPropertySelect, chkMenuItem)
433           
434        cPopup.AppendMenu(wx.NewId(), 'Properties', prpMenu)
435       
436        wPanel = cPanel.GetParent()
437       
438        if self.compPopupMenus.has_key(wPanel):
439            cPanelDict = self.compPopupMenus[wPanel]
440            if cPanelDict.has_key(cPanel.GetName()) is False:
441                cPanelDict[str(cPanel.GetName())] = cPopup
442        else:
443            self.compPopupMenus[wPanel] = {cPanel.GetName():cPopup}
444       
445        self.Bind(wx.EVT_MENU, self.OnComponentMoveUp, moveUp)
446        self.Bind(wx.EVT_MENU, self.OnComponentMoveDown, moveDown)
447       
448        cPanel.Bind(wx.EVT_RIGHT_DOWN, self.OnComponentRightClick)
449       
450   
451    def OnComponentRightClick(self, event):
452        src = event.GetEventObject()
453        curWPanel = self.getCurrentPanel()
454        #Storing the reference to current component panel in a temp variable
455        #This temp will be used to map the context menu and the component menu in
456        #the event handler for PropertySelect and other items in Context menu also.
457       
458        self.tempComp = src
459        for wpanel in self.compPopupMenus.keys():
460            if wpanel is curWPanel:
461                windowDict = self.compPopupMenus[wpanel]
462                src.PopupMenu(windowDict[str(src.GetName())])
463   
464    def attachPopupMenuToProp(self, wPanel, window, property):
465        pSubMenu = wx.Menu(title='')
466        #default = property.getWidget()
467        default = self.controller.getDefaultWidget(property.getType())
468        optList = self.controller.getOptionalWidgets(property.getType())
469       
470        mItem = pSubMenu.AppendRadioItem(wx.NewId(), default.type)
471        self.Bind(wx.EVT_MENU, self.PropPopupHandler, id = mItem.GetId())
472        for optWidget in optList:
473            mItem = pSubMenu.AppendRadioItem(wx.NewId(), optWidget.type)
474            self.Bind(wx.EVT_MENU, self.PropPopupHandler, id = mItem.GetId())
475            if property.getWidget().type == optWidget.type:
476                mItem.Check(True)
477           
478        pSubMenu.AppendSeparator()
479        configure = pSubMenu.Append(wx.NewId(), 'Configure')
480        self.Bind(wx.EVT_MENU, self.PropConfigureHandler, id = configure.GetId())
481       
482        #Configure shuold be enabled only for slider and spin buttons.
483        #If other options are enabled, then disable the Configure Menu Item
484        self.propPopUpUpdate(pSubMenu)
485       
486        chgMenu = wx.Menu(title='')
487        chgMenuItem = wx.MenuItem(chgMenu, wx.NewId(), 'Change To', subMenu = pSubMenu)
488        chgMenu.AppendItem(chgMenuItem)
489       
490        #Associate the pop Menu with the window
491        cpRef = property.getParent().getName() + '/' + property.getName()
492       
493        if self.prpPopupMenus.has_key(wPanel):
494            subDict = self.prpPopupMenus[wPanel]
495            if subDict.has_key(cpRef) is False:
496                subDict[cpRef] = chgMenu
497        else:
498            self.prpPopupMenus[wPanel] = {cpRef:chgMenu}
499       
500        window.Bind(wx.EVT_RIGHT_DOWN, self.OnPropRightClick)
501       
502    def OnPropRightClick(self, event):
503        src = event.GetEventObject()
504        curPanel = self.getCurrentPanel()
505        #The widget(actual wxPython windows) on which the Popupmenu is invoked is
506        #stored in a temp variable to access it later during the events generated
507        #by PopUpMenu
508       
509        self.tempProp = src
510        for wpanel in self.prpPopupMenus.keys():
511            if wpanel is curPanel:
512 
513        #===============================================================================
514        #  A pop-up menu is associated with each property. the member variable prpPopupMenus
515        #  is a hash object indexed by waveform names. Value of a hash object points to another
516        #  hash which indexes the popup menus by component_name/property_name.
517        #===============================================================================
518
519                windowDict = self.prpPopupMenus[wpanel]
520                cpRef = src.GetParent().GetName() + '/' + src.GetName()
521                src.GetParent().PopupMenu(windowDict[cpRef])
522           
523   
524    def PropPopupHandler(self, event):
525        srcId = event.GetId()
526        mItems = event.GetEventObject().GetMenuItems()
527       
528        #Enable the configure option only slider and spin box to set their min and
529        #max values.
530       
531        self.propPopUpUpdate(event.GetEventObject())
532       
533        for mItem in mItems:
534            if mItem.GetId() == srcId:       
535                #self.tempProp is set to identify the property when Popupmenu is invoked.   
536                property = self.tempProp
537                component = property.GetParent()
538                wform = component.GetParent()
539                wformRef = self.model.getActiveWaveform()
540                compRef = wformRef.getComponent(component.GetName())
541                propRef = compRef.findPropertyByName(property.GetName())
542                self.model.changePropertyWidget(component.GetName(),
543                                                property.GetName(), mItem.GetItemLabel())
544               
545
546    def PropConfigureHandler(self, event):
547        propertyCtrl = self.tempProp
548        cPanel = propertyCtrl.GetParent()
549        wPanel = cPanel.GetParent()
550       
551        #Get reference to the property thruogh its compnent and waveform.
552        #Then, get the widget reference from the property
553        wform = self.model.getActiveWaveform()
554        component = wform.getComponent(cPanel.GetName())
555        property = component.findPropertyByName(propertyCtrl.GetName())
556       
557        widget = property.getWidget()
558       
559        if propertyCtrl.__class__ is wx.SpinCtrl \
560            or propertyCtrl.__class__ is wx.Slider:
561            curMin, curMax = property.getRange()
562            curValue = property.getValue()
563            #curMin = widget.getMin()
564            #curMax = widget.getMax()
565            title = 'Widget Configuration'
566            confDialog = utils.ConfigureWidget(self, title, curValue)
567            confDialog.setMin(curMin)
568            confDialog.setMax(curMax)
569           
570            confDialog.ShowModal()
571           
572            #Get the new min and max once the dialog is destroyed in the
573            #event handlers of Ok and Cancel defined in ConfigureWidget
574            newMin = confDialog.getMin()
575            newMax = confDialog.getMax()
576                       
577            #No need to udpate the model if the values are not changed
578            if (newMin == curMin) and (newMax == curMax):
579                return
580            else:
581                # the newMin and newMax values will be updated to the range attribute of the property
582                status = self.model.configurePropertyWidget(cPanel.GetName(), propertyCtrl.GetName(), newMin, newMax)
583                if status is False:
584                    utils.showMessage("Invalid range of values (" + str(newMin) + "," + str(newMax) + ")" , utils.NON_FATAL)
585                return
586   
587    def propPopUpUpdate(self, menu):     
588        menuItems = menu.GetMenuItems()
589        confItemId = menu.FindItem('Configure')
590        confItem = menu.FindItemById(confItemId)
591        confItem.Enable(False)
592       
593        for mItem in menuItems:
594            if mItem.GetItemLabel() == "spin" or mItem.GetItemLabel() == "slider":
595                if mItem.IsChecked():
596                    confItem.Enable(True)
597       
598    def mapWidgetToWindow(self, parent, property, widget):
599        window = None
600        label = None
601        pValue = property.getValue()
602
603        widgetType = widget.type
604       
605        if widgetType == "text":                   
606            window = wx.TextCtrl(parent, -1, str(pValue), style = wx.TE_PROCESS_ENTER)
607        elif widgetType == "spin":
608            minV, maxV = property.getRange()
609            window = wx.SpinCtrl(parent, -1, str(pValue), min = minV, max = maxV, style = wx.TE_PROCESS_ENTER)
610        elif widgetType == "slider":
611            minV, maxV = property.getRange()
612            if widget.parameters["style"] == "HORIZONTAL":
613                styleV = wx.SL_HORIZONTAL | wx.SL_LABELS
614            elif widget.parameters["style"] == "VERTICAL":
615                styleV = wx.SL_VERTICAL | wx.SL_LABELS
616            window = wx.Slider(parent, -1, int(pValue), minValue = minV, maxValue = maxV, style = styleV, size=(120,35))
617        elif widgetType == "checkbox":
618            window = wx.CheckBox(parent, -1, property.getName())
619        elif widgetType == "listbox":
620            if (pValue is not None) and (type(pValue) is list):
621                window = wx.TextCtrl(parent, -1, str(pValue))
622            else:
623                window = wx.TextCtrl(parent, -1, str(None))
624        else:
625            window = wx.TextCtrl(parent, -1, str(pValue))
626       
627        if window is not None:
628            window.SetName(property.getName())   
629        return window
630   
631    def OnPropValueChanged(self, event):
632        if(self.updateOnRefresh.IsChecked()):
633            return
634        src = event.GetEventObject()
635        prp = src.GetName()
636        comp = src.GetParent().GetName()
637        wName = src.GetParent().GetParent().GetName()
638        wform = self.model.getWaveform(wName, WaveformModel.INSTANCE_WAVEFORM)
639        #This event is triggered whenever a property widget loses its focus.
640        #A widget loses its focus when the user switch to another widget in the same window
641        #or select a different waveform.
642        if wform is None:
643            #if event triggered as a result of object destroy or from Waveform Preview Dialog
644            #then no need to update the value. Just return
645            return
646       
647        compRef = wform.getComponent(comp)
648        prpRef = compRef.findPropertyByName(prp)
649       
650        curVal = self.formatWidgetToModel(src.GetValue(), prpRef.getType())
651        preVal = prpRef.getValue()
652       
653
654        if curVal is not None:
655           
656            #if both the values are equal then no need to call configure()
657            if preVal == curVal:
658                #in cases where a boolean property was changed to a different
659                #text value but the same boolean value (ie True changed to 1)
660                #the model won't configure since the actual value didnt change
661                #so we have to call formatModelToWidget to change the text back
662                # to True or False
663                if(prpRef.type[1] == "boolean"):
664                    self.formatModelToWidget(src, curVal)
665                return
666            else:
667                #print "configuring: wName = " + str(wName) + ", comp = " + str(comp) + ", prp = " + str(prp) + ", curVal = " + str(curVal)
668                status = self.model.configure(wName, comp, prp, curVal)
669
670                #leave the text box as it is if status is True
671                #if the configure operation failed, revert the text value to the value stored in
672                #the model.
673                if status is False:
674                    msg = "Could not configure " + prp
675                    utils.showMessage(msg, utils.NON_FATAL)
676                    self.formatModelToWidget(src, preVal)
677                    #src.SetValue(str(preVal))
678                elif prpRef.type[1] == "boolean":
679                    self.formatModelToWidget(src, curVal)
680               
681        else:
682            msg = "Invalid value for %s/%s" % (comp, prp) + "\nEnter only '" + prpRef.getType()[1] + "' values"
683            msg = msg + "\nFor sequence types, enter values separated by comma"
684            msg = msg + " and enclosed within [] e.g. [10,20,30]"
685           
686            utils.showMessage(msg, utils.NON_FATAL)
687            self.formatModelToWidget(src, preVal)     
688            self.Layout()   
689           
690   
691    def formatModelToWidget(self, widget, value):
692        if widget.__class__ is wx.TextCtrl:
693            widget.SetValue(str(value))
694        elif widget.__class__ is wx.SpinCtrl:           
695            widget.SetValue(int(value))
696        elif widget.__class__ is wx.Slider:
697            widget.SetValue(int(value))
698        elif widget.__class__ is wx.CheckBox:
699            if value == "True" or value == 1:
700                widget.SetValue(True)
701            else:
702                widget.SetValue(False)
703       
704               
705         
706    def formatWidgetToModel(self, curVal, propType):
707        """ Converts the string literal into the suitable data type
708        as configured for the property"""
709        val = None
710        #propType is a tuple containing the (xmlType,datatype)
711        #e.g. ('simple','short')
712        xmlType = propType[0]
713        dtype = propType[1]
714
715        try:
716            if (xmlType == "simple"):
717                if dtype == "short" or dtype == "ushort":
718                    val = int(curVal)
719                elif dtype == "int" or dtype == "uint":
720                    val = int(curVal)
721                elif dtype == "long" or dtype == "ulong":
722                    val = long(curVal)
723                elif dtype == "double" or dtype == "float":
724                    val = float(curVal)
725                elif dtype == "char":
726                    val = str(curVal)
727                elif dtype == "boolean":
728                    if str(curVal).lower() in self.trueValues:
729                        val = True
730                    else:
731                        val = False
732                elif dtype == "string":
733                    val = str(curVal)
734                else:
735                    val = None
736            #sequence values are represented as list of values separated
737            #by a comma. e.g. '[10,20,30]'
738           
739            elif (xmlType == "simplesequence"):
740                if dtype == "float":
741                    val = []
742                    #strip the open and close bracket
743                    listVal = curVal.lstrip('[')
744                    listVal = listVal.rstrip(']')
745                    for lVal in listVal.split(','):
746                        val.append(float(lVal))
747                if dtype == "string":
748                    val = []
749                    #strip the open and close bracket
750                    listVal = curVal.lstrip('[')
751                    listVal = listVal.rstrip(']')
752                    for lVal in listVal.split(','):
753                        val.append(str(lVal))
754                if dtype == "short" or dtype == "int":
755                    val = []
756                    #strip the open and close bracket
757                    listVal = curVal.lstrip('[')
758                    listVal = listVal.rstrip(']')
759                    for lVal in listVal.split(','):
760                        val.append(int(lVal))
761                   
762        except(ValueError):
763            val = None
764       
765        return val
766       
767    def AddToWaveformsMenu(self, newWaveform, type):
768        wMenu = self.FindMenuInMenuBar('Waveforms')
769       
770        if type == WaveformModel.SYSTEM_WAVEFORM:
771            wSubMenu = wx.Menu()
772            install = wSubMenu.Append(-1, 'Install')
773            installAndStart = wSubMenu.Append(-1, 'Install and Start')
774            viewWform = wSubMenu.Append(-1, 'Preview')
775            properties = wSubMenu.Append(-1, 'Properties')
776           
777            wMenu.InsertMenu(0,-1, newWaveform, wSubMenu) #insert at the start of the list
778           
779            self.Bind(wx.EVT_MENU, self.OnWaveformInstall, install)
780            self.Bind(wx.EVT_MENU, self.OnWaveformInstallAndStart, installAndStart)
781            self.Bind(wx.EVT_MENU, self.OnWaveformPreview, viewWform)
782            self.Bind(wx.EVT_MENU, self.OnWaveformProperties, properties)
783               
784    def AddToComponentsMenu(self, newComponent, isVisible):
785        cMenu = self.FindMenuInMenuBar('Components')
786        citem = cMenu.AppendCheckItem(-1, newComponent)
787        self.Bind(wx.EVT_MENU, self.OnComponentMenuClick, citem)
788       
789        if isVisible:
790            citem.Check(True)
791   
792    def OnWaveformInstall(self, event):
793        chosenMenu = event.GetEventObject()
794        parent = chosenMenu.GetParent()
795       
796        for mItem in parent.GetMenuItems():
797            if mItem.GetSubMenu() is chosenMenu:
798                self.controller.installWaveform(mItem.GetItemLabel(), False)
799                break
800   
801    def OnWaveformInstallAndStart(self, event):
802        chosenMenu = event.GetEventObject()
803        parent = chosenMenu.GetParent()
804       
805        for mItem in parent.GetMenuItems():
806            if mItem.GetSubMenu() is chosenMenu:
807                self.controller.installWaveform(mItem.GetItemLabel(), True)
808                break
809   
810    def OnPropertySelect(self, event):
811        srcId = event.GetId()
812        pMenu = event.GetEventObject()
813        mItemList = pMenu.GetMenuItems()
814        for mItem in mItemList:
815            if srcId == mItem.GetId():
816                propName = mItem.GetItemLabel()
817                #self.tempComp has the reference to the component panel on which
818                #the context menu is invoked in ComponentRightClick Handler
819                compName = self.tempComp.GetName()
820                self.model.updatePropertyState(compName, propName, mItem.IsChecked())
821                break
822   
823    def OnComponentMoveUp(self, event):       
824        compName = self.tempComp.GetName()
825        wformName = self.tempComp.GetParent().GetName()
826        self.model.moveComponentUp(wformName, compName)
827   
828    def OnComponentMoveDown(self, event):
829        compName = self.tempComp.GetName()
830        wformName = self.tempComp.GetParent().GetName()
831        self.model.moveComponentDown(wformName, compName)
832           
833   
834    def OnWaveformPreview(self, event):
835        chosenMenu = event.GetEventObject()
836        parent = chosenMenu.GetParent()
837       
838        for mItem in parent.GetMenuItems():
839            if mItem.GetSubMenu() is chosenMenu:
840                wformName = mItem.GetItemLabel()
841                waveform = self.model.getWaveform(wformName, WaveformModel.SYSTEM_WAVEFORM)
842                title = 'Preview - ' + wformName
843               
844                previewFrame = wx.Frame(self, -1, title, OSSIE_WAVEAPP_DIMENSION)
845                wPanel = self.createWaveformPanel(previewFrame, waveform, preview = True)
846                wPanel.Show()
847                previewFrame.Show()
848                break
849   
850    def OnWaveformProperties(self, event):
851        chosenMenu = event.GetEventObject()
852        parent = chosenMenu.GetParent()
853       
854        for mItem in parent.GetMenuItems():
855            if mItem.GetSubMenu() is chosenMenu:
856                wformName = mItem.GetItemLabel()
857                wformObj = self.model.getWaveform(wformName, WaveformModel.SYSTEM_WAVEFORM)
858                print str(wformObj)
859                title = wformName + " - Properties"
860                wformProperties = str(wformObj)
861                dlg = wx.MessageDialog(None, wformProperties, title, wx.OK | wx.ICON_INFORMATION)
862                try:
863                    dlg.ShowModal()
864                finally:
865                    dlg.Destroy()
866   
867    #Event Handler for page change. Update the active waveform on each page change
868    def OnNbPageChange(self, event):
869        pageId = event.GetSelection()
870        #GetPage() returns the reference to waveform panel object
871        wPanel = self.notebook.GetPage(pageId)
872        #update active waveform in the model
873        self.model.setActiveWaveform(wPanel.GetName())
874   
875    def OnComponentMenuClick(self, event):
876        cMenu = event.GetEventObject()
877        mItemList = cMenu.GetMenuItems()
878        for mItem in mItemList:
879            self.model.updateComponentState(mItem.GetItemLabel(), mItem.IsChecked())
880       
881    def UpdateComponentMenu(self, wform):
882       
883        componentList = wform.getAllComponents()
884        compMenu = self.FindMenuInMenuBar('Components')
885        #clear the existing items in Component Menu
886        for mItem in compMenu.GetMenuItems():
887            compMenu.DeleteItem(mItem)
888           
889        #Now update the component Menu wit the components of currently selected waveform
890        for component in componentList:
891            self.AddToComponentsMenu(component.getName(), component.isVisible())
892       
893    #listeners of WaveformListener interface
894    def waveformAdded(self, event):
895        wform = event.getSource()
896        #if(wform.name == "w1"):
897         #   print "in waveform Added"
898          #  for comp in wform.components:
899           #     for prop in comp.properties:
900                #        print str(prop.id) + ": "  + str(prop.getValue())
901                   
902                   
903       
904        #create the panel only if it is a instance waveform.
905        #For system waveform, just add it to the menu
906        wType = wform.getType()
907        if wType == WaveformModel.INSTANCE_WAVEFORM:
908            wPanel = self.createWaveformPanel(self.notebook, wform)
909            self.notebook.AddPage(wPanel, wform.getName())
910           
911        self.AddToWaveformsMenu(wform.getName(), wType)
912   
913    def waveformRemoved(self, event):
914       
915        srcWform = event.getSource()
916        #if waveform removed is a SYSTEM_WAVEFORM, i.e. the one found in /sdr/dom/waveforms,
917        #remove the waveform from the Waveforms Menu
918        if srcWform is not None and srcWform.getType() == WaveformModel.SYSTEM_WAVEFORM:
919            wformsMenu = self.FindMenuInMenuBar('Waveforms')
920            menuItems = wformsMenu.GetMenuItems()
921            for mItem in menuItems:
922                if mItem.GetItemLabel() == srcWform.getName():
923                    wformsMenu.DeleteItem(mItem)
924                    break
925            return
926     
927        curPanelId = self.notebook.GetSelection()
928        curPanel = self.notebook.GetCurrentPage()
929        wformName = curPanel.GetName()
930        self.wpanels.remove(curPanel)
931        #remove the panel from the notebook
932        self.notebook.RemovePage(curPanelId)
933        #destroy the waveform panel object
934        curPanel.Destroy()
935       
936        msg = ("%s Uninstalled !" % wformName)
937        utils.showMessage(msg, utils.INFO)
938       
939        #AdvanceSelection() sets the next available page active
940        #and trigger EVT_NOTEBOOK_PAGE_CHANGED event. The event
941        #handler OnNbPageChange() would be called that sets the
942        #active waveform thruogh model.SetActiveWaveform()
943       
944        self.notebook.AdvanceSelection(True)
945       
946        #if no running waveforms on the system?
947        if self.notebook.GetPageCount() == 0:
948            compMenu = self.FindMenuInMenuBar('Components')
949            #clear the existing items in Component Menu
950            for mItem in compMenu.GetMenuItems():
951                compMenu.DeleteItem(mItem)
952            self.model.setActiveWaveform(None)
953            self.SetSize(OSSIE_WAVEAPP_DIMENSION)
954        #notebook.AdvanceSelection() will not trigger PAGE_CHANGED event if there is
955        #only one panel left. Hence, set the active form explicitly.
956        elif self.notebook.GetPageCount() == 1:
957            nextActiveWform = self.notebook.GetCurrentPage().GetName()
958            self.model.setActiveWaveform(nextActiveWform)
959       
960    def waveformSelected(self, event):
961        wform = event.getSource()
962        #If no waveform is there, just update the title and status Bar and return
963        if wform is None:
964            self.SetTitle(OSSIE_TITLE)
965            #self.updateStatusBar()
966            return   
967        self.SetTitle(OSSIE_TITLE + ' (' + wform.getName() + ')')
968        #Component menu needs to be updated per waveform basis.       
969        self.UpdateComponentMenu(wform)
970        self.Layout()
971       
972    def componentStateChanged(self, cEvent):
973        """ A listener method of ComponentListener class that is triggerred
974        whenever a component is selected/deselected in the Component Menu"""
975
976        wPanel = self.getCurrentPanel()
977        cPanelList = wPanel.GetChildren()
978        wPanelSizer = wPanel.GetSizer()     
979        componentList = self.model.getActiveWaveform().getAllComponents()
980       
981        #Detach all the existing panels from the sizer
982        for cPanel in cPanelList:
983            if wPanelSizer.GetItem(cPanel) != None:
984                wPanelSizer.Detach(cPanel)
985                cPanel.Hide()
986       
987        #Update the sizer to be inline with the order of components in Waveform Model
988        for cmp in componentList:
989            if cmp.isVisible():
990                #print cmp.getPosition()
991                for cPanel in cPanelList:
992                    if cPanel.GetName() == cmp.getName():
993                        wPanelSizer.Add(cPanel, 0, wx.ALL | wx.EXPAND, 5)
994                        cPanel.Show()
995                        break
996       
997        wPanelSizer.Layout()
998        wPanel.Refresh()
999   
1000    def propertyStateChanged(self, event):
1001        property = event.getSource()
1002        component = property.getParent()
1003        wPanel = self.getCurrentPanel()
1004        cPanel = wPanel.FindWindowByName(component.getName())
1005        cPanelSizer = cPanel.GetSizer()
1006        #Component Panel sizer is a static box sizer. ACtual widgets are contained in a
1007        #gridbag sizer which in turn contained in this static box sizer
1008       
1009        cgsizer = cPanelSizer.GetChildren()[0].GetSizer()
1010        propWidgetsList = cgsizer.GetChildren()
1011       
1012        #propWidgetsList stores the list of labels and widgets of properties in SizerItem format.
1013        #Get the actual window from the SizerItem object before acting on the window
1014       
1015        #removing all the widgets contained in the sizer
1016        for prpWid in propWidgetsList:
1017            #prpWid is of type wx.SizerItem. Use GetWindow() to get the window tracked by this SizerItem
1018            actW = prpWid.GetWindow()
1019            if cgsizer.GetItem(actW) != None:
1020                cgsizer.Detach(actW)
1021                actW.Hide()
1022       
1023        prpList = component.getAllProperties()
1024        propWidgetsList = cPanel.GetChildren()
1025     
1026        #NOTE: The while loop inside the for loop iterates over the children of
1027        #the component panel. Since StaticBoxSizer is used to layout the properties,
1028        #the first child of the component panel (cPanel) will always be the StaticBox
1029        #object which should not be added to the gridbagsizer in addPropToCompSizer
1030        #method. Hence, iterating from 1 to length of the propWidgetsList.
1031        # (see the value of index )
1032       
1033        newPrpList = []
1034        index = 1
1035        for prp in prpList:
1036            if prp.isVisible():
1037                index = 1
1038                while ( index < (len(propWidgetsList)) ):
1039                    actW = propWidgetsList[index]
1040                   
1041                    if actW.GetName() == prp.getName():
1042                        newPrpList.append(actW)
1043                        actW.Show()
1044                    index = index + 1   
1045       
1046        newCgSizer = self.addPropToCompSizer(newPrpList)
1047        cPanelSizer.Remove(cgsizer)
1048        cPanelSizer.Add(newCgSizer, 1, wx.ALIGN_CENTER | wx.EXPAND, 10)
1049        cPanelSizer.Layout()
1050        wPanel.GetSizer().Layout()
1051                     
1052           
1053    def propertyWidgetChanged(self, event):
1054        property = event.getSource()
1055        compRef = property.getParent()
1056        wPanel = self.getCurrentPanel()
1057       
1058       
1059        # DO NOT CALL replaceComponentPanel() DIRECTLY FROM HERE AS IT INVOLVES
1060        # A CALL TO window.Destroy() METHOD. THIS METHOD IS STILL IN THE CONTEXT
1061        # OF EVENT HANDLER INVOKED AS A RESULT OF RIGHT CLICK ON PROPERTY WIDGET.
1062        # CALLING replaceComponentPanel() DIRECTLY FROM HERE WOULD **CRASH** THE
1063        # APPLICATION.
1064       
1065        wx.CallAfter(self.replaceComponentPanel, wPanel, compRef )
1066   
1067    def propertyRangeChanged(self, event):
1068        propertyCtrl = self.tempProp
1069        propRef = event.getSource()
1070        newMin, newMax = propRef.getRange()
1071        propertyCtrl.SetRange(newMin, newMax)
1072       
1073        #if GUI widget's current value is changed because new min, max values
1074        #we have to update the new value to the model as well.
1075        curWidVal = self.formatWidgetToModel(propertyCtrl.GetValue(), propRef.getType())
1076        preVal = propRef.getValue()
1077        if preVal == curWidVal:
1078            pass
1079        else:
1080            pName = propertyCtrl.GetName()
1081            cName = propertyCtrl.GetParent().GetName()
1082            wName = propertyCtrl.GetParent().GetParent().GetName()
1083       
1084            status = self.model.configure(wName, cName, pName, curWidVal)
1085            #leave the text box as it is if status is True
1086            #if the configure operation failed, revert the text value to the value stored in
1087            #the model.
1088            if status is False:
1089                msg = "Could not configure " + pName
1090                utils.showMessage(msg, utils.NON_FATAL)
1091                self.formatModelToWidget(propertyCtrl, preVal)
1092           
1093        return
1094#        if propertyCtrl.__class__ is wx.SpinCtrl:
1095#            propertyCtrl.SetRange(newMin, newMax)
1096#        if propertyCtrl.__class__ is wx.Slider:
1097#            propertyCtrl.SetMin(newMin)
1098#            propertyCtrl.SetMax(newMax)
1099   
1100    def FindMenuInMenuBar(self, title):
1101        pos = self.GetMenuBar().FindMenu(title)
1102        return self.GetMenuBar().GetMenu(pos)
1103   
1104    def getCurrentPanel(self):
1105        return self.notebook.GetCurrentPage()
1106   
1107    def replaceComponentPanel(self, wPanel, component):
1108       
1109#        Find the component to be replaced from the children list of current
1110#        active waveform panel. Replace the Old component panel in the waveform
1111#        panel's sizer with the compnent panel created new and then destroy the
1112#        old component panel
1113#       
1114        for button in self.configureButtons:
1115            if button.isComponentButton and button.getParentName() == component.getName():
1116                self.configureButtons.remove(button)
1117       
1118        oldCPanel = wPanel.FindWindowByName(component.getName())
1119        newCPanel = self.createComponentPanel(wPanel, component)
1120        wSizer = wPanel.GetSizer()         
1121        wSizer.Replace(oldCPanel, newCPanel)
1122     
1123        wSizer.Fit(wPanel)       
1124        wPanel.SetSizer(wSizer)
1125        wSizer.Layout()
1126        oldCPanel.Destroy()
1127       
1128    def OnRefresh(self, event):
1129        self.controller.refresh()
1130       
1131    def waveformRefresh(self, event):
1132        wformsTobeRemoved = event.getSource()
1133        wformMenu = self.FindMenuInMenuBar('Waveforms')
1134           
1135        for wformName in wformsTobeRemoved:
1136            wPanel = self.getWaveformPanel(wformName)
1137            self.wpanels.remove(wPanel)
1138            self.compPopupMenus.pop(wPanel)
1139            self.prpPopupMenus.pop(wPanel)
1140            wPanel.Destroy()
1141                   
1142            #update the menu display
1143            menuItems = wformMenu.GetMenuItems()
1144               
1145            #remove the selected waveform from the menu list
1146            for mItem in menuItems:
1147                if mItem.GetItemLabel() == wformName :
1148                    wformMenu.RemoveItem(mItem)
1149                    mItem.Destroy()
1150                    break
1151       
1152        for wPanel in self.wpanels:
1153            cPanelList = wPanel.GetChildren()
1154            wformRef = self.model.getWaveform(wPanel.GetName(), WaveformModel.INSTANCE_WAVEFORM)
1155            print wformRef
1156            for cPanel in cPanelList:
1157                compRef = wformRef.getComponent(cPanel.GetName())
1158                if compRef is not None:
1159                    prpList = compRef.getAllProperties()
1160                    prpWidgetList = cPanel.GetChildren()
1161               
1162                    for prpW in prpWidgetList:
1163                        if type(prpW) is wx.TextCtrl:
1164                            prpW.SetValue(str(compRef.findPropertyByName(prpW.GetName()).getValue()))
1165                        elif type(prpW) is wx.SpinCtrl:
1166                            prpW.SetValue(int(compRef.findPropertyByName(prpW.GetName()).getValue()))
1167                        elif type(prpW) is wx.Slider:
1168                            prpW.SetValue(int(compRef.findPropertyByName(prpW.GetName()).getValue()))
1169           
1170        if (self.model.getActiveWaveform() is None):
1171            nextActiveWform = None
1172            #make the first available waveform active
1173            menuItems = wformMenu.GetMenuItems()
1174            for mItem in menuItems:
1175                if mItem.IsCheckable():
1176                    mItem.Check()
1177                    nextActiveWform = mItem.GetItemLabel()
1178                    break
1179           
1180            #no running waveforms on the system
1181            if nextActiveWform is None:
1182                self.SetSize(OSSIE_WAVEAPP_DIMENSION)
1183                return
1184            self.model.setActiveWaveform(nextActiveWform)
1185                   
1186    def getWaveformPanel(self, wformName):
1187        for wPanel in self.wpanels:
1188            if (wformName == wPanel.GetName()):
1189                return wPanel
1190               
1191     
1192    def OnOpenLayout(self, event):
1193        pass
1194    def OnSaveLayout(self, event):
1195        self.model.waveformToXML()
1196        pass
1197    def OnSaveLayoutAs(self, event):
1198        pass
1199    def OnClose(self, event):
1200        if self.controller.nodeBooterProcess != None:
1201            dlg = wx.MessageDialog(self,
1202                                   "NodeBooter was started by WaveDash.\n" +
1203                                   "Would you like to terminate it?",
1204                                   "Confirm NodeBooter Termination", wx.YES | wx.NO | wx.ICON_QUESTION)
1205            result = dlg.ShowModal()
1206            if result == wx.ID_YES:
1207                print "Terminating nodeBooter"
1208                self.controller.nodeBooterProcess.terminate()
1209        self.Destroy()
1210
1211    def OnWidgetSettings(self, event):
1212        pass
1213    def OnAbout(self, event):
1214        dlg = wx.MessageDialog(self, "WaveDash\nPart of the OSSIE Toolset",
1215                               "About WaveDash")
1216        dlg.ShowModal()
1217       
1218    def OnUpdateOnRefreshCheck(self, event):
1219        for button in self.configureButtons:
1220            button.Enable(self.updateOnRefresh.IsChecked())
1221           
1222    def OpenPreferences(self, event):
1223        PreferencePage = WavedashPreferencePage(self, self.controller)
1224        PreferencePage.Show()
1225           
1226    def OnUpdateComponentClicked(self, event):
1227        src = event.GetEventObject()
1228        compName = src.GetParent().GetName()
1229        wName = src.GetParent().GetParent().GetName()
1230        self.updateComponent(compName, wName)
1231       
1232    def OnUpdateWaveformClicked(self, event):
1233        src = event.GetEventObject()
1234        wName = src.GetParent().GetName()
1235        self.updateWaveform(wName)
1236       
1237    def OnPlotPort(self, event):
1238        src = event.GetEventObject()
1239        compName = src.GetParent().GetName()
1240        waveformName = src.GetParent().GetParent().GetName()
1241        waveform = self.model.getWaveform(waveformName, WaveformModel.INSTANCE_WAVEFORM)
1242        component = waveform.getComponent(compName)
1243        port = component.getPort(src.GetLabelText())
1244        if port:
1245            context = ("DomainName1", str('OSSIE::' + waveformName), str(compName))
1246            frame = plot.create(self, port.interface.nameSpace , port.interface.name, context , port.name)
1247   
1248    def openTool(self, event):
1249        src = event.GetEventObject()
1250        toolName = src.GetValue()
1251        if toolName == 'Available Tools':
1252            return
1253        compName = src.GetParent().GetName()
1254        waveformName = src.GetParent().GetParent().GetName()
1255        waveform = self.model.getWaveform(waveformName, WaveformModel.INSTANCE_WAVEFORM)
1256        component = waveform.getComponent(compName)
1257        port = src.port
1258        for t in src.supportedTools:
1259            if t.name == toolName:
1260                tool = t
1261                break
1262           
1263        if tool.module == None:
1264            # NOTE: alf_plugins is now the package that contains all tools
1265            exec_string = "from alf_plugins." + tool.packagename + " import "
1266            exec_string += tool.modulename + " as tool_module"
1267            exec exec_string
1268
1269            tool.module = tool_module
1270        else:
1271            tool_module = tool.module
1272            reload(tool_module)
1273           
1274        if port:
1275            context = ("DomainName1", str('OSSIE::' + waveformName), str(compName))
1276            newframe = tool_module.create(self, str(port.interface.nameSpace),
1277                                          str(port.interface.name), context, str(port.name))
1278            newframe.Show(True)
1279            src.SetValue('Available Tools')
1280       
1281    def updateWaveform(self, waveformName):
1282        wform = self.model.getWaveform(waveformName, WaveformModel.INSTANCE_WAVEFORM)
1283        for component in wform.getAllComponents():
1284            self.updateComponent(component.getName(), wform.getName())
1285               
1286    def updateComponent(self, componentName, waveformName):
1287        wform = self.model.getWaveform(waveformName, WaveformModel.INSTANCE_WAVEFORM)
1288        compRef = wform.getComponent(componentName)
1289        for property in compRef.getAllProperties():
1290            curVal = self.formatWidgetToModel(property.getWindow().GetValue(), property.getType())
1291            preVal = property.getValue()
1292         
1293   
1294            if curVal is not None:
1295           
1296            #if both the values are equal then no need to call configure()
1297                if preVal == curVal:
1298                    pass
1299                else:
1300                    status = self.model.configure(waveformName, componentName, property.getName(), curVal)
1301                    #leave the text box as it is if status is True
1302                    #if the configure operation failed, revert the text value to the value stored in
1303                    #the model.
1304                    if status is False:
1305                        msg = "Could not configure " + property.getName()
1306                        utils.showMessage(msg, utils.NON_FATAL)
1307                        self.formatModelToWidget(property.getWindow(), preVal)
1308                        #src.SetValue(str(preVal))
1309                    elif property.type[1] == "boolean":
1310                        self.formatModelToWidget(property.getWindow(), curVal)
1311               
1312            else:
1313                msg = "Invalid value for %s/%s" % (componentName, property.getName()) + "\nEnter only '" + property.getType()[1] + "' values"
1314                msg = msg + "\nFor sequence types, enter values separated by comma"
1315                msg = msg + " and enclosed within [] e.g. [10,20,30]"
1316           
1317                utils.showMessage(msg, utils.NON_FATAL)
1318                self.formatModelToWidget(property.getWindow(), preVal)     
1319                self.Layout()
1320           
1321    def getRoot(self):
1322        root = __file__
1323        if os.path.islink (root):
1324            root = os.path.realpath (root)
1325        root = os.path.dirname (os.path.abspath (root))
1326        return root
1327
1328def main():
1329    app = wx.App()
1330    ctrlr = Controller()
1331    ctrlr.createWidgetContainer()
1332   
1333    frame = WavedashView(ctrlr, ctrlr.model)
1334
1335    ctrlr.CORBAutils.init_CORBA()
1336    ctrlr.buildModel()
1337
1338    app.MainLoop()
1339       
1340if __name__ == '__main__':
1341    main()
1342
1343   
Note: See TracBrowser for help on using the browser.