1 __copyright__ = "Copyright (C) 2013 David Braam - Released under terms of the AGPLv3 License"
4 import ConfigParser as configparser
7 from Cura.util import profile
8 from Cura.util import resources
10 class simpleModePanel(wx.Panel):
11 "Main user interface window for Quickprint mode"
12 def __init__(self, parent, callback):
13 super(simpleModePanel, self).__init__(parent)
14 self._callback = callback
16 self._print_material_options = []
17 self._print_profile_options = []
18 self._print_other_options = []
19 self._print_material_types = {}
20 self._all_print_materials = []
22 materials = resources.getSimpleModeMaterials()
23 other_print_material_types = []
24 for material in materials:
27 if len(material.types) == 0:
28 other_print_material_types.append(material)
30 for type in material.types:
31 if self._print_material_types.has_key(type):
32 self._print_material_types[type].append(material)
34 self._print_material_types[type] = [material]
36 if len(self._print_material_types) == 0:
37 self._print_material_types = None
39 # Create material buttons
40 self.printMaterialPanel = wx.Panel(self)
41 selectedMaterial = None
42 for material in materials:
45 # Show radio buttons if there are no material types
46 if self._print_material_types is None:
47 button = wx.RadioButton(self.printMaterialPanel, -1, material.name.replace('&', '&&'),
48 style=wx.RB_GROUP if len(self._print_material_options) == 0 else 0)
49 button.profile = material
50 button.Bind(wx.EVT_RADIOBUTTON, self._materialSelected)
51 self._print_material_options.append(button)
52 self._all_print_materials.append(material)
53 if profile.getProfileSetting('simpleModeMaterial') == material.name:
54 selectedMaterial = material
56 # Decide on the default selected material
57 if selectedMaterial is None:
58 for material in self._all_print_materials:
60 selectedMaterial = material
63 if selectedMaterial is None and len(self._all_print_materials) > 0:
64 selectedMaterial = self._all_print_materials[0]
66 # Decide to show the panel or not
67 if self._print_material_types is None and len(self._print_material_options) < 2:
68 self.printMaterialPanel.Show(len(self._print_material_options) > 1 and \
69 self._print_material_options[0].always_visible)
71 # Create material types combobox
72 self.printMaterialTypesPanel = wx.Panel(self)
73 selectedMaterialType = None
74 if self._print_material_types is not None:
75 for material_type in self._print_material_types:
76 if profile.getProfileSetting('simpleModeMaterialType') == material_type and \
77 selectedMaterial in self._print_material_types[material_type]:
78 selectedMaterialType = material_type
80 if selectedMaterialType is None:
81 if profile.getProfileSetting('simpleModeMaterialType') == _("Others") or \
82 profile.getProfileSetting('simpleModeMaterialType') == _("All"):
83 selectedMaterialType = profile.getProfileSetting('simpleModeMaterialType')
84 elif selectedMaterial is None or len(selectedMaterial.types) == 0:
85 selectedMaterialType = _("Others")
87 selectedMaterialType = selectedMaterial.types[0]
89 # Decide to show the material types or not
90 if self._print_material_types is None:
91 self.printMaterialTypesPanel.Show(False)
93 self.printTypePanel = wx.Panel(self)
95 sizer = wx.GridBagSizer()
98 boxsizer = wx.BoxSizer(wx.VERTICAL)
99 boxsizer.SetMinSize((80, 20))
100 if self._print_material_types is None:
101 self.materialTypeCombo = None
103 choices = self._print_material_types.keys()
104 choices.sort(key=lambda type: sum([mat.order for mat in self._print_material_types[type]]))
105 # Now we can add Others, so it appears towards the end
106 if len(other_print_material_types) > 0:
107 self._print_material_types[_("Others")] = other_print_material_types
108 choices.append(_("Others"))
109 choices.append(_("All"))
110 label = wx.StaticText(self.printMaterialTypesPanel, label=_("Material ease of use:"))
111 self.materialTypeCombo = wx.ComboBox(self.printMaterialTypesPanel, -1, selectedMaterialType,
112 choices=choices, style=wx.CB_READONLY)
113 self.materialTypeCombo.Bind(wx.EVT_COMBOBOX, self._materialTypeSelected)
114 boxsizer.Add(label, flag=wx.EXPAND)
115 boxsizer.Add(self.materialTypeCombo, border=5, flag=wx.BOTTOM|wx.TOP|wx.EXPAND)
116 self.printMaterialTypesPanel.SetSizer(boxsizer)
117 sizer.Add(self.printMaterialTypesPanel, (0,0), border=10, flag=wx.EXPAND|wx.RIGHT|wx.LEFT|wx.TOP)
119 if self._print_material_types is None:
120 sb = wx.StaticBox(self.printMaterialPanel, label=_("Material:"))
121 boxsizer = wx.StaticBoxSizer(sb, wx.VERTICAL)
122 boxsizer.SetMinSize((80, 20))
123 for button in self._print_material_options:
124 # wxpython 2.8 gives a 13 pixel high radio/checkbutton but wxpython 3.0
125 # gives it a 25 pixels height, so we add a border to compensate for the ugliness
126 if button.GetBestSize()[1] < 20:
130 boxsizer.Add(button, border=border, flag=wx.ALL)
131 self.printMaterialPanel.SetSizer(wx.BoxSizer(wx.VERTICAL))
132 self.printMaterialPanel.GetSizer().Add(boxsizer, flag=wx.EXPAND)
133 self.materialCombo = None
135 boxsizer = wx.BoxSizer(wx.VERTICAL)
136 boxsizer.SetMinSize((80, 20))
137 label = wx.StaticText(self.printMaterialPanel, label=_("Material:"))
138 self.materialCombo = wx.ComboBox(self.printMaterialPanel, -1, selectedMaterial.name,
139 choices=[], style=wx.CB_READONLY)
140 self.materialCombo.Bind(wx.EVT_COMBOBOX, self._materialSelected)
141 boxsizer.Add(label, flag=wx.EXPAND)
142 boxsizer.Add(self.materialCombo, border=5, flag=wx.BOTTOM|wx.TOP|wx.EXPAND)
143 self.printMaterialPanel.SetSizer(boxsizer)
144 self.materialHyperlink = wx.HyperlinkCtrl(self.printMaterialPanel, -1, label=_('Material Information'), url='',
145 style=wx.HL_ALIGN_LEFT|wx.BORDER_NONE|wx.HL_CONTEXTMENU)
146 self.materialHyperlink.Show(False)
147 self.materialDescription = wx.StaticText(self.printMaterialPanel, -1, '')
148 self.materialDescription.Show(False)
149 boxsizer.Add(self.materialDescription, border=5, flag=wx.BOTTOM|wx.TOP|wx.EXPAND)
150 boxsizer.Add(self.materialHyperlink, border=5, flag=wx.BOTTOM|wx.TOP|wx.EXPAND)
151 sizer.Add(self.printMaterialPanel, (1,0), border=10, flag=wx.EXPAND|wx.RIGHT|wx.LEFT|wx.TOP)
153 sb = wx.StaticBox(self.printTypePanel, label=_("Select a quickprint profile:"))
154 boxsizer = wx.StaticBoxSizer(sb, wx.VERTICAL)
155 boxsizer.SetMinSize((180, 20))
156 self.printTypePanel.SetSizer(wx.BoxSizer(wx.VERTICAL))
157 self.printTypePanel.GetSizer().Add(boxsizer, flag=wx.EXPAND)
158 sizer.Add(self.printTypePanel, (2,0), border=10, flag=wx.EXPAND|wx.RIGHT|wx.LEFT|wx.TOP)
161 self.printOptionsBox = wx.StaticBox(self, label=_("Other options:"))
162 boxsizer = wx.StaticBoxSizer(self.printOptionsBox, wx.VERTICAL)
163 boxsizer.SetMinSize((100, 20))
164 sizer.Add(boxsizer, (3,0), border=10, flag=wx.EXPAND|wx.RIGHT|wx.LEFT|wx.TOP)
165 self.printOptionsSizer = boxsizer
167 if selectedMaterialType:
168 self.materialTypeCombo.SetValue(selectedMaterialType)
169 self._materialTypeSelected(None)
171 if self.materialCombo:
172 self.materialCombo.SetValue(selectedMaterial.name)
174 for button in self._print_material_options:
175 if button.profile == selectedMaterial:
176 button.SetValue(True)
178 self._materialSelected(None)
181 def _materialTypeSelected(self, e):
182 materialType = self.materialTypeCombo.GetValue()
183 selection = self.materialTypeCombo.GetSelection()
186 if selection >= len(self._print_material_types.keys()):
187 materials = self._all_print_materials
188 for material in materials:
189 choices.append(material.full_name)
191 materials = self._print_material_types[materialType]
192 for material in materials:
193 choices.append(material.name)
195 # Decide on the default selected material
196 selectedMaterial = None
197 for material in materials:
199 selectedMaterial = material
202 if selectedMaterial is None and len(materials) > 0:
203 selectedMaterial = materials[0]
205 self.materialCombo.Clear()
206 self.materialCombo.AppendItems(choices)
207 if len(materials) == 0:
208 self.printMaterialTypesPanel.Show(False)
210 self.printMaterialTypesPanel.Show(True)
211 self.materialCombo.SetValue(selectedMaterial.name)
213 self.materialCombo.Layout()
214 self.printMaterialPanel.Layout()
215 self._materialSelected(e)
217 def _getSelectedMaterial(self):
218 if self.materialCombo:
219 materialType = self.materialTypeCombo.GetValue()
220 selection = self.materialTypeCombo.GetSelection()
222 if selection >= len(self._print_material_types.keys()):
223 materials = self._all_print_materials
225 materials = self._print_material_types[materialType]
227 selection = self.materialCombo.GetSelection()
229 # This is needed to avoid a wxpython 2.8 bug which returns -1
230 # when the selection is made with SetValue
232 material_name = self.materialCombo.GetValue()
233 for material in materials:
234 if material.name == material_name:
237 return materials[selection]
239 for button in self._print_material_options:
240 if button.GetValue():
241 return button.profile
245 def _materialSelected(self, e):
246 material = self._getSelectedMaterial()
248 # Delete profile options
249 boxsizer = self.printTypePanel.GetSizer().GetItem(0).GetSizer()
251 self._print_profile_options = []
254 self.printOptionsBox.Show(False)
255 self.printTypePanel.Show(False)
257 self.printOptionsBox.Show(True)
258 self.printTypePanel.Show(True)
260 self.materialHyperlink.Show(material.url is not None)
262 self.materialHyperlink.SetURL(material.url)
263 self.materialDescription.Show(material.description is not None)
264 if material.description:
265 self.materialDescription.SetLabel(material.description)
268 selectedProfile = None
269 for print_profile in material.profiles:
270 if print_profile.disabled:
272 button = wx.RadioButton(self.printTypePanel, -1, print_profile.name.replace('&', '&&'),
273 style=wx.RB_GROUP if len(self._print_profile_options) == 0 else 0)
274 button.profile = print_profile
275 self._print_profile_options.append(button)
276 if profile.getProfileSetting('simpleModeProfile') == print_profile.name:
277 selectedProfile = button
279 # Decide on the profile to be selected by default
280 if selectedProfile is None:
281 for button in self._print_profile_options:
282 if button.profile.default:
283 selectedProfile = button
286 if selectedProfile is None and len(self._print_profile_options) > 0:
287 selectedProfile = self._print_profile_options[0]
289 # Decide if we show the profile panel or not
290 if len(self._print_profile_options) < 2:
291 self.printTypePanel.Show(len(self._print_profile_options) > 0 and \
292 self._print_profile_options[0].profile.always_visible)
295 selectedProfile.SetValue(True)
297 # Add profiles to the UI
298 for button in self._print_profile_options:
299 # wxpython 2.8 gives a 13 pixel high radio/checkbutton but wxpython 3.0
300 # gives it a 25 pixels height, so we add a border to compensate for the ugliness
301 if button.GetBestSize()[1] < 20:
305 boxsizer.Add(button, border=border, flag=wx.ALL)
306 button.Bind(wx.EVT_RADIOBUTTON, self._update)
308 # Save current selected options
309 selected_options = []
310 deselected_options = []
311 for button in self._print_other_options:
312 if button.GetValue():
313 selected_options.append(button.profile.name)
315 deselected_options.append(button.profile.name)
317 # Delete profile options
318 boxsizer = self.printOptionsSizer
320 self._print_other_options = []
323 for option in material.options:
326 button = wx.CheckBox(self, -1, option.name.replace('&', '&&'))
327 button.profile = option
328 self._print_other_options.append(button)
329 # Restore selection on similarly named options
330 if option.name in selected_options or \
331 ((not option.name in deselected_options) and option.default):
332 button.SetValue(True)
334 # Decide if we show the profile panel or not
335 # The always_visible doesn't make sense for options since they are checkboxes, and not radio buttons
336 self.printOptionsBox.Show(len(self._print_other_options) > 0)
338 # Add profiles to the UI
339 for button in self._print_other_options:
340 # wxpython 2.8 gives a 13 pixel high radio/checkbutton but wxpython 3.0
341 # gives it a 25 pixels height, so we add a border to compensate for the ugliness
342 if button.GetBestSize()[1] < 20:
346 boxsizer.Add(button, border=border, flag=wx.ALL)
347 button.Bind(wx.EVT_CHECKBOX, self._update)
349 self.printTypePanel.Layout()
351 self.GetParent().Fit()
353 # Do not call the callback on the initial UI build
357 def _update(self, e):
358 if self.materialTypeCombo:
359 materialType = self.materialTypeCombo.GetValue()
360 profile.putProfileSetting('simpleModeMaterialType', materialType)
361 material = self._getSelectedMaterial()
363 profile.putProfileSetting('simpleModeMaterial', material.name)
364 for button in self._print_profile_options:
365 if button.GetValue():
366 profile.putProfileSetting('simpleModeProfile', button.profile.name)
369 def getSettingOverrides(self):
371 for setting in profile.settingsList:
372 if setting.isProfile() or setting.isAlteration():
373 settings[setting.getName()] = setting.getDefault()
375 # Apply materials, profile, then options
376 material = self._getSelectedMaterial()
378 settings.update(material.getProfileDict())
379 for button in self._print_profile_options:
380 if button.GetValue():
381 settings.update(button.profile.getProfileDict())
382 for button in self._print_other_options:
383 if button.GetValue():
384 settings.update(button.profile.getProfileDict())
388 def updateProfileToControls(self):