chiark / gitweb /
Update code for translations, fix a few translation issues and add a few missing...
[cura.git] / Cura / gui / configBase.py
index 871e4ad9f672d9ff7d2a31892091ab807384d9e9..3cf6a1d0eaf87abe149a241738330025173f4e21 100644 (file)
@@ -1,20 +1,17 @@
 from __future__ import absolute_import
-import __init__
+from __future__ import division
+__copyright__ = "Copyright (C) 2013 David Braam - Released under terms of the AGPLv3 License"
 
-import wx, wx.lib.stattext, os, sys, platform, types
+import wx, wx.lib.stattext, types
+from wx.lib.agw import floatspin
 
-from gui import validators
-from util import profile
+from Cura.util import validators
+from Cura.util import profile
 
-def main():
-       app = wx.App(False)
-       mainWindow()
-       app.MainLoop()
-
-class configWindowBase(wx.Frame):
+class configPanelBase(wx.Panel):
        "A base class for configuration dialogs. Handles creation of settings, and popups"
-       def __init__(self, title):
-               super(configWindowBase, self).__init__(None, title=title)
+       def __init__(self, parent, changeCallback = None):
+               super(configPanelBase, self).__init__(parent)
                
                self.settingControlList = []
                
@@ -26,6 +23,8 @@ class configWindowBase(wx.Frame):
                self.popup.sizer = wx.BoxSizer()
                self.popup.sizer.Add(self.popup.text, flag=wx.EXPAND|wx.ALL, border=1)
                self.popup.SetSizer(self.popup.sizer)
+
+               self._callback = changeCallback
        
        def CreateConfigTab(self, nb, name):
                leftConfigPanel, rightConfigPanel, configPanel = self.CreateConfigPanel(nb)
@@ -36,18 +35,52 @@ class configWindowBase(wx.Frame):
                configPanel = wx.Panel(parent);
                leftConfigPanel = wx.Panel(configPanel)
                rightConfigPanel = wx.Panel(configPanel)
+
                sizer = wx.GridBagSizer(2, 2)
                leftConfigPanel.SetSizer(sizer)
                sizer = wx.GridBagSizer(2, 2)
                rightConfigPanel.SetSizer(sizer)
+
                sizer = wx.BoxSizer(wx.HORIZONTAL)
                configPanel.SetSizer(sizer)
-               sizer.Add(leftConfigPanel)
+               sizer.Add(leftConfigPanel, border=35, flag=wx.RIGHT)
                sizer.Add(rightConfigPanel)
                leftConfigPanel.main = self
                rightConfigPanel.main = self
                return leftConfigPanel, rightConfigPanel, configPanel
 
+       def CreateDynamicConfigTab(self, nb, name):
+               configPanel = wx.lib.scrolledpanel.ScrolledPanel(nb)    
+               #configPanel = wx.Panel(nb);
+               leftConfigPanel = wx.Panel(configPanel)
+               rightConfigPanel = wx.Panel(configPanel)
+
+               sizer = wx.GridBagSizer(2, 2)
+               leftConfigPanel.SetSizer(sizer)
+               #sizer.AddGrowableCol(1)
+
+               sizer = wx.GridBagSizer(2, 2)
+               rightConfigPanel.SetSizer(sizer)
+               #sizer.AddGrowableCol(1)
+
+               sizer = wx.BoxSizer(wx.HORIZONTAL)
+               sizer.Add(leftConfigPanel, proportion=1, border=35, flag=wx.EXPAND)
+               sizer.Add(rightConfigPanel, proportion=1, flag=wx.EXPAND)
+               configPanel.SetSizer(sizer)
+
+               configPanel.SetAutoLayout(1)
+               configPanel.SetupScrolling(scroll_x=False, scroll_y=True)
+
+               leftConfigPanel.main = self
+               rightConfigPanel.main = self
+
+               configPanel.leftPanel = leftConfigPanel
+               configPanel.rightPanel = rightConfigPanel
+
+               nb.AddPage(configPanel, name)
+
+               return leftConfigPanel, rightConfigPanel, configPanel
+
        def OnPopupDisplay(self, setting):
                self.popup.setting = setting
                self.UpdatePopup(setting)
