| 1 | #! /bin/env python |
|---|
| 2 | |
|---|
| 3 | # \todo Clean up order of import statements |
|---|
| 4 | import wx |
|---|
| 5 | from wx.lib import ogl |
|---|
| 6 | from wavedev import ComponentClass as CC |
|---|
| 7 | from wavedev import WaveformClass |
|---|
| 8 | from omniORB import CORBA, PortableServer |
|---|
| 9 | import CosNaming |
|---|
| 10 | from ossie.cf import CF, CF__POA |
|---|
| 11 | from ossie.custominterfaces import customInterfaces |
|---|
| 12 | from ossie.standardinterfaces import standardInterfaces |
|---|
| 13 | import sys |
|---|
| 14 | import importWaveform |
|---|
| 15 | import importResource |
|---|
| 16 | import ALFshapes, ALFtiming |
|---|
| 17 | |
|---|
| 18 | import xml.dom.minidom |
|---|
| 19 | from xml.dom.minidom import Node |
|---|
| 20 | |
|---|
| 21 | import os |
|---|
| 22 | import importIDL |
|---|
| 23 | import ALFutils |
|---|
| 24 | |
|---|
| 25 | import connectTool |
|---|
| 26 | import compform |
|---|
| 27 | import shutil |
|---|
| 28 | |
|---|
| 29 | import wx.lib.foldpanelbar as fpb |
|---|
| 30 | |
|---|
| 31 | import glob |
|---|
| 32 | |
|---|
| 33 | #---------------------------------------------------------------------- |
|---|
| 34 | # Create unique IDs for menu items and toolbar items for associating |
|---|
| 35 | # events with a particular action |
|---|
| 36 | [wxID_TOOLBAR_TIMING_TOOL, wxID_TOOLBAR_REFRESH_TOOL, |
|---|
| 37 | wxID_TOOLBAR_TIMING_DISPLAY_TOOL, wxID_TOOLBAR_CONNECT_TOOL] = [ |
|---|
| 38 | wx.NewId() for x in range(4)] |
|---|
| 39 | |
|---|
| 40 | [wxID_NSBOX_POPUP_DISPLAY, wxID_NSBOX_POPUP_UNINSTALL] = [wx.NewId() for x in range(2)] |
|---|
| 41 | |
|---|
| 42 | [wxID_INSTALLBOX_POPUP_INSTALL, wxID_COMPONENTSBOX_POPUP_INSTALL] = [wx.NewId() for x in range(2)] |
|---|
| 43 | |
|---|
| 44 | #---------------------------------------------------------------------- |
|---|
| 45 | class alfApp(wx.App): |
|---|
| 46 | def OnInit(self): |
|---|
| 47 | self.main = alfFrame(None) |
|---|
| 48 | self.main.Show() |
|---|
| 49 | self.SetTopWindow(self.main) |
|---|
| 50 | return True |
|---|
| 51 | |
|---|
| 52 | #---------------------------------------------------------------------- |
|---|
| 53 | class alfFrame(wx.Frame): |
|---|
| 54 | def _init_ctrls(self, parent): |
|---|
| 55 | wx.Frame.__init__(self, id=-1, name='CompFrame', |
|---|
| 56 | parent=parent, pos=wx.DefaultPosition, size=wx.Size(1100, 800), |
|---|
| 57 | style=wx.DEFAULT_FRAME_STYLE, title=u'ALF - Waveform Debugger') |
|---|
| 58 | |
|---|
| 59 | # Initialize graphics |
|---|
| 60 | ogl.OGLInitialize() |
|---|
| 61 | ALFshapes.initializeColours() |
|---|
| 62 | |
|---|
| 63 | # Create the sash window and layout |
|---|
| 64 | self._leftWindow = wx.SashLayoutWindow(self, 101, wx.DefaultPosition, |
|---|
| 65 | wx.Size(240, 600), wx.NO_BORDER | wx.SW_3D | wx.CLIP_CHILDREN) |
|---|
| 66 | |
|---|
| 67 | self._leftWindow.SetDefaultSize(wx.Size(300, 400)) |
|---|
| 68 | self._leftWindow.SetOrientation(wx.LAYOUT_VERTICAL) |
|---|
| 69 | self._leftWindow.SetAlignment(wx.LAYOUT_LEFT) |
|---|
| 70 | self._leftWindow.SetSashVisible(wx.SASH_RIGHT, True) |
|---|
| 71 | self._leftWindow.SetExtraBorderSize(10) |
|---|
| 72 | |
|---|
| 73 | self.ID_WINDOW_TOP = 100 |
|---|
| 74 | self.ID_WINDOW_LEFT = 101 |
|---|
| 75 | self.ID_WINDOW_RIGHT = 102 |
|---|
| 76 | self.ID_WINDOW_BOTTOM = 103 |
|---|
| 77 | |
|---|
| 78 | self._leftWindow.Bind(wx.EVT_SASH_DRAGGED_RANGE, self.OnFoldPanelBarDrag, |
|---|
| 79 | id=100, id2=103) |
|---|
| 80 | self.Bind(wx.EVT_SIZE, self.OnFoldPanelSize) |
|---|
| 81 | |
|---|
| 82 | # Instantiate the main canvas |
|---|
| 83 | self.canvas = MainWindow(self, self) |
|---|
| 84 | |
|---|
| 85 | # Create the fold panel and add its windows |
|---|
| 86 | self._fpb_pnl = None |
|---|
| 87 | self.CreateFoldPanel() |
|---|
| 88 | |
|---|
| 89 | # Create the status and toolbars |
|---|
| 90 | self.CreateStatusBar(1, wx.ST_SIZEGRIP) |
|---|
| 91 | self.CreateToolBar() |
|---|
| 92 | |
|---|
| 93 | # Make a popup box for the Naming Service / Manage Waveforms functionality |
|---|
| 94 | self.nsBoxPopup = wx.Menu(title=u'') |
|---|
| 95 | self.init_nsBoxPopup_Items(self.nsBoxPopup) |
|---|
| 96 | |
|---|
| 97 | # Make a popup box for the Launch Waveforms functionality |
|---|
| 98 | self.installBoxPopup = wx.Menu(title=u'') |
|---|
| 99 | self.init_installBoxPopup_Items(self.installBoxPopup) |
|---|
| 100 | |
|---|
| 101 | # Make a popup box for the Launch Components asWaveforms functionality |
|---|
| 102 | self.componentsBoxPopup = wx.Menu(title=u'') |
|---|
| 103 | self.init_componentsBoxPopup_Items(self.componentsBoxPopup) |
|---|
| 104 | |
|---|
| 105 | self.setupToolbar() |
|---|
| 106 | |
|---|
| 107 | def __init__(self,parent): |
|---|
| 108 | self.active_wave = None |
|---|
| 109 | self.timing_display = None |
|---|
| 110 | self.tools = None |
|---|
| 111 | self.waveform_displays = {} |
|---|
| 112 | |
|---|
| 113 | # WARNING: if alf is restarted and waveforms are left running |
|---|
| 114 | # counters will overlap and cause a crash :/ |
|---|
| 115 | self.compform_counter = 0 |
|---|
| 116 | |
|---|
| 117 | self._init_ctrls(parent) |
|---|
| 118 | self.Available_Ints = ALFutils.importStandardIdl(self) |
|---|
| 119 | self.rootContext = None |
|---|
| 120 | self.domMgr = None |
|---|
| 121 | self.init_CORBA() |
|---|
| 122 | |
|---|
| 123 | ALFutils.LoadConfiguration(self) |
|---|
| 124 | |
|---|
| 125 | self.waveformData = {} |
|---|
| 126 | self.tool_frames = [] |
|---|
| 127 | self.last_waveform_data_update = None |
|---|
| 128 | self.dasXML_list = [] |
|---|
| 129 | self.availableWaveforms = {} |
|---|
| 130 | self.availableComponents = {} |
|---|
| 131 | |
|---|
| 132 | if self.rootContext != None: |
|---|
| 133 | self.DisplayInstalledWaveforms() |
|---|
| 134 | self.DisplayAvailableWaveforms() |
|---|
| 135 | self.DisplayAvailableComponents() |
|---|
| 136 | |
|---|
| 137 | def init_CORBA(self): |
|---|
| 138 | """Initialize an orb and try to connect to the DomainManager""" |
|---|
| 139 | |
|---|
| 140 | orb = CORBA.ORB_init(sys.argv, CORBA.ORB_ID) |
|---|
| 141 | obj = orb.resolve_initial_references("NameService") |
|---|
| 142 | try: |
|---|
| 143 | self.rootContext = obj._narrow(CosNaming.NamingContext) |
|---|
| 144 | except: |
|---|
| 145 | ts = "Failed to narrow the root naming context.\n" |
|---|
| 146 | ts += "Are the Naming Service and nodeBooter running?" |
|---|
| 147 | errorMsg(self, ts) |
|---|
| 148 | self.rootContext = None |
|---|
| 149 | self.domMgr = None |
|---|
| 150 | return |
|---|
| 151 | |
|---|
| 152 | if self.rootContext is None: |
|---|
| 153 | errorMsg(self,"Failed to narrow the root naming context") |
|---|
| 154 | self.domMgr = None |
|---|
| 155 | return |
|---|
| 156 | |
|---|
| 157 | name = [CosNaming.NameComponent("DomainName1",""), |
|---|
| 158 | CosNaming.NameComponent("DomainManager","")] |
|---|
| 159 | |
|---|
| 160 | try: |
|---|
| 161 | obj = self.rootContext.resolve(name) |
|---|
| 162 | except: |
|---|
| 163 | errorMsg(self,"DomainManger name not found") |
|---|
| 164 | self.domMgr = None |
|---|
| 165 | return |
|---|
| 166 | |
|---|
| 167 | self.domMgr = obj._narrow(CF.DomainManager) |
|---|
| 168 | |
|---|
| 169 | #--------------------------------------------------------------- |
|---|
| 170 | # Setup the display |
|---|
| 171 | #--------------------------------------------------------------- |
|---|
| 172 | def init_nsBoxPopup_Items(self, parent): |
|---|
| 173 | """Setup the popup menu for the Naming Service / Manage Waveforms box""" |
|---|
| 174 | |
|---|
| 175 | parent.Append(help='', id=wxID_NSBOX_POPUP_DISPLAY, kind=wx.ITEM_NORMAL, text=u'Display') |
|---|
| 176 | parent.Append(help='', id=wxID_NSBOX_POPUP_UNINSTALL, kind=wx.ITEM_NORMAL, text=u'Uninstall') |
|---|
| 177 | self.nsBox.Bind(wx.EVT_MENU, self.OnNsBoxPopupDisplayMenu, id=wxID_NSBOX_POPUP_DISPLAY) |
|---|
| 178 | self.nsBox.Bind(wx.EVT_MENU, self.OnNsBoxPopupUninstallMenu, id=wxID_NSBOX_POPUP_UNINSTALL) |
|---|
| 179 | |
|---|
| 180 | def init_installBoxPopup_Items(self, parent): |
|---|
| 181 | """Setup the popup menu for the Launch Waveforms box""" |
|---|
| 182 | |
|---|
| 183 | parent.Append(help='', id=wxID_INSTALLBOX_POPUP_INSTALL, kind=wx.ITEM_NORMAL, text=u'Install') |
|---|
| 184 | self.installBox.Bind(wx.EVT_MENU, self.OnInstallBoxPopupInstallMenu, id=wxID_INSTALLBOX_POPUP_INSTALL) |
|---|
| 185 | |
|---|
| 186 | def init_componentsBoxPopup_Items(self, parent): |
|---|
| 187 | """Setup the popup menu for the Launch Components as Waveforms box""" |
|---|
| 188 | |
|---|
| 189 | parent.Append(help='', id=wxID_COMPONENTSBOX_POPUP_INSTALL, |
|---|
| 190 | kind=wx.ITEM_NORMAL, text=u'Install') |
|---|
| 191 | self.installBox.Bind(wx.EVT_MENU, self.OnComponentsBoxPopupInstallMenu, |
|---|
| 192 | id=wxID_INSTALLBOX_POPUP_INSTALL) |
|---|
| 193 | |
|---|
| 194 | def CreateFoldPanel(self): |
|---|
| 195 | self._fpb_pnl = fpb.FoldPanelBar(self._leftWindow, -1, wx.DefaultPosition, |
|---|
| 196 | wx.Size(-1,-1), fpb.FPB_DEFAULT_STYLE, 0) |
|---|
| 197 | |
|---|
| 198 | # Create the image list for the fold button icons |
|---|
| 199 | Images = wx.ImageList(16,16) |
|---|
| 200 | Images.Add(ALFutils.GetExpandedIconBitmap()) |
|---|
| 201 | Images.Add(ALFutils.GetCollapsedIconBitmap()) |
|---|
| 202 | |
|---|
| 203 | # Add the Launch Waveforms box |
|---|
| 204 | item = self._fpb_pnl.AddFoldPanel("Launch Waveforms", |
|---|
| 205 | collapsed=False, |
|---|
| 206 | foldIcons=Images) |
|---|
| 207 | self.installBox = wx.TreeCtrl(name=u'installBox', |
|---|
| 208 | parent=item, |
|---|
| 209 | size = wx.Size(-1,200), |
|---|
| 210 | style = wx.TR_HIDE_ROOT | |
|---|
| 211 | wx.TR_HAS_BUTTONS | |
|---|
| 212 | wx.SIMPLE_BORDER) |
|---|
| 213 | self._fpb_pnl.AddFoldPanelWindow(item, self.installBox, |
|---|
| 214 | fpb.FPB_ALIGN_WIDTH, 4) |
|---|
| 215 | self.installBox.Bind(wx.EVT_RIGHT_UP, self.OnInstallBoxRightUp) |
|---|
| 216 | self.installBox.Bind(wx.EVT_LEFT_DCLICK, self.OnInstallBoxLeftDclick) |
|---|
| 217 | |
|---|
| 218 | # Add the Launch Components as Waveforms box |
|---|
| 219 | item = self._fpb_pnl.AddFoldPanel("Launch Components as Waveforms", |
|---|
| 220 | collapsed=False, |
|---|
| 221 | foldIcons=Images) |
|---|
| 222 | self.componentsBox = wx.TreeCtrl(name=u'componentsBox', |
|---|
| 223 | parent=item, |
|---|
| 224 | size = wx.Size(-1,200), |
|---|
| 225 | style = wx.TR_HIDE_ROOT | |
|---|
| 226 | wx.TR_HAS_BUTTONS | |
|---|
| 227 | wx.SIMPLE_BORDER) |
|---|
| 228 | self._fpb_pnl.AddFoldPanelWindow(item, self.componentsBox, |
|---|
| 229 | fpb.FPB_ALIGN_WIDTH, 4) |
|---|
| 230 | self.componentsBox.Bind(wx.EVT_RIGHT_UP, self.OnComponentsBoxRightUp) |
|---|
| 231 | self.componentsBox.Bind(wx.EVT_LEFT_DCLICK, |
|---|
| 232 | self.OnComponentsBoxLeftDclick) |
|---|
| 233 | |
|---|
| 234 | # Add the Manage Waveforms box |
|---|
| 235 | item = self._fpb_pnl.AddFoldPanel("Manage Waveforms", |
|---|
| 236 | collapsed=False, |
|---|
| 237 | foldIcons=Images) |
|---|
| 238 | self.nsBox = wx.TreeCtrl(name=u'nsBox', parent=item, |
|---|
| 239 | size = wx.Size(-1,200), |
|---|
| 240 | style = wx.TR_HIDE_ROOT | |
|---|
| 241 | wx.TR_HAS_BUTTONS | |
|---|
| 242 | wx.SIMPLE_BORDER) |
|---|
| 243 | self.nsBox.Bind(wx.EVT_RIGHT_UP, self.OnNsBoxRightUp) |
|---|
| 244 | self.nsBox.Bind(wx.EVT_LEFT_DCLICK, self.OnNsBoxLeftDclick) |
|---|
| 245 | self._fpb_pnl.AddFoldPanelWindow(item, self.nsBox, |
|---|
| 246 | fpb.FPB_ALIGN_WIDTH, 4) |
|---|
| 247 | |
|---|
| 248 | self._leftWindow.SizeWindows() |
|---|
| 249 | |
|---|
| 250 | |
|---|
| 251 | def setupToolbar(self): |
|---|
| 252 | toolbar = self.GetToolBar() |
|---|
| 253 | tsize = (20,20) |
|---|
| 254 | test_bmp = wx.ArtProvider.GetBitmap(wx.ART_REDO, wx.ART_TOOLBAR, tsize) |
|---|
| 255 | toolbar.AddSimpleTool(wxID_TOOLBAR_REFRESH_TOOL,test_bmp,shortHelpString="Refresh") |
|---|
| 256 | toolbar.AddSeparator() |
|---|
| 257 | |
|---|
| 258 | time_img = wx.Image('timing.png',type=wx.BITMAP_TYPE_PNG) |
|---|
| 259 | time_img.Rescale(24,24) |
|---|
| 260 | time_bmp = wx.BitmapFromImage(time_img) |
|---|
| 261 | toolbar.AddCheckTool(wxID_TOOLBAR_TIMING_TOOL,time_bmp,shortHelp="Enable Timing") |
|---|
| 262 | self.timing_view_state = False |
|---|
| 263 | |
|---|
| 264 | |
|---|
| 265 | time_img = wx.Image('timing_display.png',type=wx.BITMAP_TYPE_PNG) |
|---|
| 266 | time_img.Rescale(24,24) |
|---|
| 267 | time_bmp = wx.BitmapFromImage(time_img) |
|---|
| 268 | toolbar.AddCheckTool(wxID_TOOLBAR_TIMING_DISPLAY_TOOL,time_bmp,shortHelp="Toggle Timing Display") |
|---|
| 269 | |
|---|
| 270 | toolbar.AddSeparator() |
|---|
| 271 | |
|---|
| 272 | |
|---|
| 273 | connect_bmp = wx.ArtProvider.GetBitmap(wx.ART_COPY, wx.ART_TOOLBAR, tsize) |
|---|
| 274 | toolbar.AddSimpleTool(wxID_TOOLBAR_CONNECT_TOOL,connect_bmp,shortHelpString="Connect Tool") |
|---|
| 275 | |
|---|
| 276 | |
|---|
| 277 | |
|---|
| 278 | toolbar.Bind(wx.EVT_TOOL, self.OnToolBarClick) |
|---|
| 279 | |
|---|
| 280 | toolbar.Realize() |
|---|
| 281 | |
|---|
| 282 | # --------------------------------------------------- |
|---|
| 283 | # Event handling for toolbar |
|---|
| 284 | # --------------------------------------------------- |
|---|
| 285 | def OnToolBarClick(self,event): |
|---|
| 286 | tb = self.GetToolBar() |
|---|
| 287 | if event.GetId() == wxID_TOOLBAR_TIMING_TOOL: |
|---|
| 288 | if tb.GetToolState(wxID_TOOLBAR_TIMING_TOOL): |
|---|
| 289 | if self.active_wave == None: |
|---|
| 290 | errorMsg(self,"Please select and display a waveform first!") |
|---|
| 291 | tb.ToggleTool(wxID_TOOLBAR_TIMING_TOOL, False) |
|---|
| 292 | return |
|---|
| 293 | tb.EnableTool(wxID_TOOLBAR_TIMING_DISPLAY_TOOL, True) |
|---|
| 294 | tb.SetToolShortHelp(wxID_TOOLBAR_TIMING_TOOL, "Disable Timing") |
|---|
| 295 | self.timing_display = ALFtiming.TimingDisplay(self.active_wave.naming_context, self) |
|---|
| 296 | else: |
|---|
| 297 | self.timing_display = None |
|---|
| 298 | tb.EnableTool(wxID_TOOLBAR_TIMING_DISPLAY_TOOL, False) |
|---|
| 299 | tb.SetToolShortHelp(wxID_TOOLBAR_TIMING_TOOL, "Enable Timing") |
|---|
| 300 | self.refreshDisplay() |
|---|
| 301 | |
|---|
| 302 | if event.GetId() == wxID_TOOLBAR_TIMING_DISPLAY_TOOL: |
|---|
| 303 | if tb.GetToolState(wxID_TOOLBAR_TIMING_DISPLAY_TOOL): |
|---|
| 304 | tb.SetToolShortHelp(wxID_TOOLBAR_TIMING_DISPLAY_TOOL, "Disable Timing Graphics") |
|---|
| 305 | self.timing_view_state = True |
|---|
| 306 | else: |
|---|
| 307 | tb.SetToolShortHelp(wxID_TOOLBAR_TIMING_DISPLAY_TOOL, "Enable Timing Graphics") |
|---|
| 308 | self.timing_view_state = False |
|---|
| 309 | |
|---|
| 310 | elif event.GetId() == wxID_TOOLBAR_CONNECT_TOOL: |
|---|
| 311 | self.connect_frame = connectTool.create(self) |
|---|
| 312 | |
|---|
| 313 | # Refresh the display: Naming Service, Waveform List, and Canvas |
|---|
| 314 | elif event.GetId() == wxID_TOOLBAR_REFRESH_TOOL: |
|---|
| 315 | self.refreshDisplay(True) |
|---|
| 316 | self.DisplayInstalledWaveforms() |
|---|
| 317 | self.DisplayAvailableWaveforms() |
|---|
| 318 | self.DisplayAvailableComponents() |
|---|
| 319 | tb.ToggleTool(wxID_TOOLBAR_REFRESH_TOOL, False) |
|---|
| 320 | |
|---|
| 321 | def processTimingEvent(self, component_name, port_name, function_name, description, time_s, time_us, number_samples): |
|---|
| 322 | if self.active_wave == None or (self.active_wave.naming_context not in component_name): |
|---|
| 323 | errorMsg(self,"Cannot find waveform containing: " + component_name) |
|---|
| 324 | |
|---|
| 325 | cname = component_name[component_name.rfind('/')+1:] |
|---|
| 326 | if self.active_wave != None: |
|---|
| 327 | for comp in self.active_wave.components: |
|---|
| 328 | if comp.name == cname: |
|---|
| 329 | comp.shape.processTimingEvent(port_name, function_name, description, time_s, time_us, number_samples) |
|---|
| 330 | |
|---|
| 331 | |
|---|
| 332 | |
|---|
| 333 | # --------------------------------------------------------- |
|---|
| 334 | # Event handling for the FoldPanel |
|---|
| 335 | # -------------------------------------------------------- |
|---|
| 336 | def OnFoldPanelSize(self, event): |
|---|
| 337 | wx.LayoutAlgorithm().LayoutWindow(self, self.canvas) |
|---|
| 338 | event.Skip() |
|---|
| 339 | |
|---|
| 340 | def OnFoldPanelBarDrag(self, event): |
|---|
| 341 | if event.GetDragStatus() == wx.SASH_STATUS_OUT_OF_RANGE: |
|---|
| 342 | return |
|---|
| 343 | |
|---|
| 344 | if event.GetId() == self.ID_WINDOW_LEFT: |
|---|
| 345 | self._leftWindow.SetDefaultSize(wx.Size(event.GetDragRect().width, 400)) |
|---|
| 346 | |
|---|
| 347 | # Leaves bits of itself behind sometimes |
|---|
| 348 | wx.LayoutAlgorithm().LayoutWindow(self, self.canvas) |
|---|
| 349 | self.canvas.Refresh() |
|---|
| 350 | |
|---|
| 351 | event.Skip() |
|---|
| 352 | |
|---|
| 353 | # --------------------------------------------------------- |
|---|
| 354 | # Event handling for Naming Service / Manage Waveforms box |
|---|
| 355 | # -------------------------------------------------------- |
|---|
| 356 | def OnNsBoxRightUp(self, event): |
|---|
| 357 | self.nsBox.PopupMenu(self.nsBoxPopup) |
|---|
| 358 | event.Skip() |
|---|
| 359 | |
|---|
| 360 | def OnNsBoxLeftDclick(self, event): |
|---|
| 361 | self.DisplayWaveform() |
|---|
| 362 | |
|---|
| 363 | def OnNsBoxPopupDisplayMenu(self, event): |
|---|
| 364 | self.DisplayWaveform() |
|---|
| 365 | |
|---|
| 366 | def OnNsBoxPopupUninstallMenu(self, event): |
|---|
| 367 | self.UninstallWaveform() |
|---|
| 368 | |
|---|
| 369 | def DisplayWaveform(self): |
|---|
| 370 | sn = self.nsBox.GetSelection() |
|---|
| 371 | if sn == self.nsBox.GetRootItem(): |
|---|
| 372 | errorMsg(self,'Please select a waveform!') |
|---|
| 373 | return |
|---|
| 374 | snPrnt = self.nsBox.GetItemParent(sn) |
|---|
| 375 | if snPrnt != self.nsBox.GetRootItem(): |
|---|
| 376 | errorMsg(self,'Please select a waveform!') |
|---|
| 377 | return |
|---|
| 378 | |
|---|
| 379 | wave_name = self.nsBox.GetItemText(sn) |
|---|
| 380 | app = self.nsBox.GetPyData(sn) |
|---|
| 381 | if app is None: |
|---|
| 382 | errorMsg(self,'No application associated with this entry!') |
|---|
| 383 | return |
|---|
| 384 | |
|---|
| 385 | # Check to see if a waveform is already active |
|---|
| 386 | if self.active_wave != None: |
|---|
| 387 | self.refreshDisplay(True) |
|---|
| 388 | |
|---|
| 389 | # Set item bold and all others set to plain text |
|---|
| 390 | troot = self.nsBox.GetRootItem() |
|---|
| 391 | if self.nsBox.GetChildrenCount(troot) <= 0: |
|---|
| 392 | return |
|---|
| 393 | cid1,cookie1 = self.nsBox.GetFirstChild(troot) |
|---|
| 394 | self.nsBox.SetItemBold(cid1, False) |
|---|
| 395 | for x in range(self.nsBox.GetChildrenCount(troot,recursively=False)-1): |
|---|
| 396 | cid2,cookie2 = self.nsBox.GetNextChild(troot,cookie1) |
|---|
| 397 | self.nsBox.SetItemBold(cid2, False) |
|---|
| 398 | cid1 = cid2 |
|---|
| 399 | cookie1 = cookie2 |
|---|
| 400 | |
|---|
| 401 | self.nsBox.SetItemBold(sn, True) |
|---|
| 402 | self.nsBox.SelectItem(sn, False) |
|---|
| 403 | |
|---|
| 404 | # Check to see if this waveform has previously been displayed |
|---|
| 405 | # If so, then update the display and return |
|---|
| 406 | if self.waveform_displays.has_key(wave_name): |
|---|
| 407 | # Clear the canvas and get ready to display the waveform |
|---|
| 408 | #print "already imported this waveform .... displaying..." |
|---|
| 409 | tmpdisplay = self.waveform_displays[wave_name] |
|---|
| 410 | # self.refreshDisplay(True) |
|---|
| 411 | self.active_wave = tmpdisplay.waveform |
|---|
| 412 | self.canvas.updateDisplay(tmpdisplay) |
|---|
| 413 | return |
|---|
| 414 | |
|---|
| 415 | sadfile = app._get_profile() |
|---|
| 416 | sadfile = sadfile.replace('//','') |
|---|
| 417 | wav_name = sadfile.replace('.sad.xml','') |
|---|
| 418 | sadpath = '/sdr/' + sadfile |
|---|
| 419 | |
|---|
| 420 | self.active_wave = importWaveform.getWaveform(sadpath, self, self.Available_Ints) |
|---|
| 421 | self.active_wave.naming_context = str(wave_name) |
|---|
| 422 | |
|---|
| 423 | tmpdisplay = self.AddWaveformShape(self.active_wave) |
|---|
| 424 | self.waveform_displays[wave_name] = tmpdisplay |
|---|
| 425 | |
|---|
| 426 | self.canvas.updateDisplay(tmpdisplay) |
|---|
| 427 | |
|---|
| 428 | |
|---|
| 429 | def DisplayInstalledWaveforms(self): |
|---|
| 430 | self.nsBox.DeleteAllItems() |
|---|
| 431 | nsRoot = self.nsBox.AddRoot("ns_root") |
|---|
| 432 | |
|---|
| 433 | if self.domMgr == None or self.rootContext == None: |
|---|
| 434 | return |
|---|
| 435 | |
|---|
| 436 | dom_obj = self.rootContext.resolve([CosNaming.NameComponent("DomainName1","")]) |
|---|
| 437 | dom_context = dom_obj._narrow(CosNaming.NamingContext) |
|---|
| 438 | if dom_context is None: |
|---|
| 439 | return |
|---|
| 440 | |
|---|
| 441 | appSeq = self.domMgr._get_applications() |
|---|
| 442 | members = dom_context.list(1000) |
|---|
| 443 | for m in members[0]: |
|---|
| 444 | wav_name = str(m.binding_name[0].id) |
|---|
| 445 | wav_obj = dom_context.resolve([CosNaming.NameComponent(wav_name,"")]) |
|---|
| 446 | wav_context = wav_obj._narrow(CosNaming.NamingContext) |
|---|
| 447 | if wav_context is None: |
|---|
| 448 | continue |
|---|
| 449 | |
|---|
| 450 | contextApp = None |
|---|
| 451 | foundApp = False |
|---|
| 452 | for app in appSeq: |
|---|
| 453 | compNameCon = app._get_componentNamingContexts() |
|---|
| 454 | for compElementType in compNameCon: |
|---|
| 455 | if wav_name in compElementType.elementId: |
|---|
| 456 | waveformApp = app |
|---|
| 457 | foundApp = True |
|---|
| 458 | #print compElementType.componentId + " " + compElementType.elementId |
|---|
| 459 | break |
|---|
| 460 | |
|---|
| 461 | if not foundApp: |
|---|
| 462 | print "Could not find associated application for: " + wav_name |
|---|
| 463 | continue |
|---|
| 464 | |
|---|
| 465 | t1 = self.nsBox.AppendItem(nsRoot,wav_name) |
|---|
| 466 | self.nsBox.SetPyData(t1,waveformApp) |
|---|
| 467 | |
|---|
| 468 | # Set item bold if it is the active waveform |
|---|
| 469 | if self.active_wave is not None: |
|---|
| 470 | if self.active_wave.naming_context == wav_name: |
|---|
| 471 | self.nsBox.SetItemBold(t1, True) |
|---|
| 472 | |
|---|
| 473 | self.nsBox.SortChildren(nsRoot) |
|---|
| 474 | |
|---|
| 475 | # --------------------------------------------------------- |
|---|
| 476 | # Event handling and control for Launch Waveforms box |
|---|
| 477 | # -------------------------------------------------------- |
|---|
| 478 | def DisplayAvailableWaveforms(self): |
|---|
| 479 | self.installBox.DeleteAllItems() |
|---|
| 480 | self.availableWaveforms.clear() |
|---|
| 481 | installRoot = self.installBox.AddRoot("install_root") |
|---|
| 482 | |
|---|
| 483 | # Search for SAD files on /sdr/dom/waveforms. |
|---|
| 484 | # \todo Use SCA filesystem to ease use with embedded systems |
|---|
| 485 | # \todo Figure out how to search more directories |
|---|
| 486 | |
|---|
| 487 | for full_sad_file in glob.glob('/sdr/dom/waveforms/*.sad.xml'): |
|---|
| 488 | |
|---|
| 489 | full_das_file = full_sad_file.replace('.sad.xml', '_DAS.xml') |
|---|
| 490 | |
|---|
| 491 | # \todo Check for dasfile existence, set dasfile to null, no |
|---|
| 492 | # dasfile is not an error (although the underlying framework must |
|---|
| 493 | # be able to do dynamic deployment |
|---|
| 494 | |
|---|
| 495 | sad_file = os.path.basename(full_sad_file) |
|---|
| 496 | das_file = os.path.basename(full_das_file) |
|---|
| 497 | |
|---|
| 498 | wavename = sad_file[:-8] |
|---|
| 499 | self.availableWaveforms[wavename] = (sad_file, full_sad_file, das_file, full_das_file) |
|---|
| 500 | |
|---|
| 501 | # Populate the display at the Domain level |
|---|
| 502 | for waveform in self.availableWaveforms.keys(): |
|---|
| 503 | t1 = self.installBox.AppendItem(installRoot,waveform) |
|---|
| 504 | self.installBox.SetPyData(t1,self.availableWaveforms[waveform]) |
|---|
| 505 | self.installBox.SetItemBold(t1,False) |
|---|
| 506 | |
|---|
| 507 | self.installBox.SortChildren(installRoot) |
|---|
| 508 | |
|---|
| 509 | |
|---|
| 510 | # ----------------------------------------------------------------- |
|---|
| 511 | # Event handling and control for Launch Components as Waveforms box |
|---|
| 512 | # ----------------------------------------------------------------- |
|---|
| 513 | def DisplayAvailableComponents(self): |
|---|
| 514 | self.componentsBox.DeleteAllItems() |
|---|
| 515 | self.availableComponents.clear() |
|---|
| 516 | installRoot = self.componentsBox.AddRoot("install_root") |
|---|
| 517 | |
|---|
| 518 | for dirpath, dirnames, filenames in os.walk(self.installpath): |
|---|
| 519 | spd_file = None |
|---|
| 520 | for fname in filenames: |
|---|
| 521 | # skip the Domain Manager spd file |
|---|
| 522 | if fname.find("DomainManager") != -1: |
|---|
| 523 | continue |
|---|
| 524 | # skip the Device Manager spd file |
|---|
| 525 | if fname.find("DeviceManager") != -1: |
|---|
| 526 | continue |
|---|
| 527 | if fname.find(".spd.xml") != -1: |
|---|
| 528 | # make sure that the '.spd.xml' comes at the end |
|---|
| 529 | # of the file name |
|---|
| 530 | if fname[-8:] == ".spd.xml": |
|---|
| 531 | spd_file = fname |
|---|
| 532 | full_spd_file = dirpath + "/" |
|---|
| 533 | |
|---|
| 534 | # TODO: make sure all the xml and binary files are present |
|---|
| 535 | |
|---|
| 536 | if spd_file == None: |
|---|
| 537 | continue |
|---|
| 538 | |
|---|
| 539 | compname = spd_file[:-8] |
|---|
| 540 | compNameAndDir = full_spd_file |
|---|
| 541 | |
|---|
| 542 | if self.availableComponents.has_key(compname): |
|---|
| 543 | errorMsg(self, "Conflicting component name: " + compname) |
|---|
| 544 | continue |
|---|
| 545 | |
|---|
| 546 | self.availableComponents[compname] = (compname, compNameAndDir) |
|---|
| 547 | |
|---|
| 548 | # Populate the display at the Domain level |
|---|
| 549 | for component in self.availableComponents.keys(): |
|---|
| 550 | t1 = self.componentsBox.AppendItem(installRoot,component) |
|---|
| 551 | self.componentsBox.SetPyData(t1,self.availableComponents[component]) |
|---|
| 552 | self.componentsBox.SetItemBold(t1,False) |
|---|
| 553 | |
|---|
| 554 | self.componentsBox.SortChildren(installRoot) |
|---|
| 555 | |
|---|
| 556 | |
|---|
| 557 | def OnInstallBoxRightUp(self, event): |
|---|
| 558 | self.installBox.PopupMenu(self.installBoxPopup) |
|---|
| 559 | event.Skip() |
|---|
| 560 | |
|---|
| 561 | def OnInstallBoxPopupInstallMenu(self, event): |
|---|
| 562 | self.InstallWaveformFromBox() |
|---|
| 563 | event.Skip() |
|---|
| 564 | |
|---|
| 565 | def OnInstallBoxLeftDclick(self, event): |
|---|
| 566 | self.InstallWaveformFromBox() |
|---|
| 567 | event.Skip() |
|---|
| 568 | |
|---|
| 569 | def OnComponentsBoxRightUp(self, event): |
|---|
| 570 | self.componentsBox.PopupMenu(self.componentsBoxPopup) |
|---|
| 571 | event.Skip() |
|---|
| 572 | |
|---|
| 573 | def OnComponentsBoxPopupInstallMenu(self, event): |
|---|
| 574 | self.InstallCompform() |
|---|
| 575 | event.Skip() |
|---|
| 576 | |
|---|
| 577 | def OnComponentsBoxLeftDclick(self, event): |
|---|
| 578 | self.InstallCompform() |
|---|
| 579 | event.Skip() |
|---|
| 580 | |
|---|
| 581 | def InstallWaveformFromBox(self): |
|---|
| 582 | selection = self.installBox.GetSelection() |
|---|
| 583 | name_SAD, absolute_name_SAD, name_DAS, absolute_name_DAS = self.installBox.GetPyData(selection) |
|---|
| 584 | |
|---|
| 585 | print name_SAD |
|---|
| 586 | print absolute_name_SAD |
|---|
| 587 | self.InstallWaveform(name_SAD, absolute_name_SAD, |
|---|
| 588 | name_DAS, absolute_name_DAS) |
|---|
| 589 | |
|---|
| 590 | |
|---|
| 591 | def InstallWaveform(self,name_SAD, absolute_name_SAD, |
|---|
| 592 | name_DAS, absolute_name_DAS): |
|---|
| 593 | sadxml = importResource.stripDoctype(absolute_name_SAD) |
|---|
| 594 | doc_sad = xml.dom.minidom.parse(absolute_name_SAD) |
|---|
| 595 | app_name = doc_sad.getElementsByTagName("softwareassembly")[0].getAttribute("name") |
|---|
| 596 | _appFacProps = [] |
|---|
| 597 | devMgrSeq = self.domMgr._get_deviceManagers() |
|---|
| 598 | available_dev_seq = [] |
|---|
| 599 | for devmgr in range(len(devMgrSeq)): |
|---|
| 600 | devMgr = devMgrSeq[devmgr] |
|---|
| 601 | curr_devSeq = devMgr._get_registeredDevices() |
|---|
| 602 | for dev in range(len(curr_devSeq)): |
|---|
| 603 | curr_dev = curr_devSeq[dev] |
|---|
| 604 | available_dev_seq.append(curr_dev._get_identifier()) |
|---|
| 605 | #print curr_dev._get_identifier() |
|---|
| 606 | |
|---|
| 607 | clean_SAD = absolute_name_SAD.split("/sdr") |
|---|
| 608 | name_SAD = clean_SAD[1] |
|---|
| 609 | self.domMgr.installApplication(name_SAD) |
|---|
| 610 | |
|---|
| 611 | |
|---|
| 612 | # Parse the device assignment sequence, ensure |
|---|
| 613 | doc_das = xml.dom.minidom.parse(absolute_name_DAS) |
|---|
| 614 | deviceassignmenttypeNodeList = doc_das.getElementsByTagName("deviceassignmenttype") |
|---|
| 615 | |
|---|
| 616 | for deviceassignmenttypeNode in deviceassignmenttypeNodeList: |
|---|
| 617 | # look for assigndeviceid nodes |
|---|
| 618 | assigndeviceidNodeList = deviceassignmenttypeNode.getElementsByTagName("assigndeviceid") |
|---|
| 619 | if len(assigndeviceidNodeList) == 0: |
|---|
| 620 | ts = "Could not find \"assigndeviceid\" tag\nAborting install" |
|---|
| 621 | errorMsg(self, ts) |
|---|
| 622 | return |
|---|
| 623 | |
|---|
| 624 | # get assigndeviceid tag value (DCE:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx) |
|---|
| 625 | assigndeviceid = assigndeviceidNodeList[0].firstChild.data |
|---|
| 626 | |
|---|
| 627 | # ensure assigndeviceid is in list of available devices |
|---|
| 628 | if assigndeviceid not in available_dev_seq: |
|---|
| 629 | ts = "Could not find the required device: " + str(assigndeviceid) |
|---|
| 630 | ts += "\nAborting install" |
|---|
| 631 | errorMsg(self, ts) |
|---|
| 632 | return |
|---|
| 633 | |
|---|
| 634 | _devSeq = self.BuildDevSeq(absolute_name_DAS) |
|---|
| 635 | _applicationFactories = self.domMgr._get_applicationFactories() |
|---|
| 636 | |
|---|
| 637 | app_factory_num = -1 |
|---|
| 638 | for app_num in range(len(_applicationFactories)): |
|---|
| 639 | if _applicationFactories[app_num]._get_name()==app_name: |
|---|
| 640 | app_factory_num = app_num |
|---|
| 641 | break |
|---|
| 642 | |
|---|
| 643 | if app_factory_num == -1: |
|---|
| 644 | print "Application factory not found" |
|---|
| 645 | sys.exit(-1) |
|---|
| 646 | |
|---|
| 647 | try: |
|---|
| 648 | app = _applicationFactories[app_factory_num].create(_applicationFactories[app_factory_num]._get_name(),_appFacProps,_devSeq) |
|---|
| 649 | except: |
|---|
| 650 | print "Unable to create application - make sure that all appropriate nodes are installed" |
|---|
| 651 | return(None) |
|---|
| 652 | |
|---|
| 653 | # start the application |
|---|
| 654 | app.start() |
|---|
| 655 | |
|---|
| 656 | naming_context_list = app._get_componentNamingContexts() |
|---|
| 657 | naming_context = naming_context_list[0].elementId.split("/") |
|---|
| 658 | application_name = app._get_name() |
|---|
| 659 | waveform_name = naming_context[1] |
|---|
| 660 | |
|---|
| 661 | |
|---|
| 662 | # self.refreshDisplay() |
|---|
| 663 | self.DisplayInstalledWaveforms() |
|---|
| 664 | |
|---|
| 665 | |
|---|
| 666 | def InstallCompform(self): |
|---|
| 667 | print "WARNING: if your node's GPP UUID is not DCE:5ba336ee-aaaa-aaaa-aaaa-00123f573a7f this will not work...\n" |
|---|
| 668 | # get component name from the list |
|---|
| 669 | selection = self.componentsBox.GetSelection() |
|---|
| 670 | compName, compNameAndDir = self.componentsBox.GetPyData(selection) |
|---|
| 671 | |
|---|
| 672 | self.compform_counter = self.compform_counter + 1 |
|---|
| 673 | |
|---|
| 674 | tmp_dir_name = "/sdr/_tmp_alf_waveforms/" # this is where I put my temporary |
|---|
| 675 | # xml files |
|---|
| 676 | tmp_wave_name = "_" + compName + str(self.compform_counter) |
|---|
| 677 | |
|---|
| 678 | |
|---|
| 679 | #make the directory to put the XML |
|---|
| 680 | if os.path.exists(tmp_dir_name) == False: |
|---|
| 681 | try: |
|---|
| 682 | os.mkdir(tmp_dir_name) |
|---|
| 683 | except: |
|---|
| 684 | errorMsg(self,"Cannot create temporary directory in the waveform directory. You may need to change the temporary directory to one that you have write permissions to") |
|---|
| 685 | |
|---|
| 686 | if os.path.exists(tmp_dir_name + tmp_wave_name) == False: |
|---|
| 687 | try: |
|---|
| 688 | os.mkdir(tmp_dir_name + tmp_wave_name) |
|---|
| 689 | except: |
|---|
| 690 | errorMsg(self,"Cannot create temporary directory in the waveform directory. You may need to change the temporary directory to one that you have write permissions to") |
|---|
| 691 | return |
|---|
| 692 | |
|---|
| 693 | |
|---|
| 694 | # assumes that alf is in /sdr/tools |
|---|
| 695 | my_compform = compform.compform(compName, compNameAndDir, |
|---|
| 696 | tmp_dir_name, tmp_wave_name) |
|---|
| 697 | my_compform.create() |
|---|
| 698 | |
|---|
| 699 | |
|---|
| 700 | print "WARNING: tmp files generated in " + tmp_dir_name |
|---|
| 701 | |
|---|
| 702 | tmp_dir_name = tmp_dir_name + tmp_wave_name + "/" |
|---|
| 703 | self.InstallWaveform(tmp_wave_name + ".sad.xml", |
|---|
| 704 | tmp_dir_name + tmp_wave_name + ".sad.xml", |
|---|
| 705 | tmp_wave_name + "_DAS.xml", |
|---|
| 706 | tmp_dir_name + tmp_wave_name + "_DAS.xml") |
|---|
| 707 | |
|---|
| 708 | |
|---|
| 709 | |
|---|
| 710 | def UninstallWaveform(self): |
|---|
| 711 | selection = self.nsBox.GetSelection() |
|---|
| 712 | waveform_name = self.nsBox.GetItemText(selection) |
|---|
| 713 | if self.active_wave is not None: |
|---|
| 714 | if self.active_wave.naming_context == waveform_name: |
|---|
| 715 | self.refreshDisplay(True) |
|---|
| 716 | if self.waveform_displays.has_key(waveform_name): |
|---|
| 717 | # close any tool frames associated with waveform display |
|---|
| 718 | tmp_display = self.waveform_displays[waveform_name] |
|---|
| 719 | while len(tmp_display.tool_frames) > 0: |
|---|
| 720 | tf = tmp_display.tool_frames.pop() |
|---|
| 721 | tf.Close() |
|---|
| 722 | self.waveform_displays.pop(waveform_name) |
|---|
| 723 | app_ref = self.nsBox.GetPyData(selection) |
|---|
| 724 | # self.domMgr.uninstallApplication(app_ref._get_identifier()) # not sure if we need this or not |
|---|
| 725 | app_ref.releaseObject() |
|---|
| 726 | # self.refreshDisplay() |
|---|
| 727 | self.DisplayInstalledWaveforms() |
|---|
| 728 | |
|---|
| 729 | |
|---|
| 730 | def BuildDevSeq(self, dasXML): |
|---|
| 731 | doc_das = xml.dom.minidom.parse(dasXML) |
|---|
| 732 | |
|---|
| 733 | # create node list of "deviceassignmenttype" |
|---|
| 734 | deviceassignmenttypeNodeList = doc_das.getElementsByTagName("deviceassignmenttype") |
|---|
| 735 | |
|---|
| 736 | ds = [] |
|---|
| 737 | for n in deviceassignmenttypeNodeList: |
|---|
| 738 | componentid = n.getElementsByTagName("componentid")[0].firstChild.data |
|---|
| 739 | assigndeviceid = n.getElementsByTagName("assigndeviceid")[0].firstChild.data |
|---|
| 740 | ds.append(CF.DeviceAssignmentType(str(componentid),str(assigndeviceid))) |
|---|
| 741 | |
|---|
| 742 | return ds |
|---|
| 743 | |
|---|
| 744 | |
|---|
| 745 | #---------------------------------------------------------------------------- |
|---|
| 746 | # Waveform level controls and functions |
|---|
| 747 | #---------------------------------------------------------------------------- |
|---|
| 748 | def refreshDisplay(self, init = False): |
|---|
| 749 | # self.DisplayInstalledWaveforms() |
|---|
| 750 | |
|---|
| 751 | dc = wx.ClientDC(self.canvas) |
|---|
| 752 | self.canvas.PrepareDC(dc) |
|---|
| 753 | |
|---|
| 754 | if init: |
|---|
| 755 | if self.active_wave != None and self.timing_view_state: |
|---|
| 756 | for comp in self.active_wave.components: |
|---|
| 757 | for gauge in comp.shape.gauge_shapes: |
|---|
| 758 | gauge.gauge.Show(False) |
|---|
| 759 | |
|---|
| 760 | self.active_wave = None |
|---|
| 761 | self.timing_display = None |
|---|
| 762 | |
|---|
| 763 | self.canvas.diagram.RemoveAllShapes() |
|---|
| 764 | self.canvas.shapes = [] |
|---|
| 765 | |
|---|
| 766 | tb = self.GetToolBar() |
|---|
| 767 | tb.ToggleTool(wxID_TOOLBAR_TIMING_DISPLAY_TOOL, False) |
|---|
| 768 | self.timing_view_state = False |
|---|
| 769 | tb.SetToolShortHelp(wxID_TOOLBAR_TIMING_DISPLAY_TOOL, "Enable Timing Graphics") |
|---|
| 770 | tb.ToggleTool(wxID_TOOLBAR_TIMING_TOOL, False) |
|---|
| 771 | tb.SetToolShortHelp(wxID_TOOLBAR_TIMING_TOOL, "Enable Timing") |
|---|
| 772 | #self.canvas.diagram = ogl.Diagram() |
|---|
| 773 | #self.canvas.SetDiagram(self.canvas.diagram) |
|---|
| 774 | #self.canvas.diagram.SetCanvas(self.canvas) |
|---|
| 775 | |
|---|
| 776 | self.canvas.Refresh() |
|---|
| 777 | |
|---|
| 778 | def AddWaveformShape(self, waveform): |
|---|
| 779 | tmpdisplay = ALFshapes.WaveformShapes(waveform, self.canvas) |
|---|
| 780 | for comp in waveform.components: |
|---|
| 781 | tmpdisplay.AddComponentShape(comp) |
|---|
| 782 | tmpdisplay.ConnectComponents() |
|---|
| 783 | |
|---|
| 784 | return tmpdisplay |
|---|
| 785 | |
|---|
| 786 | |
|---|
| 787 | def updateWaveformData(self, data): |
|---|
| 788 | for d in data: |
|---|
| 789 | self.waveformData[d[0]] = d[1] |
|---|
| 790 | |
|---|
| 791 | self.last_waveform_data_update = self.waveformData.copy() |
|---|
| 792 | |
|---|
| 793 | for frame in self.tool_frames: |
|---|
| 794 | if hasattr(frame, 'updateWaveformData'): |
|---|
| 795 | frame.updateWaveformData(self.waveformData) |
|---|
| 796 | |
|---|
| 797 | def removeToolFrame(self, frame): |
|---|
| 798 | if frame not in self.tool_frames: |
|---|
| 799 | return |
|---|
| 800 | else: |
|---|
| 801 | index = self.tool_frames.index(frame) |
|---|
| 802 | del self.tool_frames[index] |
|---|
| 803 | |
|---|
| 804 | |
|---|
| 805 | |
|---|
| 806 | #---------------------------------------------------------------------- |
|---|
| 807 | class MainWindow(ogl.ShapeCanvas): |
|---|
| 808 | def __init__(self, parent, frame): |
|---|
| 809 | ogl.ShapeCanvas.__init__(self, parent) |
|---|
| 810 | |
|---|
| 811 | maxWidth = 2100 |
|---|
| 812 | maxHeight = 1000 |
|---|
| 813 | self.SetScrollbars(20, 20, maxWidth/20, maxHeight/20) |
|---|
| 814 | |
|---|
| 815 | self.frame = frame |
|---|
| 816 | self.SetBackgroundColour("LIGHT BLUE") #wxWHITE) |
|---|
| 817 | self.diagram = ogl.Diagram() |
|---|
| 818 | self.SetDiagram(self.diagram) |
|---|
| 819 | self.diagram.SetCanvas(self) |
|---|
| 820 | self.shapes = [] |
|---|
| 821 | |
|---|
| 822 | dsBrush = wx.Brush("WHEAT", wx.SOLID) |
|---|
| 823 | |
|---|
| 824 | def updateDisplay(self, waveformdisplay): |
|---|
| 825 | dc = wx.ClientDC(self) |
|---|
| 826 | self.PrepareDC(dc) |
|---|
| 827 | for compshape in waveformdisplay.shapes: |
|---|
| 828 | self.AddShape(compshape) |
|---|
| 829 | compshape.Show(True) |
|---|
| 830 | |
|---|
| 831 | self. diagram.Redraw(dc) |
|---|
| 832 | self.Refresh() |
|---|
| 833 | |
|---|
| 834 | def OnDestroy(self, evt): |
|---|
| 835 | # Do some cleanup |
|---|
| 836 | for shape in self.diagram.GetShapeList(): |
|---|
| 837 | if shape.GetParent() == None: |
|---|
| 838 | shape.SetCanvas(None) |
|---|
| 839 | shape.Destroy() |
|---|
| 840 | self.diagram.Destroy() |
|---|
| 841 | |
|---|
| 842 | |
|---|
| 843 | #---------------------------------------------------------------------- |
|---|
| 844 | |
|---|
| 845 | def errorMsg(self,msg): |
|---|
| 846 | dlg = wx.MessageDialog(self,msg,'Error', wx.OK | wx.ICON_INFORMATION) |
|---|
| 847 | try: |
|---|
| 848 | dlg.ShowModal() |
|---|
| 849 | finally: |
|---|
| 850 | dlg.Destroy() |
|---|
| 851 | return |
|---|
| 852 | |
|---|
| 853 | |
|---|
| 854 | def main(): |
|---|
| 855 | app = alfApp(0) |
|---|
| 856 | app.MainLoop() |
|---|
| 857 | |
|---|
| 858 | if __name__ == '__main__': |
|---|
| 859 | main() |
|---|