dialogs/BlockPreviewDialog.py
changeset 1242 ec2c415fc65e
parent 1241 368f8516706c
child 1244 336d515096b1
equal deleted inserted replaced
1241:368f8516706c 1242:ec2c415fc65e
    37 """
    37 """
    38 
    38 
    39 class BlockPreviewDialog(wx.Dialog):
    39 class BlockPreviewDialog(wx.Dialog):
    40 
    40 
    41     def __init__(self, parent, controller, tagname, size, title):
    41     def __init__(self, parent, controller, tagname, size, title):
       
    42         """
       
    43         Constructor
       
    44         @param parent: Parent wx.Window of dialog for modal
       
    45         @param controller: Reference to project controller
       
    46         @param tagname: Tagname of project POU edited
       
    47         @param size: wx.Size object containing size of dialog
       
    48         @param title: Title of dialog frame
       
    49         """
    42         wx.Dialog.__init__(self, parent, size=size, title=title)
    50         wx.Dialog.__init__(self, parent, size=size, title=title)
    43         
    51         
       
    52         # Save reference to
    44         self.Controller = controller
    53         self.Controller = controller
    45         self.TagName = tagname
    54         self.TagName = tagname
    46         
    55         
       
    56         # Label for preview
    47         self.PreviewLabel = wx.StaticText(self, label=_('Preview:'))
    57         self.PreviewLabel = wx.StaticText(self, label=_('Preview:'))
    48         
    58         
       
    59         # Create Preview panel
    49         self.Preview = wx.Panel(self, style=wx.SIMPLE_BORDER)
    60         self.Preview = wx.Panel(self, style=wx.SIMPLE_BORDER)
    50         self.Preview.SetBackgroundColour(wx.WHITE)
    61         self.Preview.SetBackgroundColour(wx.WHITE)
       
    62         
       
    63         # Add function to preview panel so that it answers to graphic elements
       
    64         # like Viewer
    51         setattr(self.Preview, "GetDrawingMode", lambda:FREEDRAWING_MODE)
    65         setattr(self.Preview, "GetDrawingMode", lambda:FREEDRAWING_MODE)
    52         setattr(self.Preview, "GetScaling", lambda:None)
    66         setattr(self.Preview, "GetScaling", lambda:None)
    53         setattr(self.Preview, "GetBlockType", controller.GetBlockType)
    67         setattr(self.Preview, "GetBlockType", controller.GetBlockType)
    54         setattr(self.Preview, "IsOfType", controller.IsOfType)
    68         setattr(self.Preview, "IsOfType", controller.IsOfType)
       
    69         
       
    70         # Bind paint event on Preview panel
    55         self.Preview.Bind(wx.EVT_PAINT, self.OnPaint)
    71         self.Preview.Bind(wx.EVT_PAINT, self.OnPaint)
    56         
    72         
       
    73         # Add default dialog buttons sizer
    57         self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE)
    74         self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE)
    58         self.Bind(wx.EVT_BUTTON, self.OnOK, 
    75         self.Bind(wx.EVT_BUTTON, self.OnOK, 
    59                   self.ButtonSizer.GetAffirmativeButton())
    76                   self.ButtonSizer.GetAffirmativeButton())
    60         
    77         
    61         self.Block = None
    78         self.Block = None            # Graphic element to display in preview
    62         self.DefaultBlockName = None
    79         self.MinBlockSize = None     # Graphic element minimal size
    63         self.MinBlockSize = None
    80         self.DefaultBlockName = None # Graphic element name when opening dialog
    64     
    81         
    65     def __del__(self):
    82     def __del__(self):
       
    83         """
       
    84         Destructor
       
    85         """
       
    86         # Remove reference to project controller
    66         self.Controller = None
    87         self.Controller = None
    67     
    88     
    68     def SetMinBlockSize(self, size):
    89     def SetMinBlockSize(self, size):
       
    90         """
       
    91         Define minimal graphic element size
       
    92         @param size: wx.Size object containing minimal size
       
    93         """
    69         self.MinBlockSize = size
    94         self.MinBlockSize = size
    70     
    95     
    71     def SetPreviewFont(self, font):
    96     def SetPreviewFont(self, font):
       
    97         """
       
    98         Set font of Preview panel
       
    99         @param font: wx.Font object containing font style
       
   100         """
    72         self.Preview.SetFont(font)
   101         self.Preview.SetFont(font)
    73     
   102     
    74     def TestBlockName(self, block_name):
   103     def TestBlockName(self, block_name):
    75         format = None
   104         """
       
   105         Text displayed graphic element name
       
   106         @param block_name: Graphic element name
       
   107         """
       
   108         # Variable containing error message format
       
   109         message_format = None
       
   110         # Get graphic element name in upper case
    76         uppercase_block_name = block_name.upper()
   111         uppercase_block_name = block_name.upper()
       
   112         
       
   113         # Test if graphic element name is a valid identifier
    77         if not TestIdentifier(block_name):
   114         if not TestIdentifier(block_name):
    78             format = _("\"%s\" is not a valid identifier!")
   115             message_format = _("\"%s\" is not a valid identifier!")
       
   116         
       
   117         # Test that graphic element name isn't a keyword
    79         elif uppercase_block_name in IEC_KEYWORDS:
   118         elif uppercase_block_name in IEC_KEYWORDS:
    80             format = _("\"%s\" is a keyword. It can't be used!")
   119             message_format = _("\"%s\" is a keyword. It can't be used!")
       
   120         
       
   121         # Test that graphic element name isn't a POU name
    81         elif uppercase_block_name in self.Controller.GetProjectPouNames():
   122         elif uppercase_block_name in self.Controller.GetProjectPouNames():
    82             format = _("\"%s\" pou already exists!")
   123             message_format = _("\"%s\" pou already exists!")
       
   124         
       
   125         # Test that graphic element name isn't already used in POU by a variable
       
   126         # or another graphic element
    83         elif ((self.DefaultBlockName is None or 
   127         elif ((self.DefaultBlockName is None or 
    84                self.DefaultBlockName.upper() != uppercase_block_name) and 
   128                self.DefaultBlockName.upper() != uppercase_block_name) and 
    85               uppercase_block_name in self.Controller.GetEditedElementVariables(
   129               uppercase_block_name in self.Controller.GetEditedElementVariables(
    86                                                                 self.TagName)):
   130                                                                 self.TagName)):
    87             format = _("\"%s\" element for this pou already exists!")
   131             message_format = _("\"%s\" element for this pou already exists!")
    88         
   132         
    89         if format is not None:
   133         # If an error have been identify, show error message dialog
    90             self.ShowErrorMessage(format % block_name)
   134         if message_format is not None:
       
   135             self.ShowErrorMessage(message_format % block_name)
       
   136             # Test failed
    91             return False
   137             return False
    92         
   138         
       
   139         # Test succeed
    93         return True
   140         return True
    94     
   141     
    95     def ShowErrorMessage(self, message):
   142     def ShowErrorMessage(self, message):
       
   143         """
       
   144         Show an error message dialog over this dialog
       
   145         @param message: Error message to display
       
   146         """
    96         dialog = wx.MessageDialog(self, message, 
   147         dialog = wx.MessageDialog(self, message, 
    97                                   _("Error"), 
   148                                   _("Error"), 
    98                                   wx.OK|wx.ICON_ERROR)
   149                                   wx.OK|wx.ICON_ERROR)
    99         dialog.ShowModal()
   150         dialog.ShowModal()
   100         dialog.Destroy()
   151         dialog.Destroy()
   101     
   152     
   102     def OnOK(self, event):
   153     def OnOK(self, event):
       
   154         """
       
   155         Called when dialog OK button is pressed
       
   156         Need to be overridden by inherited classes to check that dialog values
       
   157         are valid
       
   158         @param event: wx.Event from OK button
       
   159         """
       
   160         # Close dialog
   103         self.EndModal(wx.ID_OK)
   161         self.EndModal(wx.ID_OK)
   104     
   162     
   105     def RefreshPreview(self):
   163     def RefreshPreview(self):
       
   164         """
       
   165         Refresh preview panel of graphic element
       
   166         May be overridden by inherited classes
       
   167         """
       
   168         # Init preview panel paint device context
   106         dc = wx.ClientDC(self.Preview)
   169         dc = wx.ClientDC(self.Preview)
   107         dc.SetFont(self.Preview.GetFont())
   170         dc.SetFont(self.Preview.GetFont())
   108         dc.Clear()
   171         dc.Clear()
   109         
   172         
   110         if self.Block is not None:
   173         # Return immediately if no graphic element defined
   111             min_width, min_height = self.Block.GetMinSize()
   174         if self.Block is None:
   112             width = max(self.MinBlockSize[0], min_width)
   175             return
   113             height = max(self.MinBlockSize[1], min_height)
   176         
   114             self.Block.SetSize(width, height)
   177         # Calculate block size according to graphic element min size due to its
   115             client_size = self.Preview.GetClientSize()
   178         # parameters and graphic element min size defined
   116             if (width * 1.2 > client_size.width or 
   179         min_width, min_height = self.Block.GetMinSize()
   117                 height * 1.2 > client_size.height):
   180         width = max(self.MinBlockSize[0], min_width)
   118                 scale = max(float(width) / client_size.width,
   181         height = max(self.MinBlockSize[1], min_height)
   119                             float(height) / client_size.height) * 1.2
   182         self.Block.SetSize(width, height)
   120                 x = int(client_size.width * scale - width) / 2
   183         
   121                 y = int(client_size.height * scale - height) / 2
   184         # Get Preview panel size
   122             else:
   185         client_size = self.Preview.GetClientSize()
   123                 x = (client_size.width - width) / 2
   186         
   124                 y = (client_size.height - height) / 2
   187         # If graphic element is too big to be displayed in preview panel,
   125                 scale = 1.0
   188         # calculate preview panel scale so that graphic element fit inside
   126             dc.SetUserScale(1.0 / scale, 1.0 / scale)
   189         scale = (max(float(width) / client_size.width, 
   127             self.Block.SetPosition(x, y)
   190                      float(height) / client_size.height) * 1.2
   128             self.Block.Draw(dc)
   191                  if width * 1.2 > client_size.width or 
       
   192                     height * 1.2 > client_size.height
       
   193                  else 1.0)
       
   194         dc.SetUserScale(1.0 / scale, 1.0 / scale)
       
   195         
       
   196         # Center graphic element in preview panel
       
   197         x = int(client_size.width * scale - width) / 2
       
   198         y = int(client_size.height * scale - height) / 2
       
   199         self.Block.SetPosition(x, y)
       
   200         
       
   201         # Draw graphic element
       
   202         self.Block.Draw(dc)
   129     
   203     
   130     def OnPaint(self, event):
   204     def OnPaint(self, event):
       
   205         """
       
   206         Called when Preview panel need to be redraw
       
   207         @param event: wx.PaintEvent
       
   208         """
   131         self.RefreshPreview()
   209         self.RefreshPreview()
   132         event.Skip()
   210         event.Skip()
   133         
   211