@@ -59,17 +92,13 @@ class configWindowBase(wx.Frame):
        def UpdatePopup(self, setting):
                if self.popup.setting == setting:
                        if setting.validationMsg != '':
-                               self.popup.text.SetLabel(setting.validationMsg + '\n\n' + setting.helpText)
+                               self.popup.text.SetLabel(setting.validationMsg + '\n\n' + setting.setting.getTooltip())
                        else:
-                               self.popup.text.SetLabel(setting.helpText)
+                               self.popup.text.SetLabel(setting.setting.getTooltip())
                        self.popup.text.Wrap(350)
                        self.popup.Fit()
-                       if os.name == 'darwin':
-                               x, y = self.ClientToScreenXY(0, 0)
-                               sx, sy = self.GetClientSizeTuple()
-                       else:
-                               x, y = setting.ctrl.ClientToScreenXY(0, 0)
-                               sx, sy = setting.ctrl.GetSizeTuple()
+                       x, y = setting.ctrl.ClientToScreenXY(0, 0)
+                       sx, sy = setting.ctrl.GetSizeTuple()
                        #if platform.system() == "Windows":
                        #       for some reason, under windows, the popup is relative to the main window... in some cases. (Wierd ass bug)
                        #       wx, wy = self.ClientToScreenXY(0, 0)
@@ -80,59 +109,104 @@ class configWindowBase(wx.Frame):
        def updateProfileToControls(self):
                "Update the configuration wx controls to show the new configuration settings"
                for setting in self.settingControlList:
-                       if setting.type == 'profile':
-                               setting.SetValue(profile.getProfileSetting(setting.configName))
-                       else:
-                               setting.SetValue(profile.getPreference(setting.configName))
+                       setting.SetValue(setting.setting.getValue())
+               self.Update()
+
+       def _validate(self):
+               for setting in self.settingControlList:
+                       setting._validate()
+               if self._callback is not None:
+                       self._callback()
 
-class TitleRow():
+       def getLabelColumnWidth(self, panel):
+               maxWidth = 0
+               for child in panel.GetChildren():
+                       if isinstance(child, wx.lib.stattext.GenStaticText):
+                               maxWidth = max(maxWidth, child.GetSize()[0])
+               return maxWidth
+       
+       def setLabelColumnWidth(self, panel, width):
+               for child in panel.GetChildren():
+                       if isinstance(child, wx.lib.stattext.GenStaticText):
+                               size = child.GetSize()
+                               size[0] = width
+                               child.SetBestSize(size)
+       
+class TitleRow(object):
        def __init__(self, panel, name):
                "Add a title row to the configuration panel"
                sizer = panel.GetSizer()
                x = sizer.GetRows()
-               self.title = wx.StaticText(panel, -1, name)
+               self.title = wx.StaticText(panel, -1, name.replace('&', '&&'))
                self.title.SetFont(wx.Font(wx.SystemSettings.GetFont(wx.SYS_ANSI_VAR_FONT).GetPointSize(), wx.FONTFAMILY_DEFAULT, wx.NORMAL, wx.FONTWEIGHT_BOLD))
-               sizer.Add(self.title, (x,0), (1,3), flag=wx.EXPAND)
-               sizer.Add(wx.StaticLine(panel), (x+1,0), (1,3), flag=wx.EXPAND)
+               sizer.Add(self.title, (x,0), (1,3), flag=wx.EXPAND|wx.TOP|wx.LEFT, border=10)
+               sizer.Add(wx.StaticLine(panel), (x+1,0), (1,3), flag=wx.EXPAND|wx.LEFT,border=10)
                sizer.SetRows(x + 2)
 
-class SettingRow():
-       def __init__(self, panel, label, configName, defaultValue = '', helpText = 'Help: TODO', type = 'profile'):
+class SettingRow(object):
+       def __init__(self, panel, configName, valueOverride = None, index = None):
                "Add a setting to the configuration panel"
                sizer = panel.GetSizer()
                x = sizer.GetRows()
                y = 0
-               
-               self.validators = []
+               flag = 0
+
+               self.setting = profile.settingsDictionary[configName]
+               self.settingIndex = index
                self.validationMsg = ''
