chiark / gitweb /
Tell user to connect and power on 3D printer before attempting to flash firmware
[cura.git] / Cura / gui / pluginPanel.py
1 __copyright__ = "Copyright (C) 2013 David Braam - Released under terms of the AGPLv3 License"
2
3 import wx
4 import os
5 import webbrowser
6 from wx.lib import scrolledpanel
7
8 from Cura.util import profile
9 from Cura.util import pluginInfo
10 from Cura.util import explorer
11
12 class ListBoxEnh(wx.ListBox):
13         def GetValue(self):
14                 return wx.ListBox.GetSelection(self)
15
16 class pluginPanel(wx.Panel):
17         def __init__(self, parent, callback):
18                 wx.Panel.__init__(self, parent,-1)
19                 #Plugin page
20                 self.pluginList = pluginInfo.getPluginList("postprocess")
21                 self.callback = callback
22
23                 sizer = wx.GridBagSizer(2, 2)
24                 self.SetSizer(sizer)
25
26                 pluginStringList = []
27                 for p in self.pluginList:
28                         pluginStringList.append(p.getName())
29
30                 self.listbox = wx.ListBox(self, -1, choices=pluginStringList)
31                 title = wx.StaticText(self, -1, _("Plugins:"))
32                 title.SetFont(wx.Font(wx.SystemSettings.GetFont(wx.SYS_ANSI_VAR_FONT).GetPointSize(), wx.FONTFAMILY_DEFAULT, wx.NORMAL, wx.FONTWEIGHT_BOLD))
33                 helpButton = wx.Button(self, -1, '?', style=wx.BU_EXACTFIT)
34                 addButton = wx.Button(self, -1, 'V', style=wx.BU_EXACTFIT)
35                 openPluginLocationButton = wx.Button(self, -1, _("Open plugin location"))
36                 sb = wx.StaticBox(self, label=_("Enabled plugins"))
37                 boxsizer = wx.StaticBoxSizer(sb, wx.VERTICAL)
38                 self.pluginEnabledPanel = scrolledpanel.ScrolledPanel(self)
39                 self.pluginEnabledPanel.SetupScrolling(False, True)
40
41                 sizer.Add(title, (0,0), border=10, flag=wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.TOP)
42                 sizer.Add(helpButton, (0,1), border=10, flag=wx.ALIGN_RIGHT|wx.RIGHT|wx.TOP)
43                 sizer.Add(self.listbox, (1,0), span=(2,2), border=10, flag=wx.EXPAND|wx.LEFT|wx.RIGHT)
44                 sizer.Add(addButton, (3,0), span=(1,2), border=5, flag=wx.ALIGN_CENTER_HORIZONTAL|wx.ALIGN_BOTTOM)
45                 sizer.Add(boxsizer, (4,0), span=(4,2), border=10, flag=wx.EXPAND|wx.LEFT|wx.RIGHT)
46                 sizer.Add(openPluginLocationButton, (8, 0), border=10, flag=wx.LEFT|wx.BOTTOM)
47                 boxsizer.Add(self.pluginEnabledPanel, 1, flag=wx.EXPAND)
48
49                 sizer.AddGrowableCol(0)
50                 sizer.AddGrowableRow(1) # Plugins list box
51                 sizer.AddGrowableRow(4) # Enabled plugins
52                 sizer.AddGrowableRow(5) # Enabled plugins
53                 sizer.AddGrowableRow(6) # Enabled plugins
54
55                 sizer = wx.BoxSizer(wx.VERTICAL)
56                 self.pluginEnabledPanel.SetSizer(sizer)
57
58                 self.Bind(wx.EVT_BUTTON, self.OnAdd, addButton)
59                 self.Bind(wx.EVT_BUTTON, self.OnGeneralHelp, helpButton)
60                 self.Bind(wx.EVT_BUTTON, self.OnOpenPluginLocation, openPluginLocationButton)
61                 self.listbox.Bind(wx.EVT_LEFT_DCLICK, self.OnAdd)
62                 self.panelList = []
63                 self.updateProfileToControls()
64
65         def updateProfileToControls(self):
66                 self.pluginConfig = pluginInfo.getPostProcessPluginConfig()
67                 for p in self.panelList:
68                         p.Show(False)
69                         self.pluginEnabledPanel.GetSizer().Detach(p)
70                 self.panelList = []
71                 for pluginConfig in self.pluginConfig:
72                         self._buildPluginPanel(pluginConfig)
73
74         def _buildPluginPanel(self, pluginConfig):
75                 plugin = None
76                 for pluginTest in self.pluginList:
77                         if pluginTest.getFilename() == pluginConfig['filename']:
78                                 plugin = pluginTest
79                 if plugin is None:
80                         return False
81
82                 pluginPanel = wx.Panel(self.pluginEnabledPanel)
83                 s = wx.GridBagSizer(2, 2)
84                 pluginPanel.SetSizer(s)
85                 title = wx.StaticText(pluginPanel, -1, plugin.getName())
86                 title.SetFont(wx.Font(wx.SystemSettings.GetFont(wx.SYS_ANSI_VAR_FONT).GetPointSize(), wx.FONTFAMILY_DEFAULT, wx.NORMAL, wx.FONTWEIGHT_BOLD))
87                 remButton = wx.Button(pluginPanel, -1, 'X', style=wx.BU_EXACTFIT)
88                 helpButton = wx.Button(pluginPanel, -1, '?', style=wx.BU_EXACTFIT)
89                 s.Add(title, pos=(0,1), span=(1,2), flag=wx.ALIGN_BOTTOM|wx.TOP|wx.LEFT|wx.RIGHT, border=5)
90                 s.Add(helpButton, pos=(0,0), span=(1,1), flag=wx.TOP|wx.LEFT|wx.ALIGN_RIGHT, border=5)
91                 s.Add(remButton, pos=(0,3), span=(1,1), flag=wx.TOP|wx.RIGHT|wx.ALIGN_RIGHT, border=5)
92                 s.Add(wx.StaticLine(pluginPanel), pos=(1,0), span=(1,4), flag=wx.EXPAND|wx.LEFT|wx.RIGHT,border=3)
93                 info = wx.StaticText(pluginPanel, -1, plugin.getInfo())
94                 info.Wrap(300)
95                 s.Add(info, pos=(2,0), span=(1,4), flag=wx.EXPAND|wx.LEFT|wx.RIGHT,border=3)
96
97                 pluginPanel.paramCtrls = {}
98                 i = 0
99                 for param in plugin.getParams():
100                         if param['type'].lower() == 'bool': #check for type bool in plugin
101                                 if param['default'].lower() in ["true","false"]:
102                                         value = param['default'].lower()=="true" #sets default 'true'
103                                 else:
104                                         value = int(param['default'])
105                         elif param['type'].lower() == 'list': #check for 'type' list in plugin
106                                 ListOfItems = param['default'].split(',') #prepares selection entries
107                                 value = 0 #sets default selection first entry
108                         else:
109                                 value = param['default']
110                         if param['name'] in pluginConfig['params']:
111                                 value = pluginConfig['params'][param['name']]
112                         s.Add(wx.StaticText(pluginPanel, -1, param['description']), pos=(3+i,0), span=(1,2), flag=wx.LEFT|wx.RIGHT|wx.ALIGN_CENTER_VERTICAL,border=3)
113                         if param['type'].lower() == 'bool': #checks for type boolean, displays checkbox and sets stored value
114                                 ctrl = wx.CheckBox(pluginPanel, -1, "")
115                                 ctrl.SetValue(value in {"TRUE",True,1})
116                                 s.Add(ctrl, pos=(3+i,2), span=(1,2), flag=wx.EXPAND|wx.LEFT|wx.RIGHT,border=3)
117                                 ctrl.Bind(wx.EVT_CHECKBOX, self.OnSettingChange) #bind the checkbox event to the same method as for the standard text boxes
118                         elif param['type'].lower() == 'list': #checks for 'type' list, displays listbox and sets stored value (integer)
119                                 ctrl = ListBoxEnh(pluginPanel, -1, wx.DefaultPosition, (-1,(wx.SystemSettings.GetFont(wx.SYS_ANSI_VAR_FONT).GetPixelSize()[1]+1)*len(ListOfItems)+6), ListOfItems)
120                                 ctrl.Select(value)
121                                 s.Add(ctrl, pos=(3+i,2), span=(1,2), flag=wx.EXPAND|wx.LEFT|wx.RIGHT,border=3)
122                                 ctrl.Bind(wx.EVT_LISTBOX, self.OnSettingChange) #bind the listbox event to the same method as for the standard text boxes (derived class necessary due to usage of SetValue method)
123                         else: #standard text box
124                                 ctrl = wx.TextCtrl(pluginPanel, -1, value)
125                                 s.Add(ctrl, pos=(3+i,2), span=(1,2), flag=wx.EXPAND|wx.LEFT|wx.RIGHT,border=3)
126                                 ctrl.Bind(wx.EVT_TEXT, self.OnSettingChange)
127
128                         pluginPanel.paramCtrls[param['name']] = ctrl
129
130                         i += 1
131                 s.Add(wx.StaticLine(pluginPanel), pos=(3+i,0), span=(1,4), flag=wx.EXPAND|wx.LEFT|wx.RIGHT,border=3)
132
133                 self.Bind(wx.EVT_BUTTON, self.OnRem, remButton)
134                 self.Bind(wx.EVT_BUTTON, self.OnHelp, helpButton)
135
136                 s.AddGrowableCol(1)
137                 pluginPanel.SetBackgroundColour(self.GetParent().GetBackgroundColour())
138                 self.pluginEnabledPanel.GetSizer().Add(pluginPanel, flag=wx.EXPAND)
139                 self.pluginEnabledPanel.Layout()
140                 self.pluginEnabledPanel.SetSize((1,1))
141                 self.Layout()
142                 self.pluginEnabledPanel.ScrollChildIntoView(pluginPanel)
143                 self.panelList.append(pluginPanel)
144                 return True
145
146         def OnSettingChange(self, e):
147                 for panel in self.panelList:
148                         idx = self.panelList.index(panel)
149                         for k in panel.paramCtrls.keys():
150                                 if type(panel.paramCtrls[k].GetValue()) == bool:
151                                         self.pluginConfig[idx]['params'][k] = int(panel.paramCtrls[k].GetValue())
152                                 else:
153                                         self.pluginConfig[idx]['params'][k] = panel.paramCtrls[k].GetValue()
154                 pluginInfo.setPostProcessPluginConfig(self.pluginConfig)
155                 self.callback()
156
157         def OnAdd(self, e):
158                 if self.listbox.GetSelection() < 0:
159                         wx.MessageBox(_("You need to select a plugin before you can add anything."), _("Error: no plugin selected"), wx.OK | wx.ICON_INFORMATION)
160                         return
161                 p = self.pluginList[self.listbox.GetSelection()]
162                 newConfig = {'filename': p.getFilename(), 'params': {}}
163                 if not self._buildPluginPanel(newConfig):
164                         return
165                 self.pluginConfig.append(newConfig)
166                 pluginInfo.setPostProcessPluginConfig(self.pluginConfig)
167                 self.callback()
168
169         def OnRem(self, e):
170                 panel = e.GetEventObject().GetParent()
171                 sizer = self.pluginEnabledPanel.GetSizer()
172                 idx = self.panelList.index(panel)
173
174                 panel.Show(False)
175                 for p in self.panelList:
176                         sizer.Detach(p)
177                 self.panelList.pop(idx)
178                 for p in self.panelList:
179                                 sizer.Add(p, flag=wx.EXPAND)
180
181                 self.pluginEnabledPanel.Layout()
182                 self.pluginEnabledPanel.SetSize((1,1))
183                 self.Layout()
184
185                 self.pluginConfig.pop(idx)
186                 pluginInfo.setPostProcessPluginConfig(self.pluginConfig)
187                 self.callback()
188
189         def OnHelp(self, e):
190                 panel = e.GetEventObject().GetParent()
191                 idx = self.panelList.index(panel)
192
193                 fname = self.pluginConfig[idx]['filename'].lower()
194                 fname = fname[0].upper() + fname[1:]
195                 fname = fname[:fname.rfind('.')]
196                 webbrowser.open('http://wiki.ultimaker.com/CuraPlugin:_' + fname)
197
198         def OnGeneralHelp(self, e):
199                 webbrowser.open('http://wiki.ultimaker.com/Category:CuraPlugin')
200
201         def OnOpenPluginLocation(self, e):
202                 if not os.path.exists(pluginInfo.getPluginBasePaths()[0]):
203                         os.mkdir(pluginInfo.getPluginBasePaths()[0])
204                 explorer.openExplorerPath(pluginInfo.getPluginBasePaths()[0])
205
206         def GetActivePluginCount(self):
207                 pluginCount = 0
208                 for pluginConfig in self.pluginConfig:
209                         self._buildPluginPanel(pluginConfig)
210
211                         for pluginTest in self.pluginList:
212                                 if pluginTest.getFilename() == pluginConfig['filename']:
213                                         pluginCount += 1
214
215                 return pluginCount