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 |