-               self.helpText = helpText
-               self.configName = configName
                self.panel = panel
-               self.type = type
 
-               self.label = wx.lib.stattext.GenStaticText(panel, -1, label)
+               self.label = wx.lib.stattext.GenStaticText(panel, -1, self.setting.getLabel())
                self.label.Bind(wx.EVT_ENTER_WINDOW, self.OnMouseEnter)
                self.label.Bind(wx.EVT_LEAVE_WINDOW, self.OnMouseExit)
 
-               getSettingFunc = profile.getPreference
-               if self.type == 'profile':
-                       getSettingFunc = profile.getProfileSetting
-               if isinstance(defaultValue, types.StringTypes):
-                       self.ctrl = wx.TextCtrl(panel, -1, getSettingFunc(configName))
-                       self.ctrl.Bind(wx.EVT_TEXT, self.OnSettingChange)
-               elif isinstance(defaultValue, types.BooleanType):
+               #if self.setting.getType() is types.FloatType and False:
+               #       digits = 0
+               #       while 1 / pow(10, digits) > defaultValue:
+               #               digits += 1
+               #       self.ctrl = floatspin.FloatSpin(panel, -1, value=float(getSettingFunc(configName)), increment=defaultValue, digits=digits, min_val=0.0)
+               #       self.ctrl.Bind(floatspin.EVT_FLOATSPIN, self.OnSettingChange)
+               #       flag = wx.EXPAND
+               if self.setting.getType() is types.BooleanType:
                        self.ctrl = wx.CheckBox(panel, -1, style=wx.ALIGN_RIGHT)
-                       self.SetValue(getSettingFunc(configName))
+                       self.SetValue(self.setting.getValue(self.settingIndex))
                        self.ctrl.Bind(wx.EVT_CHECKBOX, self.OnSettingChange)
-               else:
-                       self.ctrl = wx.ComboBox(panel, -1, getSettingFunc(configName), choices=defaultValue, style=wx.CB_DROPDOWN|wx.CB_READONLY)
+               elif valueOverride is not None and valueOverride is wx.Colour:
+                       self.ctrl = wx.ColourPickerCtrl(panel, -1)
+                       self.SetValue(self.setting.getValue(self.settingIndex))
+                       self.ctrl.Bind(wx.EVT_COLOURPICKER_CHANGED, self.OnSettingChange)
+               elif type(self.setting.getType()) is list or valueOverride is not None:
+                       value = self.setting.getValue(self.settingIndex)
+                       choices = self.setting.getType()
+                       if valueOverride is not None:
+                               choices = valueOverride
+                       self._englishChoices = choices[:]
+                       if value not in choices and len(choices) > 0:
+                               value = choices[0]
+                       for n in xrange(0, len(choices)):
+                               choices[n] = _(choices[n])
+                       value = _(value)
+                       self.ctrl = wx.ComboBox(panel, -1, value, choices=choices, style=wx.CB_DROPDOWN|wx.CB_READONLY)
                        self.ctrl.Bind(wx.EVT_COMBOBOX, self.OnSettingChange)
+                       self.ctrl.Bind(wx.EVT_LEFT_DOWN, self.OnMouseExit)
+                       flag = wx.EXPAND
+               else:
+                       self.ctrl = wx.TextCtrl(panel, -1, self.setting.getValue(self.settingIndex))
+                       self.ctrl.Bind(wx.EVT_TEXT, self.OnSettingChange)
+                       flag = wx.EXPAND
 
-               sizer.Add(self.label, (x,y), flag=wx.ALIGN_CENTER_VERTICAL)
-               sizer.Add(self.ctrl, (x,y+1), flag=wx.ALIGN_BOTTOM|wx.EXPAND)
+               sizer.Add(self.label, (x,y), flag=wx.ALIGN_CENTER_VERTICAL|wx.LEFT,border=10)
+               sizer.Add(self.ctrl, (x,y+1), flag=wx.ALIGN_BOTTOM|flag)
                sizer.SetRows(x+1)
