editors/ConfTreeNodeEditor.py
changeset 1451 94e620cbd9de
parent 1315 ff14a66bbd12
child 1511 91538d0c242c
equal deleted inserted replaced
1450:44bf0ba866e9 1451:94e620cbd9de
    26               'other': 'new century schoolbook',
    26               'other': 'new century schoolbook',
    27               'size' : 18,
    27               'size' : 18,
    28              }
    28              }
    29 
    29 
    30 SCROLLBAR_UNIT = 10
    30 SCROLLBAR_UNIT = 10
    31 
       
    32 CWD = os.path.split(os.path.realpath(__file__))[0]
       
    33 
       
    34 def Bpath(*args):
       
    35     return os.path.join(CWD,*args)
       
    36 
    31 
    37 class GenBitmapTextButton(wx.lib.buttons.GenBitmapTextButton):
    32 class GenBitmapTextButton(wx.lib.buttons.GenBitmapTextButton):
    38     def _GetLabelSize(self):
    33     def _GetLabelSize(self):
    39         """ used internally """
    34         """ used internally """
    40         w, h = self.GetTextExtent(self.GetLabel())
    35         w, h = self.GetTextExtent(self.GetLabel())
    86 
    81 
    87         dc.DrawText(label, pos_x, pos_y)      # draw the text
    82         dc.DrawText(label, pos_x, pos_y)      # draw the text
    88 
    83 
    89 
    84 
    90 class GenStaticBitmap(wx.StaticBitmap):
    85 class GenStaticBitmap(wx.StaticBitmap):
    91     """ Customized GenStaticBitmap, fix transparency redraw bug on wx2.8/win32, 
    86     """ Customized GenStaticBitmap, fix transparency redraw bug on wx2.8/win32,
    92     and accept image name as __init__ parameter, fail silently if file do not exist"""
    87     and accept image name as __init__ parameter, fail silently if file do not exist"""
    93     def __init__(self, parent, ID, bitmapname,
    88     def __init__(self, parent, ID, bitmapname,
    94                  pos = wx.DefaultPosition, size = wx.DefaultSize,
    89                  pos = wx.DefaultPosition, size = wx.DefaultSize,
    95                  style = 0,
    90                  style = 0,
    96                  name = "genstatbmp"):
    91                  name = "genstatbmp"):
    97         
    92 
    98         bitmap = GetBitmap(bitmapname)
    93         bitmap = GetBitmap(bitmapname)
    99         if bitmap is None:
    94         if bitmap is None:
   100             bitmap = wx.EmptyBitmap(0, 0)
    95             bitmap = wx.EmptyBitmap(0, 0)
   101         
    96 
   102         wx.StaticBitmap.__init__(self, parent, ID, 
    97         wx.StaticBitmap.__init__(self, parent, ID,
   103                  bitmap,
    98                  bitmap,
   104                  pos, size,
    99                  pos, size,
   105                  style,
   100                  style,
   106                  name)
   101                  name)
   107 
   102 
   108 class ConfTreeNodeEditor(EditorPanel):
   103 class ConfTreeNodeEditor(EditorPanel):
   109     
   104 
   110     SHOW_BASE_PARAMS = True
   105     SHOW_BASE_PARAMS = True
   111     SHOW_PARAMS = True
   106     SHOW_PARAMS = True
   112     CONFNODEEDITOR_TABS = []
   107     CONFNODEEDITOR_TABS = []
   113     
   108 
   114     def _init_Editor(self, parent):
   109     def _init_Editor(self, parent):
   115         tabs_num = len(self.CONFNODEEDITOR_TABS)
   110         tabs_num = len(self.CONFNODEEDITOR_TABS)
   116         if self.SHOW_PARAMS and len(self.Controler.GetParamsAttributes()) > 0:
   111         if self.SHOW_PARAMS and len(self.Controler.GetParamsAttributes()) > 0:
   117             tabs_num += 1
   112             tabs_num += 1
   118             
   113 
   119         if tabs_num > 1 or self.SHOW_BASE_PARAMS:
   114         if tabs_num > 1 or self.SHOW_BASE_PARAMS:
   120             self.Editor = wx.Panel(parent, 
   115             self.Editor = wx.Panel(parent,
   121                 style=wx.SUNKEN_BORDER|wx.SP_3D)
   116                 style=wx.SUNKEN_BORDER|wx.SP_3D)
   122             
   117 
   123             self.MainSizer = wx.BoxSizer(wx.VERTICAL)
   118             self.MainSizer = wx.BoxSizer(wx.VERTICAL)
   124             
   119 
   125             if self.SHOW_BASE_PARAMS:
   120             if self.SHOW_BASE_PARAMS:
   126                 baseparamseditor_sizer = wx.BoxSizer(wx.HORIZONTAL)
   121                 baseparamseditor_sizer = wx.BoxSizer(wx.HORIZONTAL)
   127                 self.MainSizer.AddSizer(baseparamseditor_sizer, border=5, 
   122                 self.MainSizer.AddSizer(baseparamseditor_sizer, border=5,
   128                       flag=wx.GROW|wx.ALL)
   123                       flag=wx.GROW|wx.ALL)
   129                 
   124 
   130                 self.FullIECChannel = wx.StaticText(self.Editor, -1)
   125                 self.FullIECChannel = wx.StaticText(self.Editor, -1)
   131                 self.FullIECChannel.SetFont(
   126                 self.FullIECChannel.SetFont(
   132                     wx.Font(faces["size"], wx.DEFAULT, wx.NORMAL, 
   127                     wx.Font(faces["size"], wx.DEFAULT, wx.NORMAL,
   133                             wx.BOLD, faceName = faces["helv"]))
   128                             wx.BOLD, faceName = faces["helv"]))
   134                 baseparamseditor_sizer.AddWindow(self.FullIECChannel, 
   129                 baseparamseditor_sizer.AddWindow(self.FullIECChannel,
   135                       flag=wx.ALIGN_CENTER_VERTICAL)
   130                       flag=wx.ALIGN_CENTER_VERTICAL)
   136                 
   131 
   137                 updownsizer = wx.BoxSizer(wx.VERTICAL)
   132                 updownsizer = wx.BoxSizer(wx.VERTICAL)
   138                 baseparamseditor_sizer.AddSizer(updownsizer, border=5, 
   133                 baseparamseditor_sizer.AddSizer(updownsizer, border=5,
   139                       flag=wx.LEFT|wx.ALIGN_CENTER_VERTICAL)
   134                       flag=wx.LEFT|wx.ALIGN_CENTER_VERTICAL)
   140                 
   135 
   141                 self.IECCUpButton = wx.lib.buttons.GenBitmapTextButton(self.Editor, 
   136                 self.IECCUpButton = wx.lib.buttons.GenBitmapTextButton(self.Editor,
   142                       bitmap=GetBitmap('IECCDown'), size=wx.Size(16, 16), style=wx.NO_BORDER)
   137                       bitmap=GetBitmap('IECCDown'), size=wx.Size(16, 16), style=wx.NO_BORDER)
   143                 self.IECCUpButton.Bind(wx.EVT_BUTTON, self.GetItemChannelChangedFunction(1), 
   138                 self.IECCUpButton.Bind(wx.EVT_BUTTON, self.GetItemChannelChangedFunction(1),
   144                       self.IECCUpButton)
   139                       self.IECCUpButton)
   145                 updownsizer.AddWindow(self.IECCUpButton, flag=wx.ALIGN_LEFT)
   140                 updownsizer.AddWindow(self.IECCUpButton, flag=wx.ALIGN_LEFT)
   146                 
   141 
   147                 self.IECCDownButton = wx.lib.buttons.GenBitmapButton(self.Editor, 
   142                 self.IECCDownButton = wx.lib.buttons.GenBitmapButton(self.Editor,
   148                       bitmap=GetBitmap('IECCUp'), size=wx.Size(16, 16), style=wx.NO_BORDER)
   143                       bitmap=GetBitmap('IECCUp'), size=wx.Size(16, 16), style=wx.NO_BORDER)
   149                 self.IECCDownButton.Bind(wx.EVT_BUTTON, self.GetItemChannelChangedFunction(-1), 
   144                 self.IECCDownButton.Bind(wx.EVT_BUTTON, self.GetItemChannelChangedFunction(-1),
   150                       self.IECCDownButton)
   145                       self.IECCDownButton)
   151                 updownsizer.AddWindow(self.IECCDownButton, flag=wx.ALIGN_LEFT)
   146                 updownsizer.AddWindow(self.IECCDownButton, flag=wx.ALIGN_LEFT)
   152                 
   147 
   153                 self.ConfNodeName = wx.TextCtrl(self.Editor, 
   148                 self.ConfNodeName = wx.TextCtrl(self.Editor,
   154                       size=wx.Size(150, 25))
   149                       size=wx.Size(150, 25))
   155                 self.ConfNodeName.SetFont(
   150                 self.ConfNodeName.SetFont(
   156                     wx.Font(faces["size"] * 0.75, wx.DEFAULT, wx.NORMAL, 
   151                     wx.Font(faces["size"] * 0.75, wx.DEFAULT, wx.NORMAL,
   157                             wx.BOLD, faceName = faces["helv"]))
   152                             wx.BOLD, faceName = faces["helv"]))
   158                 self.ConfNodeName.Bind(wx.EVT_TEXT, 
   153                 self.ConfNodeName.Bind(wx.EVT_TEXT,
   159                       self.GetTextCtrlCallBackFunction(self.ConfNodeName, "BaseParams.Name", True), 
   154                       self.GetTextCtrlCallBackFunction(self.ConfNodeName, "BaseParams.Name", True),
   160                       self.ConfNodeName)
   155                       self.ConfNodeName)
   161                 baseparamseditor_sizer.AddWindow(self.ConfNodeName, border=5, 
   156                 baseparamseditor_sizer.AddWindow(self.ConfNodeName, border=5,
   162                       flag=wx.LEFT|wx.RIGHT|wx.ALIGN_CENTER_VERTICAL)
   157                       flag=wx.LEFT|wx.RIGHT|wx.ALIGN_CENTER_VERTICAL)
   163                 
   158 
   164                 buttons_sizer = self.GenerateMethodButtonSizer()
   159                 buttons_sizer = self.GenerateMethodButtonSizer()
   165                 baseparamseditor_sizer.AddSizer(buttons_sizer, flag=wx.ALIGN_CENTER)
   160                 baseparamseditor_sizer.AddSizer(buttons_sizer, flag=wx.ALIGN_CENTER)
   166             
   161 
   167             if tabs_num > 1:
   162             if tabs_num > 1:
   168                 self.ConfNodeNoteBook = wx.Notebook(self.Editor)
   163                 self.ConfNodeNoteBook = wx.Notebook(self.Editor)
   169                 parent = self.ConfNodeNoteBook
   164                 parent = self.ConfNodeNoteBook
   170                 self.MainSizer.AddWindow(self.ConfNodeNoteBook, 1, flag=wx.GROW)
   165                 self.MainSizer.AddWindow(self.ConfNodeNoteBook, 1, flag=wx.GROW)
   171             else:
   166             else:
   172                 parent = self.Editor
   167                 parent = self.Editor
   173                 self.ConfNodeNoteBook = None
   168                 self.ConfNodeNoteBook = None
   174             
   169 
   175             self.Editor.SetSizer(self.MainSizer)
   170             self.Editor.SetSizer(self.MainSizer)
   176         else:
   171         else:
   177             self.ConfNodeNoteBook = None
   172             self.ConfNodeNoteBook = None
   178             self.Editor = None
   173             self.Editor = None
   179         
   174 
   180         for title, create_func_name in self.CONFNODEEDITOR_TABS:
   175         for title, create_func_name in self.CONFNODEEDITOR_TABS:
   181             editor = getattr(self, create_func_name)(parent)
   176             editor = getattr(self, create_func_name)(parent)
   182             if self.ConfNodeNoteBook is not None:
   177             if self.ConfNodeNoteBook is not None:
   183                 self.ConfNodeNoteBook.AddPage(editor, title)
   178                 self.ConfNodeNoteBook.AddPage(editor, title)
   184             elif self.SHOW_BASE_PARAMS:
   179             elif self.SHOW_BASE_PARAMS:
   185                 self.MainSizer.AddWindow(editor, 1, flag=wx.GROW)
   180                 self.MainSizer.AddWindow(editor, 1, flag=wx.GROW)
   186             else:
   181             else:
   187                 self.Editor = editor
   182                 self.Editor = editor
   188         
   183 
   189         if self.SHOW_PARAMS and len(self.Controler.GetParamsAttributes()) > 0:
   184         if self.SHOW_PARAMS and len(self.Controler.GetParamsAttributes()) > 0:
   190             
   185 
   191             panel_style = wx.TAB_TRAVERSAL|wx.HSCROLL|wx.VSCROLL
   186             panel_style = wx.TAB_TRAVERSAL|wx.HSCROLL|wx.VSCROLL
   192             if self.ConfNodeNoteBook is None and parent != self.Editor:
   187             if self.ConfNodeNoteBook is None and parent != self.Editor:
   193                 panel_style |= wx.SUNKEN_BORDER
   188                 panel_style |= wx.SUNKEN_BORDER
   194             self.ParamsEditor = wx.ScrolledWindow(parent, 
   189             self.ParamsEditor = wx.ScrolledWindow(parent,
   195                   style=panel_style)
   190                   style=panel_style)
   196             self.ParamsEditor.Bind(wx.EVT_SIZE, self.OnParamsEditorResize)
   191             self.ParamsEditor.Bind(wx.EVT_SIZE, self.OnParamsEditorResize)
   197             self.ParamsEditor.Bind(wx.EVT_SCROLLWIN, self.OnParamsEditorScroll)
   192             self.ParamsEditor.Bind(wx.EVT_SCROLLWIN, self.OnParamsEditorScroll)
   198             
   193 
   199             self.ParamsEditorSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=1, vgap=5)
   194             self.ParamsEditorSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=1, vgap=5)
   200             self.ParamsEditorSizer.AddGrowableCol(0)
   195             self.ParamsEditorSizer.AddGrowableCol(0)
   201             self.ParamsEditorSizer.AddGrowableRow(0)
   196             self.ParamsEditorSizer.AddGrowableRow(0)
   202             self.ParamsEditor.SetSizer(self.ParamsEditorSizer)
   197             self.ParamsEditor.SetSizer(self.ParamsEditorSizer)
   203             
   198 
   204             self.ConfNodeParamsSizer = wx.BoxSizer(wx.VERTICAL)
   199             self.ConfNodeParamsSizer = wx.BoxSizer(wx.VERTICAL)
   205             self.ParamsEditorSizer.AddSizer(self.ConfNodeParamsSizer, border=5, 
   200             self.ParamsEditorSizer.AddSizer(self.ConfNodeParamsSizer, border=5,
   206                   flag=wx.LEFT|wx.RIGHT|wx.BOTTOM)
   201                   flag=wx.LEFT|wx.RIGHT|wx.BOTTOM)
   207             
   202 
   208             self.RefreshConfNodeParamsSizer()
   203             self.RefreshConfNodeParamsSizer()
   209         
   204 
   210             if self.ConfNodeNoteBook is not None:
   205             if self.ConfNodeNoteBook is not None:
   211                 self.ConfNodeNoteBook.AddPage(self.ParamsEditor, _("Config"))
   206                 self.ConfNodeNoteBook.AddPage(self.ParamsEditor, _("Config"))
   212             elif self.SHOW_BASE_PARAMS:
   207             elif self.SHOW_BASE_PARAMS:
   213                 self.MainSizer.AddWindow(self.ParamsEditor, 1, flag=wx.GROW)
   208                 self.MainSizer.AddWindow(self.ParamsEditor, 1, flag=wx.GROW)
   214             else:
   209             else:
   215                 self.Editor = self.ParamsEditor
   210                 self.Editor = self.ParamsEditor
   216         else:
   211         else:
   217             self.ParamsEditor = None
   212             self.ParamsEditor = None
   218     
   213 
   219     def __init__(self, parent, controler, window, tagname=""):
   214     def __init__(self, parent, controler, window, tagname=""):
   220         EditorPanel.__init__(self, parent, tagname, window, controler)
   215         EditorPanel.__init__(self, parent, tagname, window, controler)
   221         
   216 
   222         icon_name = self.Controler.GetIconName()
   217         icon_name = self.Controler.GetIconName()
   223         if icon_name is not None:
   218         if icon_name is not None:
   224             self.SetIcon(GetBitmap(icon_name))
   219             self.SetIcon(GetBitmap(icon_name))
   225         else:
   220         else:
   226             self.SetIcon(GetBitmap("Extension"))
   221             self.SetIcon(GetBitmap("Extension"))
   227         
   222 
   228     def __del__(self):
   223     def __del__(self):
   229         self.Controler.OnCloseEditor(self)
   224         self.Controler.OnCloseEditor(self)
   230     
   225 
   231     def GetTagName(self):
   226     def GetTagName(self):
   232         return self.Controler.CTNFullName()
   227         return self.Controler.CTNFullName()
   233     
   228 
   234     def GetTitle(self):
   229     def GetTitle(self):
   235         fullname = self.Controler.CTNFullName()
   230         fullname = self.Controler.CTNFullName()
   236         if self.Controler.CTNTestModified():
   231         if self.Controler.CTNTestModified():
   237             return "~%s~" % fullname
   232             return "~%s~" % fullname
   238         return fullname
   233         return fullname
   239     
   234 
   240     def HasNoModel(self):
   235     def HasNoModel(self):
   241         return False
   236         return False
   242     
   237 
   243     def GetBufferState(self):
   238     def GetBufferState(self):
   244         return False, False
   239         return False, False
   245     
   240 
   246     def Undo(self):
   241     def Undo(self):
   247         pass
   242         pass
   248     
   243 
   249     def Redo(self):
   244     def Redo(self):
   250         pass
   245         pass
   251     
   246 
   252     def RefreshView(self):
   247     def RefreshView(self):
   253         EditorPanel.RefreshView(self)
   248         EditorPanel.RefreshView(self)
   254         if self.SHOW_BASE_PARAMS:
   249         if self.SHOW_BASE_PARAMS:
   255             self.ConfNodeName.ChangeValue(self.Controler.MandatoryParams[1].getName())
   250             self.ConfNodeName.ChangeValue(self.Controler.MandatoryParams[1].getName())
   256             self.RefreshIECChannelControlsState()
   251             self.RefreshIECChannelControlsState()
   257         if self.ParamsEditor is not None:
   252         if self.ParamsEditor is not None:
   258             self.RefreshConfNodeParamsSizer()
   253             self.RefreshConfNodeParamsSizer()
   259             self.RefreshScrollbars()
   254             self.RefreshScrollbars()
   260     
   255 
   261     def RefreshIECChannelControlsState(self):
   256     def RefreshIECChannelControlsState(self):
   262         self.FullIECChannel.SetLabel(self.Controler.GetFullIEC_Channel())
   257         self.FullIECChannel.SetLabel(self.Controler.GetFullIEC_Channel())
   263         self.IECCDownButton.Enable(self.Controler.BaseParams.getIEC_Channel() > 0)
   258         self.IECCDownButton.Enable(self.Controler.BaseParams.getIEC_Channel() > 0)
   264         self.MainSizer.Layout()
   259         self.MainSizer.Layout()
   265     
   260 
   266     def RefreshConfNodeParamsSizer(self):
   261     def RefreshConfNodeParamsSizer(self):
   267         self.Freeze()
   262         self.Freeze()
   268         self.ConfNodeParamsSizer.Clear(True)
   263         self.ConfNodeParamsSizer.Clear(True)
   269         
   264 
   270         confnode_infos = self.Controler.GetParamsAttributes()
   265         confnode_infos = self.Controler.GetParamsAttributes()
   271         if len(confnode_infos) > 0:
   266         if len(confnode_infos) > 0:
   272             self.GenerateSizerElements(self.ConfNodeParamsSizer, confnode_infos, None, False)
   267             self.GenerateSizerElements(self.ConfNodeParamsSizer, confnode_infos, None, False)
   273         
   268 
   274         self.ParamsEditorSizer.Layout()
   269         self.ParamsEditorSizer.Layout()
   275         self.Thaw()
   270         self.Thaw()
   276     
   271 
   277     def GenerateMethodButtonSizer(self):
   272     def GenerateMethodButtonSizer(self):
   278         normal_bt_font=wx.Font(faces["size"] / 3, wx.DEFAULT, wx.NORMAL, wx.NORMAL, faceName = faces["helv"])
   273         normal_bt_font=wx.Font(faces["size"] / 3, wx.DEFAULT, wx.NORMAL, wx.NORMAL, faceName = faces["helv"])
   279         mouseover_bt_font=wx.Font(faces["size"] / 3, wx.DEFAULT, wx.NORMAL, wx.NORMAL, underline=True, faceName = faces["helv"])
   274         mouseover_bt_font=wx.Font(faces["size"] / 3, wx.DEFAULT, wx.NORMAL, wx.NORMAL, underline=True, faceName = faces["helv"])
   280         
   275 
   281         msizer = wx.BoxSizer(wx.HORIZONTAL)
   276         msizer = wx.BoxSizer(wx.HORIZONTAL)
   282         
   277 
   283         for confnode_method in self.Controler.ConfNodeMethods:
   278         for confnode_method in self.Controler.ConfNodeMethods:
   284             if "method" in confnode_method and confnode_method.get("shown",True):
   279             if "method" in confnode_method and confnode_method.get("shown",True):
   285                 button = GenBitmapTextButton(self.Editor,
   280                 button = GenBitmapTextButton(self.Editor,
   286                     bitmap=GetBitmap(confnode_method.get("bitmap", "Unknown")), 
   281                     bitmap=GetBitmap(confnode_method.get("bitmap", "Unknown")),
   287                     label=confnode_method["name"], style=wx.NO_BORDER)
   282                     label=confnode_method["name"], style=wx.NO_BORDER)
   288                 button.SetFont(normal_bt_font)
   283                 button.SetFont(normal_bt_font)
   289                 button.SetToolTipString(confnode_method["tooltip"])
   284                 button.SetToolTipString(confnode_method["tooltip"])
   290                 if confnode_method.get("push", False):
   285                 if confnode_method.get("push", False):
   291                     button.Bind(wx.EVT_LEFT_DOWN, self.GetButtonCallBackFunction(confnode_method["method"], True))
   286                     button.Bind(wx.EVT_LEFT_DOWN, self.GetButtonCallBackFunction(confnode_method["method"], True))
   303                 #hack to force size to mini
   298                 #hack to force size to mini
   304                 if not confnode_method.get("enabled",True):
   299                 if not confnode_method.get("enabled",True):
   305                     button.Disable()
   300                     button.Disable()
   306                 msizer.AddWindow(button, flag=wx.ALIGN_CENTER)
   301                 msizer.AddWindow(button, flag=wx.ALIGN_CENTER)
   307         return msizer
   302         return msizer
   308     
   303 
   309     def GenerateSizerElements(self, sizer, elements, path, clean = True):
   304     def GenerateSizerElements(self, sizer, elements, path, clean = True):
   310         if clean:
   305         if clean:
   311             sizer.Clear(True)
   306             sizer.Clear(True)
   312         first = True
   307         first = True
   313         for element_infos in elements:
   308         for element_infos in elements:
   319                 name = element_infos["name"]
   314                 name = element_infos["name"]
   320                 value = element_infos["value"]
   315                 value = element_infos["value"]
   321                 label = _(name)
   316                 label = _(name)
   322                 if value is not None:
   317                 if value is not None:
   323                     label += " - %s" % _(value)
   318                     label += " - %s" % _(value)
   324                 staticbox = wx.StaticBox(self.ParamsEditor, 
   319                 staticbox = wx.StaticBox(self.ParamsEditor,
   325                       label=_(label), size=wx.Size(10, 0))
   320                       label=_(label), size=wx.Size(10, 0))
   326                 staticboxsizer = wx.StaticBoxSizer(staticbox, wx.VERTICAL)
   321                 staticboxsizer = wx.StaticBoxSizer(staticbox, wx.VERTICAL)
   327                 if first:
   322                 if first:
   328                     sizer.AddSizer(staticboxsizer, border=5, 
   323                     sizer.AddSizer(staticboxsizer, border=5,
   329                           flag=wx.GROW|wx.TOP|wx.BOTTOM)
   324                           flag=wx.GROW|wx.TOP|wx.BOTTOM)
   330                 else:
   325                 else:
   331                     sizer.AddSizer(staticboxsizer, border=5, 
   326                     sizer.AddSizer(staticboxsizer, border=5,
   332                           flag=wx.GROW|wx.BOTTOM)
   327                           flag=wx.GROW|wx.BOTTOM)
   333                 self.GenerateSizerElements(staticboxsizer, 
   328                 self.GenerateSizerElements(staticboxsizer,
   334                                            element_infos["children"], 
   329                                            element_infos["children"],
   335                                            element_path)
   330                                            element_path)
   336             else:
   331             else:
   337                 boxsizer = wx.FlexGridSizer(cols=3, rows=1)
   332                 boxsizer = wx.FlexGridSizer(cols=3, rows=1)
   338                 boxsizer.AddGrowableCol(1)
   333                 boxsizer.AddGrowableCol(1)
   339                 if first:
   334                 if first:
   340                     sizer.AddSizer(boxsizer, border=5, 
   335                     sizer.AddSizer(boxsizer, border=5,
   341                           flag=wx.GROW|wx.ALL)
   336                           flag=wx.GROW|wx.ALL)
   342                 else:
   337                 else:
   343                     sizer.AddSizer(boxsizer, border=5, 
   338                     sizer.AddSizer(boxsizer, border=5,
   344                           flag=wx.GROW|wx.LEFT|wx.RIGHT|wx.BOTTOM)
   339                           flag=wx.GROW|wx.LEFT|wx.RIGHT|wx.BOTTOM)
   345                 
   340 
   346                 staticbitmap = GenStaticBitmap(ID=-1, bitmapname=element_infos["name"],
   341                 staticbitmap = GenStaticBitmap(ID=-1, bitmapname=element_infos["name"],
   347                     name="%s_bitmap"%element_infos["name"], parent=self.ParamsEditor,
   342                     name="%s_bitmap"%element_infos["name"], parent=self.ParamsEditor,
   348                     pos=wx.Point(0, 0), size=wx.Size(24, 24), style=0)
   343                     pos=wx.Point(0, 0), size=wx.Size(24, 24), style=0)
   349                 boxsizer.AddWindow(staticbitmap, border=5, flag=wx.RIGHT)
   344                 boxsizer.AddWindow(staticbitmap, border=5, flag=wx.RIGHT)
   350                 
   345 
   351                 statictext = wx.StaticText(self.ParamsEditor, 
   346                 statictext = wx.StaticText(self.ParamsEditor,
   352                       label="%s:"%_(element_infos["name"]))
   347                       label="%s:"%_(element_infos["name"]))
   353                 boxsizer.AddWindow(statictext, border=5, 
   348                 boxsizer.AddWindow(statictext, border=5,
   354                       flag=wx.ALIGN_CENTER_VERTICAL|wx.RIGHT)
   349                       flag=wx.ALIGN_CENTER_VERTICAL|wx.RIGHT)
   355                 
   350 
   356                 if isinstance(element_infos["type"], types.ListType):
   351                 if isinstance(element_infos["type"], types.ListType):
   357                     if isinstance(element_infos["value"], types.TupleType):
   352                     if isinstance(element_infos["value"], types.TupleType):
   358                         browse_boxsizer = wx.BoxSizer(wx.HORIZONTAL)
   353                         browse_boxsizer = wx.BoxSizer(wx.HORIZONTAL)
   359                         boxsizer.AddSizer(browse_boxsizer)
   354                         boxsizer.AddSizer(browse_boxsizer)
   360                         
   355 
   361                         textctrl = wx.TextCtrl(self.ParamsEditor, 
   356                         textctrl = wx.TextCtrl(self.ParamsEditor,
   362                               size=wx.Size(275, -1), style=wx.TE_READONLY)
   357                               size=wx.Size(275, -1), style=wx.TE_READONLY)
   363                         if element_infos["value"] is not None:
   358                         if element_infos["value"] is not None:
   364                             textctrl.SetValue(element_infos["value"][0])
   359                             textctrl.SetValue(element_infos["value"][0])
   365                             value_infos = element_infos["value"][1]
   360                             value_infos = element_infos["value"][1]
   366                         else:
   361                         else:
   367                             value_infos = None
   362                             value_infos = None
   368                         browse_boxsizer.AddWindow(textctrl)
   363                         browse_boxsizer.AddWindow(textctrl)
   369                         
   364 
   370                         button = wx.Button(self.ParamsEditor, 
   365                         button = wx.Button(self.ParamsEditor,
   371                               label="...", size=wx.Size(25, 25))
   366                               label="...", size=wx.Size(25, 25))
   372                         browse_boxsizer.AddWindow(button)
   367                         browse_boxsizer.AddWindow(button)
   373                         button.Bind(wx.EVT_BUTTON, 
   368                         button.Bind(wx.EVT_BUTTON,
   374                                     self.GetBrowseCallBackFunction(element_infos["name"], textctrl, element_infos["type"], 
   369                                     self.GetBrowseCallBackFunction(element_infos["name"], textctrl, element_infos["type"],
   375                                                                    value_infos, element_path), 
   370                                                                    value_infos, element_path),
   376                                     button)
   371                                     button)
   377                     else:
   372                     else:
   378                         combobox = wx.ComboBox(self.ParamsEditor, 
   373                         combobox = wx.ComboBox(self.ParamsEditor,
   379                               size=wx.Size(300, -1), style=wx.CB_READONLY)
   374                               size=wx.Size(300, -1), style=wx.CB_READONLY)
   380                         boxsizer.AddWindow(combobox)
   375                         boxsizer.AddWindow(combobox)
   381                         
   376 
   382                         if element_infos["use"] == "optional":
   377                         if element_infos["use"] == "optional":
   383                             combobox.Append("")
   378                             combobox.Append("")
   384                         if len(element_infos["type"]) > 0 and isinstance(element_infos["type"][0], types.TupleType):
   379                         if len(element_infos["type"]) > 0 and isinstance(element_infos["type"][0], types.TupleType):
   385                             for choice, xsdclass in element_infos["type"]:
   380                             for choice, xsdclass in element_infos["type"]:
   386                                 combobox.Append(choice)
   381                                 combobox.Append(choice)
   387                             name = element_infos["name"]
   382                             name = element_infos["name"]
   388                             value = element_infos["value"]
   383                             value = element_infos["value"]
   389                         
   384 
   390                             staticbox = wx.StaticBox(self.ParamsEditor, 
   385                             staticbox = wx.StaticBox(self.ParamsEditor,
   391                                   label="%s - %s"%(_(name), _(value)), size=wx.Size(10, 0))
   386                                   label="%s - %s"%(_(name), _(value)), size=wx.Size(10, 0))
   392                             staticboxsizer = wx.StaticBoxSizer(staticbox, wx.VERTICAL)
   387                             staticboxsizer = wx.StaticBoxSizer(staticbox, wx.VERTICAL)
   393                             sizer.AddSizer(staticboxsizer, border=5, flag=wx.GROW|wx.BOTTOM)
   388                             sizer.AddSizer(staticboxsizer, border=5, flag=wx.GROW|wx.BOTTOM)
   394                             self.GenerateSizerElements(staticboxsizer, element_infos["children"], element_path)
   389                             self.GenerateSizerElements(staticboxsizer, element_infos["children"], element_path)
   395                             callback = self.GetChoiceContentCallBackFunction(combobox, staticboxsizer, element_path)
   390                             callback = self.GetChoiceContentCallBackFunction(combobox, staticboxsizer, element_path)
   400                         if element_infos["value"] is None:
   395                         if element_infos["value"] is None:
   401                             combobox.SetStringSelection("")
   396                             combobox.SetStringSelection("")
   402                         else:
   397                         else:
   403                             combobox.SetStringSelection(element_infos["value"])
   398                             combobox.SetStringSelection(element_infos["value"])
   404                         combobox.Bind(wx.EVT_COMBOBOX, callback, combobox)
   399                         combobox.Bind(wx.EVT_COMBOBOX, callback, combobox)
   405                 
   400 
   406                 elif isinstance(element_infos["type"], types.DictType):
   401                 elif isinstance(element_infos["type"], types.DictType):
   407                     scmin = -(2**31)
   402                     scmin = -(2**31)
   408                     scmax = 2**31-1
   403                     scmax = 2**31-1
   409                     if "min" in element_infos["type"]:
   404                     if "min" in element_infos["type"]:
   410                         scmin = element_infos["type"]["min"]
   405                         scmin = element_infos["type"]["min"]
   411                     if "max" in element_infos["type"]:
   406                     if "max" in element_infos["type"]:
   412                         scmax = element_infos["type"]["max"]
   407                         scmax = element_infos["type"]["max"]
   413                     spinctrl = wx.SpinCtrl(self.ParamsEditor, 
   408                     spinctrl = wx.SpinCtrl(self.ParamsEditor,
   414                           size=wx.Size(300, -1), style=wx.SP_ARROW_KEYS|wx.ALIGN_RIGHT)
   409                           size=wx.Size(300, -1), style=wx.SP_ARROW_KEYS|wx.ALIGN_RIGHT)
   415                     spinctrl.SetRange(scmin, scmax)
   410                     spinctrl.SetRange(scmin, scmax)
   416                     boxsizer.AddWindow(spinctrl)
   411                     boxsizer.AddWindow(spinctrl)
   417                     if element_infos["value"] is not None:
   412                     if element_infos["value"] is not None:
   418                         spinctrl.SetValue(element_infos["value"])
   413                         spinctrl.SetValue(element_infos["value"])
   419                     spinctrl.Bind(wx.EVT_SPINCTRL, 
   414                     spinctrl.Bind(wx.EVT_SPINCTRL,
   420                                   self.GetTextCtrlCallBackFunction(spinctrl, element_path),
   415                                   self.GetTextCtrlCallBackFunction(spinctrl, element_path),
   421                                   spinctrl)
   416                                   spinctrl)
   422                 
   417 
   423                 else:
   418                 else:
   424                     if element_infos["type"] == "boolean":
   419                     if element_infos["type"] == "boolean":
   425                         checkbox = wx.CheckBox(self.ParamsEditor, size=wx.Size(17, 25))
   420                         checkbox = wx.CheckBox(self.ParamsEditor, size=wx.Size(17, 25))
   426                         boxsizer.AddWindow(checkbox)
   421                         boxsizer.AddWindow(checkbox)
   427                         if element_infos["value"] is not None:
   422                         if element_infos["value"] is not None:
   428                             checkbox.SetValue(element_infos["value"])
   423                             checkbox.SetValue(element_infos["value"])
   429                         checkbox.Bind(wx.EVT_CHECKBOX, 
   424                         checkbox.Bind(wx.EVT_CHECKBOX,
   430                                       self.GetCheckBoxCallBackFunction(checkbox, element_path), 
   425                                       self.GetCheckBoxCallBackFunction(checkbox, element_path),
   431                                       checkbox)
   426                                       checkbox)
   432                     
   427 
   433                     elif element_infos["type"] in ["unsignedLong", "long","integer"]:
   428                     elif element_infos["type"] in ["unsignedLong", "long","integer"]:
   434                         if element_infos["type"].startswith("unsigned"):
   429                         if element_infos["type"].startswith("unsigned"):
   435                             scmin = 0
   430                             scmin = 0
   436                         else:
   431                         else:
   437                             scmin = -(2**31)
   432                             scmin = -(2**31)
   438                         scmax = 2**31-1
   433                         scmax = 2**31-1
   439                         spinctrl = wx.SpinCtrl(self.ParamsEditor, 
   434                         spinctrl = wx.SpinCtrl(self.ParamsEditor,
   440                               size=wx.Size(300, -1), style=wx.SP_ARROW_KEYS|wx.ALIGN_RIGHT)
   435                               size=wx.Size(300, -1), style=wx.SP_ARROW_KEYS|wx.ALIGN_RIGHT)
   441                         spinctrl.SetRange(scmin, scmax)
   436                         spinctrl.SetRange(scmin, scmax)
   442                         boxsizer.AddWindow(spinctrl)
   437                         boxsizer.AddWindow(spinctrl)
   443                         if element_infos["value"] is not None:
   438                         if element_infos["value"] is not None:
   444                             spinctrl.SetValue(element_infos["value"])
   439                             spinctrl.SetValue(element_infos["value"])
   445                         spinctrl.Bind(wx.EVT_SPINCTRL, 
   440                         spinctrl.Bind(wx.EVT_SPINCTRL,
   446                                       self.GetTextCtrlCallBackFunction(spinctrl, element_path), 
   441                                       self.GetTextCtrlCallBackFunction(spinctrl, element_path),
   447                                       spinctrl)
   442                                       spinctrl)
   448                     
   443 
   449                     else:
   444                     else:
   450                         choices = self.ParentWindow.GetConfigEntry(element_path, [""])
   445                         choices = self.ParentWindow.GetConfigEntry(element_path, [""])
   451                         textctrl = TextCtrlAutoComplete(name=element_infos["name"], 
   446                         textctrl = TextCtrlAutoComplete(name=element_infos["name"],
   452                                                         parent=self.ParamsEditor, 
   447                                                         parent=self.ParamsEditor,
   453                                                         choices=choices, 
   448                                                         choices=choices,
   454                                                         element_path=element_path,
   449                                                         element_path=element_path,
   455                                                         size=wx.Size(300, -1))
   450                                                         size=wx.Size(300, -1))
   456                         
   451 
   457                         boxsizer.AddWindow(textctrl)
   452                         boxsizer.AddWindow(textctrl)
   458                         if element_infos["value"] is not None:
   453                         if element_infos["value"] is not None:
   459                             textctrl.ChangeValue(str(element_infos["value"]))
   454                             textctrl.ChangeValue(str(element_infos["value"]))
   460                         callback = self.GetTextCtrlCallBackFunction(textctrl, element_path)
   455                         callback = self.GetTextCtrlCallBackFunction(textctrl, element_path)
   461                         textctrl.Bind(wx.EVT_TEXT_ENTER, callback)
   456                         textctrl.Bind(wx.EVT_TEXT_ENTER, callback)
   462                         textctrl.Bind(wx.EVT_KILL_FOCUS, callback)
   457                         textctrl.Bind(wx.EVT_KILL_FOCUS, callback)
   463             first = False
   458             first = False
   464     
   459 
   465     
   460 
   466     def GetItemChannelChangedFunction(self, dir):
   461     def GetItemChannelChangedFunction(self, dir):
   467         def OnConfNodeTreeItemChannelChanged(event):
   462         def OnConfNodeTreeItemChannelChanged(event):
   468             confnode_IECChannel = self.Controler.BaseParams.getIEC_Channel()
   463             confnode_IECChannel = self.Controler.BaseParams.getIEC_Channel()
   469             res = self.SetConfNodeParamsAttribute("BaseParams.IEC_Channel", confnode_IECChannel + dir)
   464             res = self.SetConfNodeParamsAttribute("BaseParams.IEC_Channel", confnode_IECChannel + dir)
   470             wx.CallAfter(self.RefreshIECChannelControlsState)
   465             wx.CallAfter(self.RefreshIECChannelControlsState)
   471             wx.CallAfter(self.ParentWindow._Refresh, TITLE, FILEMENU, PROJECTTREE)
   466             wx.CallAfter(self.ParentWindow._Refresh, TITLE, FILEMENU, PROJECTTREE)
   472             event.Skip()
   467             event.Skip()
   473         return OnConfNodeTreeItemChannelChanged
   468         return OnConfNodeTreeItemChannelChanged
   474     
   469 
   475     def SetConfNodeParamsAttribute(self, *args, **kwargs):
   470     def SetConfNodeParamsAttribute(self, *args, **kwargs):
   476         res, StructChanged = self.Controler.SetParamsAttribute(*args, **kwargs)
   471         res, StructChanged = self.Controler.SetParamsAttribute(*args, **kwargs)
   477         if StructChanged and self.ParamsEditor is not None:
   472         if StructChanged and self.ParamsEditor is not None:
   478             wx.CallAfter(self.RefreshConfNodeParamsSizer)
   473             wx.CallAfter(self.RefreshConfNodeParamsSizer)
   479         wx.CallAfter(self.ParentWindow._Refresh, TITLE, FILEMENU)
   474         wx.CallAfter(self.ParentWindow._Refresh, TITLE, FILEMENU)
   480         return res
   475         return res
   481     
   476 
   482     def GetButtonCallBackFunction(self, method, push=False):
   477     def GetButtonCallBackFunction(self, method, push=False):
   483         """ Generate the callbackfunc for a given confnode method"""
   478         """ Generate the callbackfunc for a given confnode method"""
   484         def OnButtonClick(event):
   479         def OnButtonClick(event):
   485             # Disable button to prevent re-entrant call 
   480             # Disable button to prevent re-entrant call
   486             event.GetEventObject().Disable()
   481             event.GetEventObject().Disable()
   487             # Call
   482             # Call
   488             getattr(self.Controler,method)()
   483             getattr(self.Controler,method)()
   489             # Re-enable button 
   484             # Re-enable button
   490             event.GetEventObject().Enable()
   485             event.GetEventObject().Enable()
   491             
   486 
   492             if not push:
   487             if not push:
   493                 event.Skip()
   488                 event.Skip()
   494         return OnButtonClick
   489         return OnButtonClick
   495     
   490 
   496     def GetChoiceCallBackFunction(self, choicectrl, path):
   491     def GetChoiceCallBackFunction(self, choicectrl, path):
   497         def OnChoiceChanged(event):
   492         def OnChoiceChanged(event):
   498             res = self.SetConfNodeParamsAttribute(path, choicectrl.GetStringSelection())
   493             res = self.SetConfNodeParamsAttribute(path, choicectrl.GetStringSelection())
   499             if res is None:
   494             if res is None:
   500                 res = ""
   495                 res = ""
   501             choicectrl.SetStringSelection(res)
   496             choicectrl.SetStringSelection(res)
   502             event.Skip()
   497             event.Skip()
   503         return OnChoiceChanged
   498         return OnChoiceChanged
   504     
   499 
   505     def GetChoiceContentCallBackFunction(self, choicectrl, staticboxsizer, path):
   500     def GetChoiceContentCallBackFunction(self, choicectrl, staticboxsizer, path):
   506         def OnChoiceContentChanged(event):
   501         def OnChoiceContentChanged(event):
   507             res = self.SetConfNodeParamsAttribute(path, choicectrl.GetStringSelection())
   502             res = self.SetConfNodeParamsAttribute(path, choicectrl.GetStringSelection())
   508             wx.CallAfter(self.RefreshConfNodeParamsSizer)
   503             wx.CallAfter(self.RefreshConfNodeParamsSizer)
   509             event.Skip()
   504             event.Skip()
   510         return OnChoiceContentChanged
   505         return OnChoiceContentChanged
   511     
   506 
   512     def GetTextCtrlCallBackFunction(self, textctrl, path, refresh=False):
   507     def GetTextCtrlCallBackFunction(self, textctrl, path, refresh=False):
   513         def OnTextCtrlChanged(event):
   508         def OnTextCtrlChanged(event):
   514             res = self.SetConfNodeParamsAttribute(path, textctrl.GetValue())
   509             res = self.SetConfNodeParamsAttribute(path, textctrl.GetValue())
   515             if res != textctrl.GetValue():
   510             if res != textctrl.GetValue():
   516                 if isinstance(textctrl, wx.SpinCtrl):
   511                 if isinstance(textctrl, wx.SpinCtrl):
   520             if refresh:
   515             if refresh:
   521                 wx.CallAfter(self.ParentWindow._Refresh, TITLE, FILEMENU, PROJECTTREE, PAGETITLES)
   516                 wx.CallAfter(self.ParentWindow._Refresh, TITLE, FILEMENU, PROJECTTREE, PAGETITLES)
   522                 wx.CallAfter(self.ParentWindow.SelectProjectTreeItem, self.GetTagName())
   517                 wx.CallAfter(self.ParentWindow.SelectProjectTreeItem, self.GetTagName())
   523             event.Skip()
   518             event.Skip()
   524         return OnTextCtrlChanged
   519         return OnTextCtrlChanged
   525     
   520 
   526     def GetCheckBoxCallBackFunction(self, chkbx, path):
   521     def GetCheckBoxCallBackFunction(self, chkbx, path):
   527         def OnCheckBoxChanged(event):
   522         def OnCheckBoxChanged(event):
   528             res = self.SetConfNodeParamsAttribute(path, chkbx.IsChecked())
   523             res = self.SetConfNodeParamsAttribute(path, chkbx.IsChecked())
   529             chkbx.SetValue(res)
   524             chkbx.SetValue(res)
   530             event.Skip()
   525             event.Skip()
   531         return OnCheckBoxChanged
   526         return OnCheckBoxChanged
   532     
   527 
   533     def GetBrowseCallBackFunction(self, name, textctrl, library, value_infos, path):
   528     def GetBrowseCallBackFunction(self, name, textctrl, library, value_infos, path):
   534         infos = [value_infos]
   529         infos = [value_infos]
   535         def OnBrowseButton(event):
   530         def OnBrowseButton(event):
   536             dialog = BrowseValuesLibraryDialog(self, name, library, infos[0])
   531             dialog = BrowseValuesLibraryDialog(self, name, library, infos[0])
   537             if dialog.ShowModal() == wx.ID_OK:
   532             if dialog.ShowModal() == wx.ID_OK:
   539                 textctrl.ChangeValue(value)
   534                 textctrl.ChangeValue(value)
   540                 infos[0] = value_infos
   535                 infos[0] = value_infos
   541             dialog.Destroy()
   536             dialog.Destroy()
   542             event.Skip()
   537             event.Skip()
   543         return OnBrowseButton
   538         return OnBrowseButton
   544     
   539 
   545     def RefreshScrollbars(self):
   540     def RefreshScrollbars(self):
   546         self.ParamsEditor.GetBestSize()
   541         self.ParamsEditor.GetBestSize()
   547         xstart, ystart = self.ParamsEditor.GetViewStart()
   542         xstart, ystart = self.ParamsEditor.GetViewStart()
   548         window_size = self.ParamsEditor.GetClientSize()
   543         window_size = self.ParamsEditor.GetClientSize()
   549         maxx, maxy = self.ParamsEditorSizer.GetMinSize()
   544         maxx, maxy = self.ParamsEditorSizer.GetMinSize()
   550         posx = max(0, min(xstart, (maxx - window_size[0]) / SCROLLBAR_UNIT))
   545         posx = max(0, min(xstart, (maxx - window_size[0]) / SCROLLBAR_UNIT))
   551         posy = max(0, min(ystart, (maxy - window_size[1]) / SCROLLBAR_UNIT))
   546         posy = max(0, min(ystart, (maxy - window_size[1]) / SCROLLBAR_UNIT))
   552         self.ParamsEditor.Scroll(posx, posy)
   547         self.ParamsEditor.Scroll(posx, posy)
   553         self.ParamsEditor.SetScrollbars(SCROLLBAR_UNIT, SCROLLBAR_UNIT, 
   548         self.ParamsEditor.SetScrollbars(SCROLLBAR_UNIT, SCROLLBAR_UNIT,
   554                 maxx / SCROLLBAR_UNIT, maxy / SCROLLBAR_UNIT, posx, posy)
   549                 maxx / SCROLLBAR_UNIT, maxy / SCROLLBAR_UNIT, posx, posy)
   555     
   550 
   556     def OnParamsEditorResize(self, event):
   551     def OnParamsEditorResize(self, event):
   557         self.RefreshScrollbars()
   552         self.RefreshScrollbars()
   558         event.Skip()
   553         event.Skip()
   559     
   554 
   560     def OnParamsEditorScroll(self, event):
   555     def OnParamsEditorScroll(self, event):
   561         control = self.ParamsEditor.FindFocus()
   556         control = self.ParamsEditor.FindFocus()
   562         if isinstance(control, TextCtrlAutoComplete):
   557         if isinstance(control, TextCtrlAutoComplete):
   563             control.DismissListBox()
   558             control.DismissListBox()
   564             self.Refresh()
   559             self.Refresh()
   565         event.Skip()
   560         event.Skip()
   566     
   561