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

Revision 10621, 52.6 KB (checked in by c2dietric, 2 years ago)

updates to ALF and WaveDash? titles

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