-               
-               self.defaultBGColour = self.ctrl.GetBackgroundColour()
+
+               self.ctrl.Bind(wx.EVT_ENTER_WINDOW, self.OnMouseEnter)
+               self.ctrl.Bind(wx.EVT_LEAVE_WINDOW, self.OnMouseExit)
+               if isinstance(self.ctrl, floatspin.FloatSpin):
+                       self.ctrl.GetTextCtrl().Bind(wx.EVT_ENTER_WINDOW, self.OnMouseEnter)
+                       self.ctrl.GetTextCtrl().Bind(wx.EVT_LEAVE_WINDOW, self.OnMouseExit)
+                       self.defaultBGColour = self.ctrl.GetTextCtrl().GetBackgroundColour()
+               else:
+                       self.defaultBGColour = self.ctrl.GetBackgroundColour()
                
                panel.main.settingControlList.append(self)
 
@@ -141,55 +215,52 @@ class SettingRow():
 
        def OnMouseExit(self, e):
                self.panel.main.OnPopupHide(self)
+               e.Skip()
 
        def OnSettingChange(self, e):
-               if self.type == 'profile':
-                       profile.putProfileSetting(self.configName, self.GetValue())
-               else:
-                       profile.putPreference(self.configName, self.GetValue())
-               result = validators.SUCCESS
-               msgs = []
-               for validator in self.validators:
-                       res, err = validator.validate()
-                       if res == validators.ERROR:
-                               result = res
-                       elif res == validators.WARNING and result != validators.ERROR:
-                               result = res
-                       if res != validators.SUCCESS:
-                               msgs.append(err)
+               self.setting.setValue(self.GetValue(), self.settingIndex)
+               self.panel.main._validate()
+
+       def _validate(self):
+               result, msg = self.setting.validate()
+
+               ctrl = self.ctrl
+               if isinstance(ctrl, floatspin.FloatSpin):
+                       ctrl = ctrl.GetTextCtrl()
                if result == validators.ERROR:
-                       self.ctrl.SetBackgroundColour('Red')
+                       ctrl.SetBackgroundColour('Red')
                elif result == validators.WARNING:
-                       self.ctrl.SetBackgroundColour('Yellow')
+                       ctrl.SetBackgroundColour('Yellow')
                else:
-                       self.ctrl.SetBackgroundColour(self.defaultBGColour)
-               self.ctrl.Refresh()
+                       ctrl.SetBackgroundColour(self.defaultBGColour)
+               ctrl.Refresh()
 
-               self.validationMsg = '\n'.join(msgs)
+               self.validationMsg = msg
                self.panel.main.UpdatePopup(self)
 
        def GetValue(self):
-               return str(self.ctrl.GetValue())
+               if isinstance(self.ctrl, wx.ColourPickerCtrl):
+                       return str(self.ctrl.GetColour().GetAsString(wx.C2S_HTML_SYNTAX))
+               elif isinstance(self.ctrl, wx.ComboBox):
+                       value = str(self.ctrl.GetValue())
+                       for ret in self._englishChoices:
+                               if _(ret) == value:
+                                       return ret
+                       return value
+               else:
+                       return str(self.ctrl.GetValue())
 
        def SetValue(self, value):
                if isinstance(self.ctrl, wx.CheckBox):
                        self.ctrl.SetValue(str(value) == "True")
+               elif isinstance(self.ctrl, wx.ColourPickerCtrl):
+                       self.ctrl.SetColour(value)
+               elif isinstance(self.ctrl, floatspin.FloatSpin):
+                       try:
+                               self.ctrl.SetValue(float(value))
+                       except ValueError:
+                               pass
+               elif isinstance(self.ctrl, wx.ComboBox):
+                       self.ctrl.SetValue(_(value))
                else:
                        self.ctrl.SetValue(value)
-
-#Settings notify works as a validator, but instead of validating anything, it calls another function, which can use the value.
-# A bit hacky, bit it works.
-class settingNotify():
-       def __init__(self, setting, func):
-               self.setting = setting
-               self.setting.validators.append(self)
-               self.func = func
-       
-       def validate(self):
-               try:
-                       f = float(self.setting.GetValue())
-                       self.func(f)
-                       return validators.SUCCESS, ''
-               except ValueError:
-                       self.func()
-                       return validators.SUCCESS, ''