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 selectedMaterial is None or len(selectedMaterial.types) == 0:
82 selectedMaterialType = _("Others")
84 selectedMaterialType = selectedMaterial.types[0]
86 # Decide to show the material types or not
87 if self._print_material_types is None:
88 self.printMaterialTypesPanel.Show(False)
90 self.printTypePanel = wx.Panel(self)
92 sizer = wx.GridBagSizer()
95 boxsizer = wx.BoxSizer(wx.VERTICAL)
96 boxsizer.SetMinSize((80, 20))
97 if self._print_material_types is None:
98 self.materialTypeCombo = None
100 choices = self._print_material_types.keys()
101 choices.sort(key=lambda type: sum([mat.order for mat in self._print_material_types[type]]))
102 # Now we can add Others, so it appears towards the end
103 if len(other_print_material_types) > 0:
104 self._print_material_types[_("Others")] = other_print_material_types
105 choices.append(_("Others"))
106 choices.append(_("All"))
107 label = wx.StaticText(self.printMaterialTypesPanel, label=_("Material ease of use:"))
108 self.materialTypeCombo = wx.ComboBox(self.printMaterialTypesPanel, -1, selectedMaterialType,
109 choices=choices, style=wx.CB_READONLY)
110 self.materialTypeCombo.Bind(wx.EVT_COMBOBOX, self._materialTypeSelected)
111 boxsizer.Add(label, flag=wx.EXPAND)
112 boxsizer.Add(self.materialTypeCombo, border=5, flag=wx.BOTTOM|wx.TOP|wx.EXPAND)
113 self.printMaterialTypesPanel.SetSizer(boxsizer)
114 sizer.Add(self.printMaterialTypesPanel, (0,0), border=10, flag=wx.EXPAND|wx.RIGHT|wx.LEFT|wx.TOP)
116 if self._print_material_types is None:
117 sb = wx.StaticBox(self.printMaterialPanel, label=_("Material:"))
118 boxsizer = wx.StaticBoxSizer(sb, wx.VERTICAL)
119 boxsizer.SetMinSize((80, 20))
120 for button in self._print_material_options:
121 # wxpython 2.8 gives a 13 pixel high radio/checkbutton but wxpython 3.0
122 # gives it a 25 pixels height, so we add a border to compensate for the ugliness
123 if button.GetBestSize()[1] < 20:
127 boxsizer.Add(button, border=border, flag=wx.ALL)
128 self.printMaterialPanel.SetSizer(wx.BoxSizer(wx.VERTICAL))
129 self.printMaterialPanel.GetSizer().Add(boxsizer, flag=wx.EXPAND)
130 self.materialCombo = None
132 boxsizer = wx.BoxSizer(wx.VERTICAL)
133 boxsizer.SetMinSize((80, 20))
134 label = wx.StaticText(self.printMaterialPanel, label=_("Material:"))
135 self.materialCombo = wx.ComboBox(self.printMaterialPanel, -1, selectedMaterial.name,
136 choices=[], style=wx.CB_READONLY)
137 self.materialCombo.Bind(wx.EVT_COMBOBOX, self._materialSelected)
138 boxsizer.Add(label, flag=wx.EXPAND)
139 boxsizer.Add(self.materialCombo, border=5, flag=wx.BOTTOM|wx.TOP|wx.EXPAND)
140 self.printMaterialPanel.SetSizer(boxsizer)
141 self.materialHyperlink = wx.HyperlinkCtrl(self.printMaterialPanel, -1, label=_('Material Information'), url='',
142 style=wx.HL_ALIGN_LEFT|wx.BORDER_NONE|wx.HL_CONTEXTMENU)
143 self.materialHyperlink.Show(False)
144 self.materialDescription = wx.StaticText(self.printMaterialPanel, -1, '')
145 self.materialDescription.Show(False)
146 boxsizer.Add(self.materialDescription, border=5, flag=wx.BOTTOM|wx.TOP|wx.EXPAND)
147 boxsizer.Add(self.materialHyperlink, border=5, flag=wx.BOTTOM|wx.TOP|wx.EXPAND)
148 sizer.Add(self.printMaterialPanel, (1,0), border=10, flag=wx.EXPAND|wx.RIGHT|wx.LEFT|wx.TOP)
150 sb = wx.StaticBox(self.printTypePanel, label=_("Select a quickprint profile:"))
151 boxsizer = wx.StaticBoxSizer(sb, wx.VERTICAL)
152 boxsizer.SetMinSize((180, 20))
153 self.printTypePanel.SetSizer(wx.BoxSizer(wx.VERTICAL))
154 self.printTypePanel.GetSizer().Add(boxsizer, flag=wx.EXPAND)
155 sizer.Add(self.printTypePanel, (2,0), border=10, flag=wx.EXPAND|wx.RIGHT|wx.LEFT|wx.TOP)
158 self.printOptionsBox = wx.StaticBox(self, label=_("Other options:"))
159 boxsizer = wx.StaticBoxSizer(self.printOptionsBox, wx.VERTICAL)
160 boxsizer.SetMinSize((100, 20))
161 sizer.Add(boxsizer, (3,0), border=10, flag=wx.EXPAND|wx.RIGHT|wx.LEFT|wx.TOP)
162 self.printOptionsSizer = boxsizer
164 if selectedMaterialType:
165 self.materialTypeCombo.SetValue(selectedMaterialType)
166 self._materialTypeSelected(None)
168 if self.materialCombo:
169 self.materialCombo.SetValue(selectedMaterial.name)
171 for button in self._print_material_options:
172 if button.profile == selectedMaterial:
173 button.SetValue(True)
175 self._materialSelected(None)
178 def _materialTypeSelected(self, e):
179 materialType = self.materialTypeCombo.GetValue()
180 selection = self.materialTypeCombo.GetSelection()
183 if selection >= len(self._print_material_types.keys()):
184 materials = self._all_print_materials
185 for material in materials:
186 choices.append(material.full_name)
188 materials = self._print_material_types[materialType]
189 for material in materials:
190 choices.append(material.name)
192 # Decide on the default selected material
193 selectedMaterial = None
194 for material in materials:
196 selectedMaterial = material
199 if selectedMaterial is None and len(materials) > 0:
200 selectedMaterial = materials[0]
202 self.materialCombo.Clear()
203 self.materialCombo.AppendItems(choices)
204 if len(materials) == 0:
205 self.printMaterialTypesPanel.Show(False)
207 self.printMaterialTypesPanel.Show(True)
208 self.materialCombo.SetValue(selectedMaterial.name)
210 self.materialCombo.Layout()
211 self.printMaterialPanel.Layout()
212 self._materialSelected(e)
214 def _getSelectedMaterial(self):
215 if self.materialCombo:
216 materialType = self.materialTypeCombo.GetValue()
217 selection = self.materialTypeCombo.GetSelection()
219 if selection >= len(self._print_material_types.keys()):
220 materials = self._all_print_materials
222 materials = self._print_material_types[materialType]
224 selection = self.materialCombo.GetSelection()
226 # This is needed to avoid a wxpython 2.8 bug which returns -1
227 # when the selection is made with SetValue
229 material_name = self.materialCombo.GetValue()
230 for material in materials:
231 if material.name == material_name:
234 return materials[selection]
236 for button in self._print_material_options:
237 if button.GetValue():
238 return button.profile
242 def _materialSelected(self, e):
243 material = self._getSelectedMaterial()
245 # Delete profile options
246 boxsizer = self.printTypePanel.GetSizer().GetItem(0).GetSizer()
248 self._print_profile_options = []
251 self.printOptionsBox.Show(False)
252 self.printTypePanel.Show(False)
254 self.printOptionsBox.Show(True)
255 self.printTypePanel.Show(True)
257 self.materialHyperlink.Show(material.url is not None)
259 self.materialHyperlink.SetURL(material.url)
260 self.materialDescription.Show(material.description is not None)
261 if material.description:
262 self.materialDescription.SetLabel(material.description)
265 selectedProfile = None
266 for print_profile in material.profiles:
267 if print_profile.disabled:
269 button = wx.RadioButton(self.printTypePanel, -1, print_profile.name.replace('&', '&&'),
270 style=wx.RB_GROUP if len(self._print_profile_options) == 0 else 0)
271 button.profile = print_profile
272 self._print_profile_options.append(button)
273 if profile.getProfileSetting('simpleModeProfile') == print_profile.name:
274 selectedProfile = button
276 # Decide on the profile to be selected by default
277 if selectedProfile is None:
278 for button in self._print_profile_options:
279 if button.profile.default:
280 selectedProfile = button
283 if selectedProfile is None and len(self._print_profile_options) > 0:
284 selectedProfile = self._print_profile_options[0]
286 # Decide if we show the profile panel or not
287 if len(self._print_profile_options) < 2:
288 self.printTypePanel.Show(len(self._print_profile_options) > 0 and \
289 self._print_profile_options[0].profile.always_visible)
292 selectedProfile.SetValue(True)
294 # Add profiles to the UI
295 for button in self._print_profile_options:
296 # wxpython 2.8 gives a 13 pixel high radio/checkbutton but wxpython 3.0
297 # gives it a 25 pixels height, so we add a border to compensate for the ugliness
298 if button.GetBestSize()[1] < 20:
302 boxsizer.Add(button, border=border, flag=wx.ALL)
303 button.Bind(wx.EVT_RADIOBUTTON, self._update)
305 # Save current selected options
306 selected_options = []
307 deselected_options = []
308 for button in self._print_other_options:
309 if button.GetValue():
310 selected_options.append(button.profile.name)
312 deselected_options.append(button.profile.name)
314 # Delete profile options
315 boxsizer = self.printOptionsSizer
317 self._print_other_options = []
320 for option in material.options:
323 button = wx.CheckBox(self, -1, option.name.replace('&', '&&'))
324 button.profile = option
325 self._print_other_options.append(button)
326 # Restore selection on similarly named options
327 if option.name in selected_options or \
328 ((not option.name in deselected_options) and option.default):
329 button.SetValue(True)
331 # Decide if we show the profile panel or not
332 # The always_visible doesn't make sense for options since they are checkboxes, and not radio buttons
333 self.printOptionsBox.Show(len(self._print_other_options) > 0)
335 # Add profiles to the UI
336 for button in self._print_other_options:
337 # wxpython 2.8 gives a 13 pixel high radio/checkbutton but wxpython 3.0
338 # gives it a 25 pixels height, so we add a border to compensate for the ugliness
339 if button.GetBestSize()[1] < 20:
343 boxsizer.Add(button, border=border, flag=wx.ALL)
344 button.Bind(wx.EVT_CHECKBOX, self._update)
346 self.printTypePanel.Layout()
348 self.GetParent().Fit()
350 # Do not call the callback on the initial UI build
354 def _update(self, e):
355 material = self._getSelectedMaterial()
357 profile.putProfileSetting('simpleModeMaterial', material.name)
358 for button in self._print_profile_options:
359 if button.GetValue():
360 profile.putProfileSetting('simpleModeProfile', button.profile.name)
363 def getSettingOverrides(self):
365 for setting in profile.settingsList:
366 if setting.isProfile() or setting.isAlteration():
367 settings[setting.getName()] = setting.getDefault()
369 # Apply materials, profile, then options
370 material = self._getSelectedMaterial()
372 settings.update(material.getProfileDict())
373 for button in self._print_profile_options:
374 if button.GetValue():
375 settings.update(button.profile.getProfileDict())
376 for button in self._print_other_options:
377 if button.GetValue():
378 settings.update(button.profile.getProfileDict())
382 def updateProfileToControls(self):