chiark / gitweb /
Removed _export suffix. Slighty changed some texts.
[cura.git] / Cura / cura_sf / fabmetheus_utilities / settings.py
1 """
2 Settings is a collection of utilities to display, read & write the settings and position widgets.
3
4 """
5
6 from __future__ import absolute_import
7 from __future__ import division
8 #Init has to be imported first because it has code to workaround the python bug where relative imports don't work if the module is imported as a main module.
9 import __init__
10
11 import os, sys
12 import types, math
13
14 from util import profile
15 from fabmetheus_utilities import archive
16
17 def DEFSET(setting):
18         return setting.value
19
20 def storedSetting(name):
21         return lambda setting: profile.getProfileSetting(name)
22 def storedSettingFloat(name):
23         return lambda setting: profile.getProfileSettingFloat(name)
24 def storedSettingInt(name):
25         return lambda setting: int(profile.getProfileSettingFloat(name))
26 def storedPreference(name):
27         return lambda setting: profile.getPreference(name)
28 def storedPreferenceFloat(name):
29         return lambda setting: profile.getPreferenceFloat(name)
30 def storedSettingInvertBoolean(name):
31         return lambda setting: profile.getProfileSetting(name) == "False"
32
33 def ifSettingAboveZero(name):
34         return lambda setting: profile.getProfileSettingFloat(name) > 0
35
36 def ifSettingIs(name, value):
37         return lambda setting: profile.getProfileSetting(name) == value
38
39 def raftLayerCount(setting):
40         if profile.getProfileSetting('enable_raft') == "True":
41                 return '1'
42         return '0'
43
44 def storedPercentSetting(name):
45         return lambda setting: profile.getProfileSettingFloat(name) / 100
46
47 def calculateEdgeWidth(setting):
48         return profile.calculateEdgeWidth()
49
50 def calculateShells(setting):
51         return profile.calculateLineCount() - 1
52
53 def calculateShellsBase(setting):
54         edgeWidth = profile.calculateEdgeWidth()
55         extraWall = profile.getProfileSettingFloat('extra_base_wall_thickness')
56         
57         return profile.calculateLineCount() - 1 + int(extraWall / edgeWidth + 0.0001)
58
59 def calculateSolidLayerCount(setting):
60         return profile.calculateSolidLayerCount()
61
62 def firstLayerSpeedRatio(setting):
63         bottomSpeed = profile.getProfileSettingFloat('bottom_layer_speed')
64         speed = profile.getProfileSettingFloat('print_speed')
65         return bottomSpeed/speed
66
67 def calcSupportDistanceRatio(setting):
68         edgeWidth = calculateEdgeWidth(setting)
69         distance = profile.getProfileSettingFloat('support_distance')
70         return distance / edgeWidth
71
72 def calculateMultiplyDistance(setting):
73         edgeWidth = calculateEdgeWidth(setting)
74         return 10.0 / edgeWidth
75
76 def calcBottomLayerFlowRateRatio(setting):
77         bottomThickness = profile.getProfileSettingFloat('bottom_thickness')
78         layerThickness = profile.getProfileSettingFloat('layer_height')
79         if bottomThickness < layerThickness:
80                 return 1.0
81         return bottomThickness / layerThickness
82
83 def calcExtraBottomThickness(setting):
84         bottomThickness = profile.getProfileSettingFloat('bottom_thickness')
85         layerThickness = profile.getProfileSettingFloat('layer_height')
86         if bottomThickness < layerThickness:
87                 return 0.0
88         return bottomThickness - layerThickness
89
90 def calcLayerSkip(setting):
91         bottomThickness = profile.getProfileSettingFloat('bottom_thickness')
92         layerThickness = profile.getProfileSettingFloat('layer_height')
93         if bottomThickness < layerThickness:
94                 return 0
95         return int(math.ceil((bottomThickness - layerThickness) / layerThickness + 0.0001) - 1)
96
97 def getProfileInformation():
98         return {
99                 'carve': {
100                         'Add_Layer_Template_to_SVG': DEFSET,
101                         'Edge_Width_mm': calculateEdgeWidth,
102                         'Extra_Decimal_Places_float': DEFSET,
103                         'Import_Coarseness_ratio': DEFSET,
104                         'Layer_Height_mm': storedSettingFloat("layer_height"),
105                         'Layers_From_index': calcLayerSkip,
106                         'Layers_To_index': DEFSET,
107                         'Correct_Mesh': DEFSET,
108                         'Unproven_Mesh': DEFSET,
109                         'SVG_Viewer': DEFSET,
110                         'FlipX': storedSetting("flip_x"),
111                         'FlipY': storedSetting("flip_y"),
112                         'FlipZ': storedSetting("flip_z"),
113                         'SwapXZ': storedSetting("swap_xz"),
114                         'SwapYZ': storedSetting("swap_yz"),
115                         'Scale': storedSettingFloat("model_scale"),
116                         'Rotate': storedSettingFloat("model_rotate_base"),
117                         'CenterX': storedSettingFloat("machine_center_x"),
118                         'CenterY': storedSettingFloat("machine_center_y"),
119                         'AlternativeCenterFile': storedSetting("alternative_center"),
120                 },'scale': {
121                         'Activate_Scale': "False",
122                         'XY_Plane_Scale_ratio': DEFSET,
123                         'Z_Axis_Scale_ratio': DEFSET,
124                         'SVG_Viewer': DEFSET,
125                 },'bottom': {
126                         'Activate_Bottom': DEFSET,
127                         'Additional_Height_over_Layer_Thickness_ratio': DEFSET,
128                         'Altitude_mm': calcExtraBottomThickness,
129                         'SVG_Viewer': DEFSET,
130                 },'preface': {
131                         'Meta': DEFSET,
132                         'Set_Positioning_to_Absolute': "False",
133                         'Set_Units_to_Millimeters': "False",
134                         'Start_at_Home': DEFSET,
135                         'Turn_Extruder_Off_at_Shut_Down': DEFSET,
136                         'Turn_Extruder_Off_at_Start_Up': DEFSET,
137                 },'widen': {
138                         'Activate_Widen': DEFSET,
139                         'Widen_Width_over_Edge_Width_ratio': DEFSET,
140                 },'inset': {
141                         'Add_Custom_Code_for_Temperature_Reading': "False",
142                         'Infill_in_Direction_of_Bridge': ifSettingAboveZero('fill_density'),
143                         'Infill_Width': storedSettingFloat("nozzle_size"),
144                         'Loop_Order_Choice': DEFSET,
145                         'Overlap_Removal_Width_over_Perimeter_Width_ratio': DEFSET,
146                         'Turn_Extruder_Heater_Off_at_Shut_Down': "False",
147                         'Volume_Fraction_ratio': DEFSET,
148                 },'fill': {
149                         'Activate_Fill': "True",
150                         'Solid_Surface_Top': storedSetting("solid_top"),
151                         'Override_First_Layer_Sequence': storedSetting("force_first_layer_sequence"),
152                         'Diaphragm_Period_layers': DEFSET,
153                         'Diaphragm_Thickness_layers': DEFSET,
154                         'Extra_Shells_on_Alternating_Solid_Layer_layers': calculateShells,
155                         'Extra_Shells_on_Base_layers': calculateShellsBase,
156                         'Extra_Shells_on_Sparse_Layer_layers': calculateShells,
157                         'Grid_Circle_Separation_over_Perimeter_Width_ratio': DEFSET,
158                         'Grid_Extra_Overlap_ratio': DEFSET,
159                         'Grid_Junction_Separation_Band_Height_layers': DEFSET,
160                         'Grid_Junction_Separation_over_Octogon_Radius_At_End_ratio': DEFSET,
161                         'Grid_Junction_Separation_over_Octogon_Radius_At_Middle_ratio': DEFSET,
162                         'Infill_Begin_Rotation_degrees': DEFSET,
163                         'Infill_Begin_Rotation_Repeat_layers': DEFSET,
164                         'Infill_Odd_Layer_Extra_Rotation_degrees': DEFSET,
165                         'Grid_Circular': ifSettingIs('infill_type', 'Grid Circular'),
166                         'Grid_Hexagonal': ifSettingIs('infill_type', 'Grid Hexagonal'),
167                         'Grid_Rectangular': ifSettingIs('infill_type', 'Grid Rectangular'),
168                         'Line': ifSettingIs('infill_type', 'Line'),
169                         'Infill_Perimeter_Overlap_ratio': storedPercentSetting('fill_overlap'),
170                         'Infill_Solidity_ratio': storedPercentSetting('fill_density'),
171                         'Infill_Width': storedSettingFloat("nozzle_size"),
172                         'Sharpest_Angle_degrees': DEFSET,
173                         'Solid_Surface_Thickness_layers': calculateSolidLayerCount,
174                         'Start_From_Choice': DEFSET,
175                         'Surrounding_Angle_degrees': DEFSET,
176                         'Thread_Sequence_Choice': storedSetting('sequence'),
177                 },'multiply': {
178                         'Activate_Multiply': "False",
179                         'Center_X_mm': storedSettingFloat("machine_center_x"),
180                         'Center_Y_mm': storedSettingFloat("machine_center_y"),
181                         'Number_of_Columns_integer': storedSetting('model_multiply_x'),
182                         'Number_of_Rows_integer': storedSetting('model_multiply_y'),
183                         'Reverse_Sequence_every_Odd_Layer': DEFSET,
184                         'Separation_over_Perimeter_Width_ratio': calculateMultiplyDistance,
185                 },'speed': {
186                         'Activate_Speed': "True",
187                         'Add_Flow_Rate': "True",
188                         'Bridge_Feed_Rate_Multiplier_ratio': storedPercentSetting('bridge_speed'),
189                         'Bridge_Flow_Rate_Multiplier_ratio': storedPercentSetting('bridge_speed'),
190                         'Duty_Cyle_at_Beginning_portion': DEFSET,
191                         'Duty_Cyle_at_Ending_portion': DEFSET,
192                         'Feed_Rate_mm/s': storedSettingFloat("print_speed"),
193                         'Flow_Rate_Setting_float': storedSettingFloat("print_speed"),
194                         'Object_First_Layer_Feed_Rate_Infill_Multiplier_ratio': firstLayerSpeedRatio,
195                         'Object_First_Layer_Feed_Rate_Perimeter_Multiplier_ratio': firstLayerSpeedRatio,
196                         'Object_First_Layer_Feed_Rate_Travel_Multiplier_ratio': firstLayerSpeedRatio,
197                         'Object_First_Layer_Flow_Rate_Infill_Multiplier_ratio': firstLayerSpeedRatio,
198                         'Object_First_Layer_Flow_Rate_Perimeter_Multiplier_ratio': firstLayerSpeedRatio,
199                         'Object_First_Layers_Amount_Of_Layers_For_Speed_Change': DEFSET,
200                         'Orbital_Feed_Rate_over_Operating_Feed_Rate_ratio': DEFSET,
201                         'Maximum_Z_Feed_Rate_mm/s': DEFSET,
202                         'Perimeter_Feed_Rate_Multiplier_ratio': DEFSET,
203                         'Perimeter_Flow_Rate_Multiplier_ratio': DEFSET,
204                         'Travel_Feed_Rate_mm/s': storedSettingFloat("travel_speed"),
205                         'Bottom_layer_flow_rate_ratio': calcBottomLayerFlowRateRatio,
206                 },'temperature': {
207                         'Activate_Temperature': DEFSET,#ifSettingAboveZero('print_temperature'),
208                         'Cooling_Rate_Celcius/second': DEFSET,
209                         'Heating_Rate_Celcius/second': DEFSET,
210                         'Base_Temperature_Celcius': DEFSET,#storedSettingFloat("print_temperature"),
211                         'Interface_Temperature_Celcius': DEFSET,#storedSettingFloat("print_temperature"),
212                         'Object_First_Layer_Infill_Temperature_Celcius': DEFSET,#storedSettingFloat("print_temperature"),
213                         'Object_First_Layer_Perimeter_Temperature_Celcius': DEFSET,#storedSettingFloat("print_temperature"),
214                         'Object_Next_Layers_Temperature_Celcius': DEFSET,#storedSettingFloat("print_temperature"),
215                         'Support_Layers_Temperature_Celcius': DEFSET,#storedSettingFloat("print_temperature"),
216                         'Supported_Layers_Temperature_Celcius': DEFSET,#storedSettingFloat("print_temperature"),
217                 },'raft': {
218                         'Activate_Raft': "True",
219                         'Add_Raft,_Elevate_Nozzle,_Orbit': DEFSET,
220                         'Base_Feed_Rate_Multiplier_ratio': DEFSET,
221                         'Base_Flow_Rate_Multiplier_ratio': storedPercentSetting('raft_base_material_amount'),
222                         'Base_Infill_Density_ratio': DEFSET,
223                         'Base_Layer_Thickness_over_Layer_Thickness': DEFSET,
224                         'Base_Layers_integer': raftLayerCount,
225                         'Base_Nozzle_Lift_over_Base_Layer_Thickness_ratio': DEFSET,
226                         'Initial_Circling': DEFSET,
227                         'Infill_Overhang_over_Extrusion_Width_ratio': DEFSET,
228                         'Interface_Feed_Rate_Multiplier_ratio': DEFSET,
229                         'Interface_Flow_Rate_Multiplier_ratio': storedPercentSetting('raft_interface_material_amount'),
230                         'Interface_Infill_Density_ratio': DEFSET,
231                         'Interface_Layer_Thickness_over_Layer_Thickness': DEFSET,
232                         'Interface_Layers_integer': raftLayerCount,
233                         'Interface_Nozzle_Lift_over_Interface_Layer_Thickness_ratio': DEFSET,
234                         'Name_of_Support_End_File': DEFSET,
235                         'Name_of_Support_Start_File': DEFSET,
236                         'Operating_Nozzle_Lift_over_Layer_Thickness_ratio': DEFSET,
237                         'Raft_Additional_Margin_over_Length_%': DEFSET,
238                         'Raft_Margin_mm': storedSettingFloat('raft_margin'),
239                         'Support_Cross_Hatch': 'False',
240                         'Support_Flow_Rate_over_Operating_Flow_Rate_ratio': storedPercentSetting('support_rate'),
241                         'Support_Gap_over_Perimeter_Extrusion_Width_ratio': calcSupportDistanceRatio,
242                         'Support_Material_Choice_': storedSetting('support'),
243                         'Support_Minimum_Angle_degrees': DEFSET,
244                         'Support_Margin_mm': '3.0',
245                         'Support_Offset_X_mm': lambda setting: -profile.getPreferenceFloat('extruder_offset_x1') if profile.getProfileSetting('support_dual_extrusion') == 'True' and int(profile.getPreference('extruder_amount')) > 1 else '0',
246                         'Support_Offset_Y_mm': lambda setting: -profile.getPreferenceFloat('extruder_offset_y1') if profile.getProfileSetting('support_dual_extrusion') == 'True' and int(profile.getPreference('extruder_amount')) > 1 else '0',
247                 },'skirt': {
248                         'Skirt_line_count': storedSetting("skirt_line_count"),
249                         'Convex': lambda setting: "True" if profile.getProfileSettingFloat('skirt_gap') > 0.0 else "False",
250                         'Gap_Width_mm': storedSetting("skirt_gap"),
251                         'Layers_To_index': "1",
252                 },'joris': {
253                         'Activate_Joris': storedSetting("joris"),
254                         'Layers_From_index': calculateSolidLayerCount,
255                 },'chamber': {
256                         'Activate_Chamber': "False",
257                         'Bed_Temperature_Celcius': DEFSET,
258                         'Bed_Temperature_Begin_Change_Height_mm': DEFSET,
259                         'Bed_Temperature_End_Change_Height_mm': DEFSET,
260                         'Bed_Temperature_End_Celcius': DEFSET,
261                         'Chamber_Temperature_Celcius': DEFSET,
262                         'Holding_Force_bar': DEFSET,
263                 },'tower': {
264                         'Activate_Tower': "False",
265                         'Extruder_Possible_Collision_Cone_Angle_degrees': DEFSET,
266                         'Maximum_Tower_Height_layers': DEFSET,
267                         'Tower_Start_Layer_integer': DEFSET,
268                 },'jitter': {
269                         'Activate_Jitter': "False",
270                         'Jitter_Over_Perimeter_Width_ratio': DEFSET,
271                 },'clip': {
272                         'Activate_Clip': "False",
273                         'Clip_Over_Perimeter_Width_ratio': DEFSET,
274                         'Maximum_Connection_Distance_Over_Perimeter_Width_ratio': DEFSET,
275                 },'smooth': {
276                         'Activate_Smooth': "False",
277                         'Layers_From_index': DEFSET,
278                         'Maximum_Shortening_over_Width_float': DEFSET,
279                 },'stretch': {
280                         'Activate_Stretch': "False",
281                         'Cross_Limit_Distance_Over_Perimeter_Width_ratio': DEFSET,
282                         'Loop_Stretch_Over_Perimeter_Width_ratio': DEFSET,
283                         'Path_Stretch_Over_Perimeter_Width_ratio': DEFSET,
284                         'Perimeter_Inside_Stretch_Over_Perimeter_Width_ratio': DEFSET,
285                         'Perimeter_Outside_Stretch_Over_Perimeter_Width_ratio': DEFSET,
286                         'Stretch_From_Distance_Over_Perimeter_Width_ratio': DEFSET,
287                 },'skin': {
288                         'Activate_Skin': storedSetting("enable_skin"),
289                         'Horizontal_Infill_Divisions_integer': "1",
290                         'Horizontal_Perimeter_Divisions_integer': "1",
291                         'Vertical_Divisions_integer': "2",
292                         'Hop_When_Extruding_Infill': "False",
293                         'Layers_From_index': "1",
294                 },'comb': {
295                         'Activate_Comb': "True",
296                         'Running_Jump_Space_mm': DEFSET,
297                 },'cool': {
298                         'Activate_Cool': "True",
299                         'Bridge_Cool_Celcius': DEFSET,
300                         'Cool_Type': DEFSET,
301                         'Maximum_Cool_Celcius': DEFSET,
302                         'Minimum_Layer_Time_seconds': storedSettingFloat("cool_min_layer_time"),
303                         'Minimum_Orbital_Radius_millimeters': DEFSET,
304                         'Name_of_Cool_End_File': DEFSET,
305                         'Name_of_Cool_Start_File': DEFSET,
306                         'Orbital_Outset_millimeters': DEFSET,
307                         'Turn_Fan_On_at_Beginning': storedSetting("fan_enabled"),
308                         'Turn_Fan_Off_at_Ending': storedSetting("fan_enabled"),
309                         'Minimum_feed_rate_mm/s': storedSettingFloat("cool_min_feedrate"),
310                         'Fan_on_at_layer': storedSettingInt('fan_layer'),
311                         'Fan_speed_min_%': storedSettingInt('fan_speed'),
312                         'Fan_speed_max_%': storedSettingInt('fan_speed_max'),
313                 },'hop': {
314                         'Activate_Hop': "False",
315                         'Hop_Over_Layer_Thickness_ratio': DEFSET,
316                         'Minimum_Hop_Angle_degrees': DEFSET,
317                 },'wipe': {
318                         'Activate_Wipe': "False",
319                         'Arrival_X_mm': DEFSET,
320                         'Arrival_Y_mm': DEFSET,
321                         'Arrival_Z_mm': DEFSET,
322                         'Departure_X_mm': DEFSET,
323                         'Departure_Y_mm': DEFSET,
324                         'Departure_Z_mm': DEFSET,
325                         'Wipe_X_mm': DEFSET,
326                         'Wipe_Y_mm': DEFSET,
327                         'Wipe_Z_mm': DEFSET,
328                         'Wipe_Period_layers': DEFSET,
329                 },'oozebane': {
330                         'Activate_Oozebane': "False",
331                         'After_Startup_Distance_millimeters': DEFSET,
332                         'Early_Shutdown_Distance_millimeters': DEFSET,
333                         'Early_Startup_Distance_Constant_millimeters': DEFSET,
334                         'Early_Startup_Maximum_Distance_millimeters': DEFSET,
335                         'First_Early_Startup_Distance_millimeters': DEFSET,
336                         'Minimum_Distance_for_Early_Startup_millimeters': DEFSET,
337                         'Minimum_Distance_for_Early_Shutdown_millimeters': DEFSET,
338                         'Slowdown_Startup_Steps_positive_integer': DEFSET,
339                 },'dwindle': {
340                         'Activate_Dwindle': "False",
341                         'End_Rate_Multiplier_ratio': '0.5',
342                         'Pent_Up_Volume_cubic_millimeters': "0.4",
343                         'Slowdown_Steps_positive_integer': '5',
344                         'Slowdown_Volume_cubic_millimeters': "5.0",
345                 },'splodge': {
346                         'Activate_Splodge': "False",
347                         'Initial_Lift_over_Extra_Thickness_ratio': DEFSET,
348                         'Initial_Splodge_Feed_Rate_mm/s': DEFSET,
349                         'Operating_Splodge_Feed_Rate_mm/s': DEFSET,
350                         'Operating_Splodge_Quantity_Length_millimeters': DEFSET,
351                         'Initial_Splodge_Quantity_Length_millimeters': DEFSET,
352                         'Operating_Lift_over_Extra_Thickness_ratio': DEFSET,
353                 },'home': {
354                         'Activate_Home': "False",
355                         'Name_of_Home_File': DEFSET,
356                 },'lash': {
357                         'Activate_Lash': "False",
358                         'X_Backlash_mm': DEFSET,
359                         'Y_Backlash_mm': DEFSET,
360                 },'fillet': {
361                         'Activate_Fillet': "False",
362                         'Arc_Point': DEFSET,
363                         'Arc_Radius': DEFSET,
364                         'Arc_Segment': DEFSET,
365                         'Bevel': DEFSET,
366                         'Corner_Feed_Rate_Multiplier_ratio': DEFSET,
367                         'Fillet_Radius_over_Perimeter_Width_ratio': DEFSET,
368                         'Reversal_Slowdown_Distance_over_Perimeter_Width_ratio': DEFSET,
369                         'Use_Intermediate_Feed_Rate_in_Corners': DEFSET,
370                 },'limit': {
371                         'Activate_Limit': "False",
372                         'Maximum_Initial_Feed_Rate_mm/s': DEFSET,
373                 },'unpause': {
374                         'Activate_Unpause': "False",
375                         'Delay_milliseconds': DEFSET,
376                         'Maximum_Speed_ratio': DEFSET,
377                 },'dimension': {
378                         'Activate_Dimension': "True",
379                         'Absolute_Extrusion_Distance': "True",
380                         'Relative_Extrusion_Distance': "False",
381                         'Extruder_Retraction_Speed_mm/s': storedSettingFloat('retraction_speed'),
382                         'Filament_Diameter_mm': storedSettingFloat("filament_diameter"),
383                         'Filament_Packing_Density_ratio': storedSettingFloat("filament_density"),
384                         'Maximum_E_Value_before_Reset_float': DEFSET,
385                         'Minimum_Travel_for_Retraction_millimeters': storedSettingFloat("retraction_min_travel"),
386                         'Retract_Within_Island': storedSettingInvertBoolean("retract_on_jumps_only"),
387                         'Retraction_Distance_millimeters': lambda setting: profile.getProfileSettingFloat('retraction_amount') if profile.getProfileSetting('retraction_enable') == 'True' else 0,
388                         'Restart_Extra_Distance_millimeters': storedSettingFloat('retraction_extra'),
389                 },'alteration': {
390                         'Activate_Alteration': storedSetting('add_start_end_gcode'),
391                         'Name_of_End_File': "end.gcode",
392                         'Name_of_Start_File': "start.gcode",
393                         'Remove_Redundant_Mcode': "True",
394                         'Replace_Variable_with_Setting': DEFSET,
395                 },'export': {
396                         'Activate_Export': "True",
397                         'Add_Descriptive_Extension': DEFSET,
398                         'Add_Export_Suffix': "False",
399                         'Add_Profile_Extension': DEFSET,
400                         'Add_Timestamp_Extension': DEFSET,
401                         'Also_Send_Output_To': DEFSET,
402                         'Analyze_Gcode': DEFSET,
403                         'Comment_Choice': DEFSET,
404                         'Do_Not_Change_Output': DEFSET,
405                         'binary_16_byte': DEFSET,
406                         'gcode_step': DEFSET,
407                         'gcode_time_segment': DEFSET,
408                         'gcode_small': DEFSET,
409                         'File_Extension': storedSetting('gcode_extension'),
410                         'Name_of_Replace_File': DEFSET,
411                         'Save_Penultimate_Gcode': "False",
412                 }
413         }
414
415 def safeConfigName(name):
416         return name.replace("=", "").replace(":", "").replace(" ", "_").replace("(", "").replace(")", "")
417
418 def getReadRepository(repository):
419         "Read the configuration for this 'repository'"
420         
421         info = getProfileInformation()
422         if not info.has_key(repository.name):
423                 print("Warning: Plugin: " + repository.name + " missing from Cura info")
424                 return repository
425         info = info[repository.name]
426         
427         #print('getReadRepository:', repository.name)
428         for p in repository.preferences:
429                 name = safeConfigName(p.name)
430                 if not info.has_key(name):
431                         print("Setting: " + repository.name + ":" + name + " missing from Cura info")
432                         continue
433                 if isinstance(info[name], types.FunctionType):
434                         p.setValueToString(str(info[name](p)))
435                 else:
436                         p.setValueToString(str(info[name]))
437
438         return repository
439
440 def printProgress(layerIndex, procedureName):
441         print("Progress[" + procedureName + ":" + str(layerIndex+1) + "]")
442         sys.stdout.flush()
443
444 def printProgressByNumber(layerIndex, numberOfLayers, procedureName):
445         print("Progress[" + procedureName + ":" + str(layerIndex+1) + ":" + str(numberOfLayers) + "]")
446         sys.stdout.flush()
447
448 def getAlterationFileLines(fileName):
449         'Get the alteration file line and the text lines from the fileName in the alterations directories.'
450         return getAlterationLines(fileName)
451
452 def getAlterationLines(fileName):
453         return archive.getTextLines(getAlterationFile(fileName))
454
455 def getAlterationFile(fileName):
456         return profile.getAlterationFileContents(fileName)
457
458 ####################################
459 ## Configuration settings classes ##
460 ####################################
461
462 class GeneralSetting:
463         "Just a basic setting subclass"
464         def getFromValue( self, name, repository, value ):
465                 #print('GeneralSetting:', name, repository, value )
466                 self.name = name
467                 self.value = value
468                 repository.preferences.append(self)
469                 return self
470
471 class StringSetting(GeneralSetting):
472         "A class to display, read & write a string."
473         def setValueToString(self, value):
474                 self.value = value
475
476 class BooleanSetting( GeneralSetting ):
477         "A class to display, read & write a boolean."
478         def setValueToString(self, value):
479                 self.value = str(value) == "True"
480
481 class LatentStringVar:
482         "This is actually used as 'group' object for Radio buttons. (Did I mention the code is a mess?)"
483         "This class doesn't have a name, and isn't really used for anything. It doesn't even know which repository it belongs to"
484
485 class Radio( BooleanSetting ):
486         "A class to display, read & write a boolean with associated radio button."
487         def getFromRadio( self, latentStringVar, name, repository, value ):
488                 "Initialize."
489                 #print('Radio->getFromRadio:', latentStringVar, name, repository, value )
490                 self.name = name
491                 self.value = value
492                 repository.preferences.append(self)
493                 return self
494
495 class RadioCapitalized( Radio ):
496         "A class to display, read & write a boolean with associated radio button."
497
498 class RadioCapitalizedButton( Radio ):
499         "A class to display, read & write a boolean with associated radio button. With an added configuration dialog button"
500         "Only used for the extra export options, which we are not using, so ignore the path for now"
501         def getFromPath( self, latentStringVar, name, path, repository, value ):
502                 "Initialize."
503                 #print('RadioCapitalizedButton->getFromPath:', latentStringVar, name, path, repository, value )
504                 self.name = name
505                 self.value = value
506                 repository.preferences.append(self)
507                 return self
508                 
509 class FileNameInput(StringSetting ):
510         "A class to display, read & write a fileName."
511         def getFromFileName( self, fileTypes, name, repository, value ):
512                 #print('FileNameInput:getFromFileName:', self, fileTypes, name, repository, value )
513                 self.name = name
514                 self.value = value
515                 return self
516
517 class HelpPage:
518     "A class to open a help page."
519     def getOpenFromAbsolute( self, hypertextAddress ):
520         return self
521
522 class MenuButtonDisplay:
523         "A class to add a combo box selection."
524         def getFromName( self, name, repository ):
525                 #print('MenuButtonDisplay->getFromName:', name, repository )
526                 self.name = name
527                 self.value = "ERROR"
528                 self.radioList = []
529                 repository.preferences.append(self)
530                 return self
531         
532         def addRadio(self, radio, default):
533                 if default:
534                         self.value = radio.name
535                 self.radioList.append(radio)
536         
537         def setValueToString(self, value):
538                 valueFound = False
539                 for radio in self.radioList:
540                         if radio.name == value:
541                                 valueFound = True;
542                 if valueFound:
543                         self.value = value
544                         for radio in self.radioList:
545                                 radio.value = (radio.name == value)
546
547 class MenuRadio( BooleanSetting ):
548         "A class to display, read & write a boolean with associated combo box selection."
549         def getFromMenuButtonDisplay( self, menuButtonDisplay, name, repository, value ):
550                 "Initialize."
551                 #print('MenuRadio->getFromMenuButtonDisplay:', menuButtonDisplay, name, repository, value )
552                 self.name = name
553                 self.value = value
554                 menuButtonDisplay.addRadio(self, value)
555                 return self
556
557 class LabelDisplay:
558         "A class to add a label."
559         def getFromName( self, name, repository ):
560                 "Initialize."
561                 return self
562
563 class FloatSetting(GeneralSetting):
564         "A class to display, read & write a float."
565         def setValueToString(self, value):
566                 self.value = float(value)
567
568 class FloatSpin( FloatSetting ):
569         "A class to display, read & write an float in a spin box."
570         def getFromValue(self, from_, name, repository, to, value):
571                 "Initialize."
572                 self.name = name
573                 self.value = value
574                 if repository != None:
575                         repository.preferences.append(self)
576                 return self
577
578 class LabelSeparator:
579         "A class to add a label and menu separator."
580         def getFromRepository( self, repository ):
581                 "Initialize."
582                 return self
583
584 class IntSpin(FloatSpin):
585         "A class to display, read & write an int in a spin box."
586         def getSingleIncrementFromValue( self, from_, name, repository, to, value ):
587                 "Initialize."
588                 self.name = name
589                 self.value = value
590                 repository.preferences.append(self)
591                 return self
592
593         def setValueToString(self, value):
594                 self.value = int(value)
595
596 ##########################
597 # Helper classes
598 ##########################
599
600 class LayerCount:
601         'A class to handle the layerIndex.'
602         def __init__(self):
603                 'Initialize.'
604                 self.layerIndex = -1
605
606         def __repr__(self):
607                 'Get the string representation of this LayerCount.'
608                 return str(self.layerIndex)
609
610         def printProgressIncrement(self, procedureName):
611                 'Print progress then increment layerIndex.'
612                 self.layerIndex += 1
613                 printProgress(self.layerIndex, procedureName)
614