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') == _("All"):
82 selectedMaterialType = profile.getProfileSetting('simpleModeMaterialType')
83 elif selectedMaterial is None or len(selectedMaterial.types) == 0:
84 selectedMaterialType = _("Others")
86 selectedMaterialType = selectedMaterial.types[0]
88 # Decide to show the material types or not
89 if self._print_material_types is None:
90 self.printMaterialTypesPanel.Show(False)
92 self.printTypePanel = wx.Panel(self)
94 sizer = wx.GridBagSizer()
97 boxsizer = wx.BoxSizer(wx.VERTICAL)
98 boxsizer.SetMinSize((80, 20))
99 if self._print_material_types is None:
100 self.materialTypeCombo = None
102 choices = self._print_material_types.keys()
103 choices.sort(key=lambda type: sum([mat.order for mat in self._print_material_types[type]]))
104 # Now we can add Others, so it appears towards the end
105 if len(other_print_material_types) > 0:
106 self._print_material_types[_("Others")] = other_print_material_types
107 choices.append(_("Others"))
108 choices.append(_("All"))
109 label = wx.StaticText(self.printMaterialTypesPanel, label=_("Material ease of use:"))
110 self.materialTypeCombo = wx.ComboBox(self.printMaterialTypesPanel, -1, selectedMaterialType,
111 choices=choices, style=wx.CB_READONLY)
112 self.materialTypeCombo.Bind(wx.EVT_COMBOBOX, self._materialTypeSelected)
113 boxsizer.Add(label, flag=wx.EXPAND)
114 boxsizer.Add(self.materialTypeCombo, border=5, flag=wx.BOTTOM|wx.TOP|wx.EXPAND)
115 self.printMaterialTypesPanel.SetSizer(boxsizer)
116 sizer.Add(self.printMaterialTypesPanel, (0,0), border=10, flag=wx.EXPAND|wx.RIGHT|wx.LEFT|wx.TOP)
118 if self._print_material_types is None:
119 sb = wx.StaticBox(self.printMaterialPanel, label=_("Material:"))
120 boxsizer = wx.StaticBoxSizer(sb, wx.VERTICAL)
121 boxsizer.SetMinSize((80, 20))
122 for button in self._print_material_options:
123 # wxpython 2.8 gives a 13 pixel high radio/checkbutton but wxpython 3.0
124 # gives it a 25 pixels height, so we add a border to compensate for the ugliness
125 if button.GetBestSize()[1] < 20:
129 boxsizer.Add(button, border=border, flag=wx.ALL)
130 self.printMaterialPanel.SetSizer(wx.BoxSizer(wx.VERTICAL))
131 self.printMaterialPanel.GetSizer().Add(boxsizer, flag=wx.EXPAND)
132 self.materialCombo = None
134 boxsizer = wx.BoxSizer(wx.VERTICAL)
135 boxsizer.SetMinSize((80, 20))
136 label = wx.StaticText(self.printMaterialPanel, label=_("Material:"))
137 self.materialCombo = wx.ComboBox(self.printMaterialPanel, -1, selectedMaterial.name,
138 choices=[], style=wx.CB_READONLY)
139 self.materialCombo.Bind(wx.EVT_COMBOBOX, self._materialSelected)
140 boxsizer.Add(label, flag=wx.EXPAND)
141 boxsizer.Add(self.materialCombo, border=5, flag=wx.BOTTOM|wx.TOP|wx.EXPAND)
142 self.printMaterialPanel.SetSizer(boxsizer)
143 self.materialHyperlink = wx.HyperlinkCtrl(self.printMaterialPanel, -1, label=_('Material Information'), url='',
144 style=wx.HL_ALIGN_LEFT|wx.BORDER_NONE|wx.HL_CONTEXTMENU)
145 self.materialHyperlink.Show(False)
146 self.materialDescription = wx.StaticText(self.printMaterialPanel, -1, '')
147 self.materialDescription.Show(False)
148 boxsizer.Add(self.materialDescription, border=5, flag=wx.BOTTOM|wx.TOP|wx.EXPAND)
149 boxsizer.Add(self.materialHyperlink, border=5, flag=wx.BOTTOM|wx.TOP|wx.EXPAND)
150 sizer.Add(self.printMaterialPanel, (1,0), border=10, flag=wx.EXPAND|wx.RIGHT|wx.LEFT|wx.TOP)
152 sb = wx.StaticBox(self.printTypePanel, label=_("Select a quickprint profile:"))
153 boxsizer = wx.StaticBoxSizer(sb, wx.VERTICAL)
154 boxsizer.SetMinSize((180, 20))
155 self.printTypePanel.SetSizer(wx.BoxSizer(wx.VERTICAL))
156 self.printTypePanel.GetSizer().Add(boxsizer, flag=wx.EXPAND)
157 sizer.Add(self.printTypePanel, (2,0), border=10, flag=wx.EXPAND|wx.RIGHT|wx.LEFT|wx.TOP)
160 self.printOptionsBox = wx.StaticBox(self, label=_("Other options:"))
161 boxsizer = wx.StaticBoxSizer(self.printOptionsBox, wx.VERTICAL)
162 boxsizer.SetMinSize((100, 20))
163 sizer.Add(boxsizer, (3,0), border=10, flag=wx.EXPAND|wx.RIGHT|wx.LEFT|wx.TOP)
164 self.printOptionsSizer = boxsizer
166 if selectedMaterialType:
167 self.materialTypeCombo.SetValue(selectedMaterialType)
168 self._materialTypeSelected(None)
170 if self.materialCombo:
171 self.materialCombo.SetValue(selectedMaterial.name)
173 for button in self._print_material_options:
174 if button.profile == selectedMaterial:
175 button.SetValue(True)
177 self._materialSelected(None)
180 def _materialTypeSelected(self, e):
181 materialType = self.materialTypeCombo.GetValue()
182 selection = self.materialTypeCombo.GetSelection()
185 if selection >= len(self._print_material_types.keys()) or \
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()) or \
224 materials = self._all_print_materials
226 materials = self._print_material_types[materialType]
228 selection = self.materialCombo.GetSelection()
230 return materials[selection]
232 for button in self._print_material_options:
233 if button.GetValue():
234 return button.profile
238 def _materialSelected(self, e):
239 material = self._getSelectedMaterial()
241 # Delete profile options
242 boxsizer = self.printTypePanel.GetSizer().GetItem(0).GetSizer()
244 self._print_profile_options = []
247 self.printOptionsBox.Show(False)
248 self.printTypePanel.Show(False)
250 self.printOptionsBox.Show(True)
251 self.printTypePanel.Show(True)
253 self.materialHyperlink.Show(material.url is not None)
255 self.materialHyperlink.SetURL(material.url)
256 self.materialDescription.Show(material.description is not None)
257 if material.description:
258 self.materialDescription.SetLabel(material.description)
261 selectedProfile = None
262 for print_profile in material.profiles:
263 if print_profile.disabled:
265 button = wx.RadioButton(self.printTypePanel, -1, print_profile.name.replace('&', '&&'),
266 style=wx.RB_GROUP if len(self._print_profile_options) == 0 else 0)
267 button.profile = print_profile
268 self._print_profile_options.append(button)
269 if profile.getProfileSetting('simpleModeProfile') == print_profile.name:
270 selectedProfile = button
272 # Decide on the profile to be selected by default
273 if selectedProfile is None:
274 for button in self._print_profile_options:
275 if button.profile.default:
276 selectedProfile = button
279 if selectedProfile is None and len(self._print_profile_options) > 0:
280 selectedProfile = self._print_profile_options[0]
282 # Decide if we show the profile panel or not
283 if len(self._print_profile_options) < 2:
284 self.printTypePanel.Show(len(self._print_profile_options) > 0 and \
285 self._print_profile_options[0].profile.always_visible)
288 selectedProfile.SetValue(True)
290 # Add profiles to the UI
291 for button in self._print_profile_options:
292 # wxpython 2.8 gives a 13 pixel high radio/checkbutton but wxpython 3.0
293 # gives it a 25 pixels height, so we add a border to compensate for the ugliness
294 if button.GetBestSize()[1] < 20:
298 boxsizer.Add(button, border=border, flag=wx.ALL)
299 button.Bind(wx.EVT_RADIOBUTTON, self._update)
301 # Save current selected options
302 selected_options = []
303 deselected_options = []
304 for button in self._print_other_options:
305 if button.GetValue():
306 selected_options.append(button.profile.name)
308 deselected_options.append(button.profile.name)
310 # Delete profile options
311 boxsizer = self.printOptionsSizer
313 self._print_other_options = []
316 for option in material.options:
319 button = wx.CheckBox(self, -1, option.name.replace('&', '&&'))
320 button.profile = option
321 self._print_other_options.append(button)
322 # Restore selection on similarly named options
323 if option.name in selected_options or \
324 ((not option.name in deselected_options) and option.default):
325 button.SetValue(True)
327 # Decide if we show the profile panel or not
328 # The always_visible doesn't make sense for options since they are checkboxes, and not radio buttons
329 self.printOptionsBox.Show(len(self._print_other_options) > 0)
331 # Add profiles to the UI
332 for button in self._print_other_options:
333 # wxpython 2.8 gives a 13 pixel high radio/checkbutton but wxpython 3.0
334 # gives it a 25 pixels height, so we add a border to compensate for the ugliness
335 if button.GetBestSize()[1] < 20:
339 boxsizer.Add(button, border=border, flag=wx.ALL)
340 button.Bind(wx.EVT_CHECKBOX, self._update)
342 self.printTypePanel.Layout()
344 self.GetParent().Fit()
346 # Do not call the callback on the initial UI build
350 def _update(self, e):
351 if self.materialTypeCombo:
352 materialType = self.materialTypeCombo.GetValue()
353 profile.putProfileSetting('simpleModeMaterialType', materialType)
354 material = self._getSelectedMaterial()
356 profile.putProfileSetting('simpleModeMaterial', material.name)
357 for button in self._print_profile_options:
358 if button.GetValue():
359 profile.putProfileSetting('simpleModeProfile', button.profile.name)
362 def getSettingOverrides(self):
364 for setting in profile.settingsList:
365 if setting.isProfile() or setting.isAlteration():
366 settings[setting.getName()] = setting.getDefault()
368 # Apply materials, profile, then options
369 material = self._getSelectedMaterial()
371 settings.update(material.getProfileDict())
372 for button in self._print_profile_options:
373 if button.GetValue():
374 settings.update(button.profile.getProfileDict())
375 for button in self._print_other_options:
376 if button.GetValue():
377 settings.update(button.profile.getProfileDict())
381 def updateProfileToControls(self):