1 __copyright__ = "Copyright (C) 2013 David Braam - Released under terms of the AGPLv3 License"
6 from wx.lib import scrolledpanel
8 from Cura.util import profile
9 from Cura.util import pluginInfo
10 from Cura.util import explorer
12 class ListBoxEnh(wx.ListBox):
14 return wx.ListBox.GetSelection(self)
16 class pluginPanel(wx.Panel):
17 def __init__(self, parent, callback):
18 wx.Panel.__init__(self, parent,-1)
20 self.pluginList = pluginInfo.getPluginList("postprocess")
21 self.callback = callback
23 sizer = wx.GridBagSizer(2, 2)
27 for p in self.pluginList:
28 pluginStringList.append(p.getName())
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)
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)
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
55 sizer = wx.BoxSizer(wx.VERTICAL)
56 self.pluginEnabledPanel.SetSizer(sizer)
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)
63 self.updateProfileToControls()
65 def updateProfileToControls(self):
66 self.pluginConfig = pluginInfo.getPostProcessPluginConfig()
67 for p in self.panelList:
69 self.pluginEnabledPanel.GetSizer().Detach(p)
71 for pluginConfig in self.pluginConfig:
72 self._buildPluginPanel(pluginConfig)
74 def _buildPluginPanel(self, pluginConfig):
76 for pluginTest in self.pluginList:
77 if pluginTest.getFilename() == pluginConfig['filename']:
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())
95 s.Add(info, pos=(2,0), span=(1,4), flag=wx.EXPAND|wx.LEFT|wx.RIGHT,border=3)
97 pluginPanel.paramCtrls = {}
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'
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
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)
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)
128 pluginPanel.paramCtrls[param['name']] = ctrl
131 s.Add(wx.StaticLine(pluginPanel), pos=(3+i,0), span=(1,4), flag=wx.EXPAND|wx.LEFT|wx.RIGHT,border=3)
133 self.Bind(wx.EVT_BUTTON, self.OnRem, remButton)
134 self.Bind(wx.EVT_BUTTON, self.OnHelp, helpButton)
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))
142 self.pluginEnabledPanel.ScrollChildIntoView(pluginPanel)
143 self.panelList.append(pluginPanel)
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())
153 self.pluginConfig[idx]['params'][k] = panel.paramCtrls[k].GetValue()
154 pluginInfo.setPostProcessPluginConfig(self.pluginConfig)
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)
161 p = self.pluginList[self.listbox.GetSelection()]
162 newConfig = {'filename': p.getFilename(), 'params': {}}
163 if not self._buildPluginPanel(newConfig):
165 self.pluginConfig.append(newConfig)
166 pluginInfo.setPostProcessPluginConfig(self.pluginConfig)
170 panel = e.GetEventObject().GetParent()
171 sizer = self.pluginEnabledPanel.GetSizer()
172 idx = self.panelList.index(panel)
175 for p in self.panelList:
177 self.panelList.pop(idx)
178 for p in self.panelList:
179 sizer.Add(p, flag=wx.EXPAND)
181 self.pluginEnabledPanel.Layout()
182 self.pluginEnabledPanel.SetSize((1,1))
185 self.pluginConfig.pop(idx)
186 pluginInfo.setPostProcessPluginConfig(self.pluginConfig)
190 panel = e.GetEventObject().GetParent()
191 idx = self.panelList.index(panel)
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)
198 def OnGeneralHelp(self, e):
199 webbrowser.open('http://wiki.ultimaker.com/Category:CuraPlugin')
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])
206 def GetActivePluginCount(self):
208 for pluginConfig in self.pluginConfig:
209 self._buildPluginPanel(pluginConfig)
211 for pluginTest in self.pluginList:
212 if pluginTest.getFilename() == pluginConfig['filename']: