controls/ProjectPropertiesPanel.py
changeset 700 cf3db1775105
child 702 ece862b07321
equal deleted inserted replaced
699:649399ffdaf0 700:cf3db1775105
       
     1 #!/usr/bin/env python
       
     2 # -*- coding: utf-8 -*-
       
     3 
       
     4 #This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor
       
     5 #based on the plcopen standard. 
       
     6 #
       
     7 #Copyright (C) 2012: Edouard TISSERANT and Laurent BESSARD
       
     8 #
       
     9 #See COPYING file for copyrights details.
       
    10 #
       
    11 #This library is free software; you can redistribute it and/or
       
    12 #modify it under the terms of the GNU General Public
       
    13 #License as published by the Free Software Foundation; either
       
    14 #version 2.1 of the License, or (at your option) any later version.
       
    15 #
       
    16 #This library is distributed in the hope that it will be useful,
       
    17 #but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    18 #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       
    19 #General Public License for more details.
       
    20 #
       
    21 #You should have received a copy of the GNU General Public
       
    22 #License along with this library; if not, write to the Free Software
       
    23 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
       
    24 
       
    25 import wx
       
    26 
       
    27 REQUIRED_PARAMS = ["projectName", "productName", "productVersion", "companyName"]
       
    28 
       
    29 class ProjectPropertiesPanel(wx.Notebook):
       
    30     
       
    31     def AddSizerParams(self, parent, sizer, params):
       
    32         for idx, (name, label) in enumerate(params):
       
    33             border = 0
       
    34             if idx == 0:
       
    35                 border |= wx.TOP
       
    36             elif idx == len(params) - 1:
       
    37                 border |= wx.BOTTOM
       
    38             
       
    39             st = wx.StaticText(id=-1, parent=parent, 
       
    40                   label=label, name=name + '_label',
       
    41                   pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
       
    42             sizer.AddWindow(st, 0, border=10, flag=wx.ALIGN_CENTER_VERTICAL|border|wx.LEFT)
       
    43             
       
    44             tc_id = wx.NewId()
       
    45             tc = wx.TextCtrl(id=tc_id, parent=parent, 
       
    46                   name=name, pos=wx.Point(0, 0), 
       
    47                   size=wx.Size(0, 24), style=wx.TE_PROCESS_ENTER)
       
    48             setattr(self, name, tc)
       
    49             callback = self.GetTextCtrlChangedFunction(tc, name)
       
    50             self.Bind(wx.EVT_TEXT_ENTER, callback, id=tc_id)
       
    51             tc.Bind(wx.EVT_KILL_FOCUS, callback)
       
    52             sizer.AddWindow(tc, 0, border=10, flag=wx.GROW|border|wx.RIGHT)
       
    53 
       
    54     def __init__(self, parent, controller=None, window=None, enable_required=True):
       
    55         wx.Notebook.__init__(self, id=-1, parent=parent, 
       
    56               name='ProjectPropertiesPanel', style=0, 
       
    57               pos=wx.Point(0, 0), size=wx.Size(500, 300))
       
    58 
       
    59         self.Controller = controller
       
    60         self.ParentWindow = window
       
    61         self.Values = None
       
    62         
       
    63         # Project Panel elements
       
    64 
       
    65         self.ProjectPanel = wx.Panel(id=-1, parent=self, 
       
    66               name='ProjectPanel', pos=wx.Point(0, 0),
       
    67               size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL)
       
    68         projectpanel_sizer = wx.FlexGridSizer(cols=2, hgap=5, rows=5, vgap=15)
       
    69         projectpanel_sizer.AddGrowableCol(1)
       
    70         self.ProjectPanel.SetSizer(projectpanel_sizer)
       
    71         
       
    72         self.AddSizerParams(self.ProjectPanel, projectpanel_sizer,
       
    73               [("projectName", _('Project Name (required):')),
       
    74                ("projectVersion", _('Project Version (optional):')),
       
    75                ("productName", _('Product Name (required):')),
       
    76                ("productVersion", _('Product Version (required):')),
       
    77                ("productRelease", _('Product Release (optional):'))])
       
    78         
       
    79         self.AddPage(self.ProjectPanel, _("Project"))
       
    80         
       
    81         # Author Panel elements
       
    82 
       
    83         self.AuthorPanel = wx.Panel(id=-1, parent=self,
       
    84               name='AuthorPanel', pos=wx.Point(0, 0),
       
    85               size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL)
       
    86         authorpanel_sizer = wx.FlexGridSizer(cols=2, hgap=5, rows=4, vgap=15)
       
    87         authorpanel_sizer.AddGrowableCol(1)
       
    88         self.AuthorPanel.SetSizer(authorpanel_sizer)
       
    89         
       
    90         self.AddSizerParams(self.AuthorPanel, authorpanel_sizer,
       
    91               [("companyName", _('Company Name (required):')),
       
    92                ("companyURL", _('Company URL (optional):')),
       
    93                ("authorName", _('Author Name (optional):')),
       
    94                ("organization", _('Organization (optional):'))])
       
    95         
       
    96         self.AddPage(self.AuthorPanel, _("Author"))
       
    97 
       
    98         # Graphics Panel elements
       
    99 
       
   100         self.GraphicsPanel = wx.Panel(id=-1, parent=self, 
       
   101               name='GraphicsPanel', pos=wx.Point(0, 0),
       
   102               size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL)
       
   103         graphicpanel_sizer = wx.FlexGridSizer(cols=1, hgap=5, rows=4, vgap=5)
       
   104         graphicpanel_sizer.AddGrowableCol(0)
       
   105         graphicpanel_sizer.AddGrowableRow(3)
       
   106         self.GraphicsPanel.SetSizer(graphicpanel_sizer)
       
   107         
       
   108         pageSize_st = wx.StaticText(id=-1, parent=self.GraphicsPanel,
       
   109               label=_('Page Size (optional):'), name='pageSize_label', 
       
   110               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
       
   111         graphicpanel_sizer.AddWindow(pageSize_st, 0, border=10, flag=wx.ALIGN_CENTER_VERTICAL|wx.TOP|wx.LEFT|wx.RIGHT)
       
   112         
       
   113         pageSize_sizer = wx.FlexGridSizer(cols=2, hgap=5, rows=2, vgap=5)
       
   114         pageSize_sizer.AddGrowableCol(1)
       
   115         graphicpanel_sizer.AddSizer(pageSize_sizer, 0, border=10, flag=wx.GROW|wx.LEFT|wx.RIGHT)
       
   116         
       
   117         for name, label in [('PageWidth', _('Width:')),
       
   118                             ('PageHeight', _('Height:'))]:
       
   119             st = wx.StaticText(id=-1, parent=self.GraphicsPanel,
       
   120                   label=label, name=name + "_label",
       
   121                   pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
       
   122             pageSize_sizer.AddWindow(st, 0, border=12, flag=wx.ALIGN_CENTER_VERTICAL|wx.LEFT)
       
   123             
       
   124             sp_id = wx.NewId()
       
   125             sp = wx.SpinCtrl(id=sp_id, parent=self.GraphicsPanel, 
       
   126                   name=name, pos=wx.Point(0, 0),
       
   127                   size=wx.Size(0, 24), style=wx.TE_PROCESS_ENTER, 
       
   128                   min=0, max=2**16)
       
   129             setattr(self, name, sp)
       
   130             callback = self.GetPageSizeChangedFunction(sp, name)
       
   131             self.Bind(wx.EVT_TEXT_ENTER, callback, id=sp_id)
       
   132             sp.Bind(wx.EVT_KILL_FOCUS, callback)
       
   133             pageSize_sizer.AddWindow(sp, 0, border=0, flag=wx.GROW)
       
   134         
       
   135         scaling_st = wx.StaticText(id=-1, parent=self.GraphicsPanel,
       
   136               label=_('Grid Resolution:'), name='scaling_label', 
       
   137               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
       
   138         graphicpanel_sizer.AddWindow(scaling_st, 0, border=10, flag=wx.GROW|wx.LEFT|wx.RIGHT)
       
   139         
       
   140         scaling_nb = wx.Notebook(id=-1, parent=self.GraphicsPanel, 
       
   141               name='ScalingNotebook', pos=wx.Point(0, 0), 
       
   142               size=wx.Size(0, 0), style=0)
       
   143         graphicpanel_sizer.AddWindow(scaling_nb, 0, border=10, flag=wx.GROW|wx.BOTTOM|wx.LEFT|wx.RIGHT)
       
   144         
       
   145         self.Scalings = {}
       
   146         for language, translation in [("FBD",_("FBD")), ("LD",_("LD")), ("SFC",_("SFC"))]:
       
   147             scaling_panel = wx.Panel(id=-1, parent=scaling_nb, 
       
   148                   name=language + '_panel', pos=wx.Point(0, 0),
       
   149                   size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL)
       
   150             scalingpanel_sizer = wx.FlexGridSizer(cols=2, hgap=5, rows=2, vgap=5)
       
   151             scalingpanel_sizer.AddGrowableCol(1)
       
   152             scaling_panel.SetSizer(scalingpanel_sizer)
       
   153             
       
   154             scaling_controls = []
       
   155             for idx, (name, label) in enumerate([('XScale', _('Horizontal:')),
       
   156                                                  ('YScale', _('Vertical:'))]):
       
   157                 if idx == 0:
       
   158                     border = wx.TOP
       
   159                 else:
       
   160                     border = wx.BOTTOM
       
   161                 
       
   162                 st = wx.StaticText(id=-1, parent=scaling_panel,
       
   163                       label=label, name=name + '_label', 
       
   164                       pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
       
   165                 scalingpanel_sizer.AddWindow(st, 0, border=10, flag=wx.ALIGN_CENTER_VERTICAL|border|wx.LEFT)
       
   166                 
       
   167                 sp_id = wx.NewId()
       
   168                 sp = wx.SpinCtrl(id=sp_id, parent=scaling_panel, 
       
   169                       name=name, pos=wx.Point(0, 0),
       
   170                       size=wx.Size(0, 24), style=wx.TE_PROCESS_ENTER, 
       
   171                       min=0, max=2**16)
       
   172                 scaling_controls.append(sp)
       
   173                 callback = self.GetScalingChangedFunction(sp, language, name)
       
   174                 self.Bind(wx.EVT_TEXT_ENTER, callback, id=sp_id)
       
   175                 sp.Bind(wx.EVT_KILL_FOCUS, callback)
       
   176                 scalingpanel_sizer.AddWindow(sp, 0, border=10, flag=wx.GROW|border|wx.RIGHT)
       
   177         
       
   178             self.Scalings[language] = scaling_controls
       
   179             scaling_nb.AddPage(scaling_panel, translation)
       
   180         
       
   181         self.AddPage(self.GraphicsPanel, _("Graphics"))
       
   182 
       
   183         # Miscellaneous Panel elements
       
   184 
       
   185         self.MiscellaneousPanel = wx.Panel(id=-1, parent=self, 
       
   186               name='MiscellaneousPanel', pos=wx.Point(0, 0),
       
   187               size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL)
       
   188         miscellaneouspanel_sizer = wx.FlexGridSizer(cols=2, hgap=5, rows=2, vgap=15)
       
   189         miscellaneouspanel_sizer.AddGrowableCol(1)
       
   190         miscellaneouspanel_sizer.AddGrowableRow(1)
       
   191         self.MiscellaneousPanel.SetSizer(miscellaneouspanel_sizer)
       
   192         
       
   193         language_label = wx.StaticText(id=-1, parent=self.MiscellaneousPanel,
       
   194               label=_('Language (optional):'), name='language_label', 
       
   195               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
       
   196         miscellaneouspanel_sizer.AddWindow(language_label, 0, border=10, flag=wx.ALIGN_CENTER_VERTICAL|wx.TOP|wx.LEFT)
       
   197         
       
   198         language_id = wx.NewId()
       
   199         self.Language = wx.ComboBox(id=language_id, parent=self.MiscellaneousPanel, 
       
   200               name='Language', pos=wx.Point(0, 0),
       
   201               size=wx.Size(0, 28), style=wx.CB_READONLY)
       
   202         self.Bind(wx.EVT_COMBOBOX, self.OnLanguageChanged, id=language_id)
       
   203         miscellaneouspanel_sizer.AddWindow(self.Language, 0, border=10, flag=wx.GROW|wx.TOP|wx.RIGHT)
       
   204         
       
   205         description_label = wx.StaticText(id=-1, parent=self.MiscellaneousPanel,
       
   206               label=_('Content Description (optional):'), name='description_label', 
       
   207               pos=wx.Point(0, 0), size=wx.DefaultSize, style=0)
       
   208         miscellaneouspanel_sizer.AddWindow(description_label, 0, border=10, flag=wx.BOTTOM|wx.LEFT)
       
   209         
       
   210         description_id = wx.NewId()
       
   211         self.ContentDescription = wx.TextCtrl(id=description_id, parent=self.MiscellaneousPanel, 
       
   212               name='ContentDescription', pos=wx.Point(0, 0),
       
   213               size=wx.Size(0, 24), style=wx.TE_MULTILINE|wx.TE_PROCESS_ENTER)
       
   214         self.Bind(wx.EVT_TEXT_ENTER, self.OnContentDescriptionChanged, id=description_id)
       
   215         self.ContentDescription.Bind(wx.EVT_KILL_FOCUS, self.OnContentDescriptionChanged)
       
   216         miscellaneouspanel_sizer.AddWindow(self.ContentDescription, 0, border=10, flag=wx.GROW|wx.BOTTOM|wx.RIGHT)
       
   217         
       
   218         self.AddPage(self.MiscellaneousPanel, _("Miscellaneous"))
       
   219         
       
   220         for param in REQUIRED_PARAMS:
       
   221             getattr(self, param).Enable(enable_required)
       
   222            
       
   223         languages = ["", "en-US", "fr-FR", "zh-CN"]
       
   224         
       
   225         for language in languages:
       
   226             self.Language.Append(language)
       
   227 
       
   228     def RefreshView(self):
       
   229         if self.Controller is not None:
       
   230             self.SetValues(self.Controller.GetProjectProperties())
       
   231 
       
   232     def SetValues(self, values):
       
   233         self.Values = values
       
   234         for item, value in values.items():
       
   235             if item == "language":
       
   236                 self.Language.SetStringSelection(value)
       
   237             elif item == "contentDescription":
       
   238                 self.ContentDescription.SetValue(value)
       
   239             elif item == "pageSize":
       
   240                 self.PageWidth.SetValue(value[0])
       
   241                 self.PageHeight.SetValue(value[1])
       
   242             elif item == "scaling":
       
   243                 for language, (x, y) in value.items():
       
   244                     if language in self.Scalings:
       
   245                         self.Scalings[language][0].SetValue(x)
       
   246                         self.Scalings[language][1].SetValue(y)
       
   247             else:
       
   248                 tc = getattr(self, item, None)
       
   249                 if tc is not None:
       
   250                     tc.SetValue(value)
       
   251         
       
   252     def GetValues(self):
       
   253         values = {}
       
   254         for param in ["projectName", "projectVersion",
       
   255                       "productName", "productVersion",
       
   256                       "productRelease", "companyName",
       
   257                       "companyURL", "authorName", 
       
   258                       "organization"]:
       
   259             value = getattr(self, param).GetValue()
       
   260             if param in REQUIRED_PARAMS or value != "":
       
   261                 values[param] = value
       
   262         if self.Language.GetStringSelection() != "":
       
   263             values["language"] = self.Language.GetStringSelection()
       
   264         if self.ContentDescription.GetValue() != "":
       
   265             values["contentDescription"] = self.ContentDescription.GetValue()
       
   266         values["pageSize"] = (self.PageWidth.GetValue(), self.PageHeight.GetValue())
       
   267         values["scaling"] = {}
       
   268         for language in ["FBD", "LD", "SFC"]:
       
   269             values["scaling"][language] = (self.Scalings[language][0].GetValue(),
       
   270                                            self.Scalings[language][1].GetValue())
       
   271         return values
       
   272     
       
   273     def GetTextCtrlChangedFunction(self, textctrl, name):
       
   274         def TextCtrlChangedFunction(event):
       
   275             if self.Controller is not None:
       
   276                 if self.Values is not None:
       
   277                     old_value = self.Values.get(name)
       
   278                 else:
       
   279                     old_value = None
       
   280                 new_value = textctrl.GetValue()
       
   281                 if old_value != new_value:
       
   282                     self.Controller.SetProjectProperties(properties={name: new_value})
       
   283                     self.ParentWindow.RefreshTitle()
       
   284                     self.ParentWindow.RefreshFileMenu()
       
   285                     self.ParentWindow.RefreshEditMenu()
       
   286                     self.ParentWindow.RefreshProjectTree()
       
   287                     self.ParentWindow.RefreshPageTitles()
       
   288                     wx.CallAfter(self.RefreshView)
       
   289             event.Skip()
       
   290         return TextCtrlChangedFunction
       
   291 
       
   292     def GetPageSizeChangedFunction(self, spinctrl, name):
       
   293         def PageSizeChangedFunction(event):
       
   294             if self.Controller is not None:
       
   295                 if self.Values is not None:
       
   296                     old_value = self.Values.get("pageSize")
       
   297                 else:
       
   298                     old_value = (0, 0)
       
   299                 if name == 'PageWidth':
       
   300                     new_value = (spinctrl.GetValue(), old_value[1])
       
   301                 else:
       
   302                     new_value = (old_value[0], spinctrl.GetValue())
       
   303                 if old_value != new_value:
       
   304                     self.Controller.SetProjectProperties(properties={"pageSize": new_value})
       
   305                     self.ParentWindow.RefreshTitle()
       
   306                     self.ParentWindow.RefreshFileMenu()
       
   307                     self.ParentWindow.RefreshEditMenu()
       
   308                     self.ParentWindow.RefreshPageTitles()
       
   309                     self.ParentWindow.RefreshScaling()
       
   310                     wx.CallAfter(self.RefreshView)
       
   311             event.Skip()
       
   312         return PageSizeChangedFunction
       
   313     
       
   314     def GetScalingChangedFunction(self, spinctrl, language, name):
       
   315         def ScalingChangedFunction(event):
       
   316             if self.Controller is not None:
       
   317                 old_value = (0, 0)
       
   318                 if self.Values is not None:
       
   319                     scaling = self.Values.get("scaling")
       
   320                     if scaling is not None:
       
   321                         old_value = scaling.get(language)
       
   322                 if name == 'XScale':
       
   323                     new_value = (spinctrl.GetValue(), old_value[1])
       
   324                 else:
       
   325                     new_value = (old_value[0], spinctrl.GetValue())
       
   326                 if old_value != new_value:
       
   327                     self.Controller.SetProjectProperties(properties={"scaling": {language: new_value}})
       
   328                     self.ParentWindow.RefreshTitle()
       
   329                     self.ParentWindow.RefreshFileMenu()
       
   330                     self.ParentWindow.RefreshEditMenu()
       
   331                     self.ParentWindow.RefreshPageTitles()
       
   332                     self.ParentWindow.RefreshScaling()
       
   333                     wx.CallAfter(self.RefreshView)
       
   334             event.Skip()
       
   335         return ScalingChangedFunction
       
   336     
       
   337     def OnLanguageChanged(self, event):
       
   338         if self.Controller is not None:
       
   339             if self.Values is not None:
       
   340                 old_value = self.Values.get("language")
       
   341             else:
       
   342                 old_value = None
       
   343             new_value = self.Language.GetStringSelection()
       
   344             if old_value != new_value:
       
   345                 self.Controller.SetProjectProperties(properties={"language": new_value})
       
   346                 self.ParentWindow.RefreshTitle()
       
   347                 self.ParentWindow.RefreshFileMenu()
       
   348                 self.ParentWindow.RefreshEditMenu()
       
   349                 self.ParentWindow.RefreshPageTitles()
       
   350                 wx.CallAfter(self.RefreshView)
       
   351         event.Skip()
       
   352         
       
   353     def OnContentDescriptionChanged(self, event):
       
   354         if self.Controller is not None:
       
   355             if self.Values is not None:
       
   356                 old_value = self.Values.get("contentDescription")
       
   357             else:
       
   358                 old_value = None
       
   359             new_value = self.ContentDescription.GetValue()
       
   360             if old_value != new_value:
       
   361                 self.Controller.SetProjectProperties(properties={"contentDescription": new_value})
       
   362                 self.ParentWindow.RefreshTitle()
       
   363                 self.ParentWindow.RefreshFileMenu()
       
   364                 self.ParentWindow.RefreshEditMenu()
       
   365                 self.ParentWindow.RefreshPageTitles()
       
   366                 wx.CallAfter(self.RefreshView)
       
   367         event.Skip()