232 """ |
232 """ |
233 Class that implements a Viewer based on a wx.ScrolledWindow for drawing and |
233 Class that implements a Viewer based on a wx.ScrolledWindow for drawing and |
234 manipulating graphic elements |
234 manipulating graphic elements |
235 """ |
235 """ |
236 |
236 |
237 class Viewer(wx.ScrolledWindow): |
237 class Viewer(wx.ScrolledWindow, DebugViewer): |
238 |
238 |
239 if wx.VERSION < (2, 6, 0): |
239 if wx.VERSION < (2, 6, 0): |
240 def Bind(self, event, function, id = None): |
240 def Bind(self, event, function, id = None): |
241 if id is not None: |
241 if id is not None: |
242 event(self, id, function) |
242 event(self, id, function) |
342 |
342 |
343 # Create a new Viewer |
343 # Create a new Viewer |
344 def __init__(self, parent, tagname, window, controler, debug = False, instancepath = ""): |
344 def __init__(self, parent, tagname, window, controler, debug = False, instancepath = ""): |
345 wx.ScrolledWindow.__init__(self, parent, pos=wx.Point(0, 0), size=wx.Size(0, 0), |
345 wx.ScrolledWindow.__init__(self, parent, pos=wx.Point(0, 0), size=wx.Size(0, 0), |
346 style=wx.HSCROLL | wx.VSCROLL | wx.ALWAYS_SHOW_SB) |
346 style=wx.HSCROLL | wx.VSCROLL | wx.ALWAYS_SHOW_SB) |
|
347 DebugViewer.__init__(self, controler, debug) |
347 self._init_menus() |
348 self._init_menus() |
348 # Adding a rubberband to Viewer |
349 # Adding a rubberband to Viewer |
349 self.rubberBand = RubberBand(drawingSurface=self) |
350 self.rubberBand = RubberBand(drawingSurface=self) |
350 self.SetBackgroundColour(wx.Colour(255,255,255)) |
351 self.SetBackgroundColour(wx.Colour(255,255,255)) |
351 self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM) |
352 self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM) |
357 self.PagePen = wx.TRANSPARENT_PEN |
358 self.PagePen = wx.TRANSPARENT_PEN |
358 self.DrawingWire = False |
359 self.DrawingWire = False |
359 self.current_id = 0 |
360 self.current_id = 0 |
360 self.TagName = tagname |
361 self.TagName = tagname |
361 self.Errors = [] |
362 self.Errors = [] |
362 self.Debug = debug |
|
363 self.InstancePath = instancepath |
363 self.InstancePath = instancepath |
364 self.StartMousePos = None |
364 self.StartMousePos = None |
365 self.StartScreenPos = None |
365 self.StartScreenPos = None |
366 |
366 |
367 # Initialize Block, Wire and Comment numbers |
367 # Initialize Block, Wire and Comment numbers |
375 self.ParentWindow = window |
375 self.ParentWindow = window |
376 self.Controler = controler |
376 self.Controler = controler |
377 |
377 |
378 if not self.Debug: |
378 if not self.Debug: |
379 self.SetDropTarget(ViewerDropTarget(self)) |
379 self.SetDropTarget(ViewerDropTarget(self)) |
|
380 |
|
381 self.NewDataRefreshRect = None |
380 |
382 |
381 dc = wx.ClientDC(self) |
383 dc = wx.ClientDC(self) |
382 font = wx.Font(faces["size"], wx.SWISS, wx.NORMAL, wx.NORMAL, faceName = faces["mono"]) |
384 font = wx.Font(faces["size"], wx.SWISS, wx.NORMAL, wx.NORMAL, faceName = faces["mono"]) |
383 dc.SetFont(font) |
385 dc.SetFont(font) |
384 width, height = dc.GetTextExtent("ABCDEFGHIJKLMNOPQRSTUVWXYZ") |
386 width, height = dc.GetTextExtent("ABCDEFGHIJKLMNOPQRSTUVWXYZ") |
386 faces["size"] -= 1 |
388 faces["size"] -= 1 |
387 font = wx.Font(faces["size"], wx.SWISS, wx.NORMAL, wx.NORMAL, faceName = faces["mono"]) |
389 font = wx.Font(faces["size"], wx.SWISS, wx.NORMAL, wx.NORMAL, faceName = faces["mono"]) |
388 dc.SetFont(font) |
390 dc.SetFont(font) |
389 width, height = dc.GetTextExtent("ABCDEFGHIJKLMNOPQRSTUVWXYZ") |
391 width, height = dc.GetTextExtent("ABCDEFGHIJKLMNOPQRSTUVWXYZ") |
390 self.SetFont(font) |
392 self.SetFont(font) |
|
393 self.MiniTextDC = wx.MemoryDC() |
|
394 self.MiniTextDC.SetFont(wx.Font(faces["size"] * 0.75, wx.SWISS, wx.NORMAL, wx.NORMAL, faceName = faces["helv"])) |
391 |
395 |
392 self.SetScale(len(ZOOM_FACTORS) / 2) |
396 self.SetScale(len(ZOOM_FACTORS) / 2) |
393 |
397 |
394 self.ResetView() |
398 self.ResetView() |
395 |
399 |
465 else: |
470 else: |
466 self.PrepareDC(dc) |
471 self.PrepareDC(dc) |
467 dc.SetUserScale(self.ViewScale[0], self.ViewScale[1]) |
472 dc.SetUserScale(self.ViewScale[0], self.ViewScale[1]) |
468 return dc |
473 return dc |
469 |
474 |
|
475 def GetMiniTextExtent(self, text): |
|
476 return self.MiniTextDC.GetTextExtent(text) |
|
477 |
470 def GetMiniFont(self): |
478 def GetMiniFont(self): |
471 font = self.GetFont() |
479 return self.MiniTextDC.GetFont() |
472 return wx.Font(font.GetPointSize() * 0.75, wx.SWISS, wx.NORMAL, wx.NORMAL, faceName = faces["helv"]) |
480 |
473 |
|
474 #------------------------------------------------------------------------------- |
481 #------------------------------------------------------------------------------- |
475 # Element management functions |
482 # Element management functions |
476 #------------------------------------------------------------------------------- |
483 #------------------------------------------------------------------------------- |
477 |
484 |
478 def AddBlock(self, block): |
485 def AddBlock(self, block): |
547 iec_path = "%s.%s%d"%(self.InstancePath, block.GetType(), block.GetId()) |
554 iec_path = "%s.%s%d"%(self.InstancePath, block.GetType(), block.GetId()) |
548 else: |
555 else: |
549 iec_path = "%s.%s%d_%s"%(self.InstancePath, block.GetType(), block.GetId(), connectorname) |
556 iec_path = "%s.%s%d_%s"%(self.InstancePath, block.GetType(), block.GetId(), connectorname) |
550 elif isinstance(block, FBD_Variable): |
557 elif isinstance(block, FBD_Variable): |
551 iec_path = "%s.%s"%(self.InstancePath, block.GetName()) |
558 iec_path = "%s.%s"%(self.InstancePath, block.GetName()) |
552 elif isinstance(element, (LD_Contact, LD_Coil)): |
559 elif isinstance(element, LD_Contact): |
553 iec_path = "%s.%s"%(self.InstancePath, element.GetName()) |
560 iec_path = "%s.%s"%(self.InstancePath, element.GetName()) |
554 elif isinstance(element, SFC_Step): |
561 elif isinstance(element, SFC_Step): |
555 iec_path = "%s.%s.X"%(self.InstancePath, element.GetName()) |
562 iec_path = "%s.%s.X"%(self.InstancePath, element.GetName()) |
556 elif isinstance(element, SFC_Transition): |
563 elif isinstance(element, SFC_Transition): |
557 connectors = element.GetConnectors() |
564 connectors = element.GetConnectors() |
572 self.Subscribed = {} |
579 self.Subscribed = {} |
573 self.SelectedElement = None |
580 self.SelectedElement = None |
574 self.HighlightedElement = None |
581 self.HighlightedElement = None |
575 |
582 |
576 def Flush(self): |
583 def Flush(self): |
577 for element, iec_path in self.Subscribed.iteritems(): |
584 self.DeleteDataConsumers() |
578 self.Controler.UnsubscribeDebugIECVariable(iec_path, element) |
|
579 for block in self.Blocks: |
585 for block in self.Blocks: |
580 block.Flush() |
586 block.Flush() |
581 |
587 |
582 # Remove all elements |
588 # Remove all elements |
583 def CleanView(self): |
589 def CleanView(self): |
640 |
646 |
641 |
647 |
642 #------------------------------------------------------------------------------- |
648 #------------------------------------------------------------------------------- |
643 # Refresh functions |
649 # Refresh functions |
644 #------------------------------------------------------------------------------- |
650 #------------------------------------------------------------------------------- |
|
651 |
|
652 def UpdateRefreshRect(self, refresh_rect): |
|
653 if self.NewDataRefreshRect is None: |
|
654 self.NewDataRefreshRect = refresh_rect |
|
655 else: |
|
656 self.NewDataRefreshRect.Union(refresh_rect) |
|
657 |
|
658 def RefreshNewData(self): |
|
659 if self.NewDataRefreshRect is not None: |
|
660 refresh_rect, self.NewDataRefreshRect = self.NewDataRefreshRect, None |
|
661 self.RefreshRect(self.GetScrolledRect(refresh_rect), False) |
|
662 DebugViewer.RefreshNewData(self) |
645 |
663 |
646 def ResetBuffer(self): |
664 def ResetBuffer(self): |
647 pass |
665 pass |
648 |
666 |
649 # Refresh Viewer elements |
667 # Refresh Viewer elements |
677 else: |
695 else: |
678 if connectorname == "": |
696 if connectorname == "": |
679 iec_path = "%s.%s%d"%(self.InstancePath, block.GetType(), block.GetId()) |
697 iec_path = "%s.%s%d"%(self.InstancePath, block.GetType(), block.GetId()) |
680 else: |
698 else: |
681 iec_path = "%s.%s%d_%s"%(self.InstancePath, block.GetType(), block.GetId(), connectorname) |
699 iec_path = "%s.%s%d_%s"%(self.InstancePath, block.GetType(), block.GetId(), connectorname) |
682 if self.Controler.SubscribeDebugIECVariable(iec_path.upper(), wire) is not None: |
700 if self.AddDataConsumer(iec_path.upper(), wire) is None: |
683 self.Subscribed[wire] = iec_path.upper() |
|
684 else: |
|
685 wire.SetValue("undefined") |
701 wire.SetValue("undefined") |
686 elif isinstance(block, FBD_Variable): |
702 elif isinstance(block, FBD_Variable): |
687 iec_path = "%s.%s"%(self.InstancePath, block.GetName()) |
703 iec_path = "%s.%s"%(self.InstancePath, block.GetName()) |
688 if self.Controler.SubscribeDebugIECVariable(iec_path.upper(), wire) is not None: |
704 if self.AddDataConsumer(iec_path.upper(), wire) is None: |
689 self.Subscribed[wire] = iec_path.upper() |
|
690 else: |
|
691 wire.SetValue("undefined") |
705 wire.SetValue("undefined") |
692 elif isinstance(block, FBD_Connector): |
706 elif isinstance(block, FBD_Connector): |
693 wire.SetValue("undefined") |
707 wire.SetValue("undefined") |
694 |
708 |
695 if self.Debug: |
709 if self.Debug: |
696 for block in self.Blocks.keys(): |
710 for block in self.Blocks.keys(): |
697 block.SpreadCurrent() |
711 block.SpreadCurrent() |
698 iec_path = self.GetElementIECPath(block) |
712 iec_path = self.GetElementIECPath(block) |
699 if iec_path is not None: |
713 if iec_path is not None: |
700 result = self.Controler.SubscribeDebugIECVariable(iec_path.upper(), block) |
714 self.AddDataConsumer(iec_path.upper(), block) |
701 if result is not None: |
715 |
702 self.Subscribed[block] = iec_path.upper() |
|
703 |
|
704 self.RefreshVisibleElements() |
716 self.RefreshVisibleElements() |
705 self.ShowErrors() |
717 self.ShowErrors() |
706 self.Refresh(False) |
718 self.Refresh(False) |
707 |
719 |
708 def GetPreviousSteps(self, connector): |
720 def GetPreviousSteps(self, connector): |
2685 names = exclude.copy() |
2697 names = exclude.copy() |
2686 if isinstance(element, FBD_Block): |
2698 if isinstance(element, FBD_Block): |
2687 names.update(dict([(varname.upper(), True) for varname in self.Controler.GetEditedElementVariables(self.TagName, self.Debug)])) |
2699 names.update(dict([(varname.upper(), True) for varname in self.Controler.GetEditedElementVariables(self.TagName, self.Debug)])) |
2688 format = "Block%d" |
2700 format = "Block%d" |
2689 elif isinstance(element, SFC_Step): |
2701 elif isinstance(element, SFC_Step): |
2690 names.update(dict([block.GetName().upper() for block in self.Blocks if isinstance(block, SFC_Step)])) |
2702 names.update(dict([(block.GetName().upper(), True) for block in self.Blocks if isinstance(block, SFC_Step)])) |
2691 format = "Step%d" |
2703 format = "Step%d" |
2692 i = 1 |
2704 i = 1 |
2693 while names.get((format%i).upper(), False): |
2705 while names.get((format%i).upper(), False): |
2694 i += 1 |
2706 i += 1 |
2695 return format%i |
2707 return format%i |