Commit c9cf01f5 authored by sumpfralle's avatar sumpfralle

implemented loading and saving of the new settings


git-svn-id: https://pycam.svn.sourceforge.net/svnroot/pycam/trunk@274 bbaffbd6-741e-11dd-a85d-61de82d9cad9
parent 8a7c529b
...@@ -381,13 +381,14 @@ class ProjectGui: ...@@ -381,13 +381,14 @@ class ProjectGui:
self.gui.add_from_file(gtk_build_file) self.gui.add_from_file(gtk_build_file)
self.window = self.gui.get_object("ProjectWindow") self.window = self.gui.get_object("ProjectWindow")
# file loading # file loading
self.last_config_file = None self.last_settings_file = None
self.last_model_file = None self.last_model_file = None
self.last_toolpath_file = None self.last_toolpath_file = None
# define callbacks and accelerator keys for the menu actions # define callbacks and accelerator keys for the menu actions
for objname, callback, data, accel_key in ( for objname, callback, data, accel_key in (
("LoadProcessingTemplates", self.load_processing_file, None, "<Control>t"), ("LoadSettings", self.load_settings_file, None, "<Control>t"),
("SaveProcessingTemplates", self.save_processing_settings_file, lambda: self.last_config_file, None), ("SaveSettings", self.save_settings_file, lambda: self.last_settings_file, None),
("SaveAsSettings", self.save_settings_file, None, None),
("LoadModel", self.load_model_file, None, "<Control>l"), ("LoadModel", self.load_model_file, None, "<Control>l"),
("SaveModel", self.save_model, lambda: self.last_model_file, "<Control>s"), ("SaveModel", self.save_model, lambda: self.last_model_file, "<Control>s"),
("SaveAsModel", self.save_model, None, "<Control><Shift>s"), ("SaveAsModel", self.save_model, None, "<Control><Shift>s"),
...@@ -426,7 +427,7 @@ class ProjectGui: ...@@ -426,7 +427,7 @@ class ProjectGui:
self.toolpath = GuiCommon.ToolPathList() self.toolpath = GuiCommon.ToolPathList()
self._physics_cache = None self._physics_cache = None
self.cutter = None self.cutter = None
self.process_settings_list = [] self.process_list = []
self.tool_list = [] self.tool_list = []
self.task_list = [] self.task_list = []
# add some dummies - to be implemented later ... # add some dummies - to be implemented later ...
...@@ -548,11 +549,7 @@ class ProjectGui: ...@@ -548,11 +549,7 @@ class ProjectGui:
"MaterialAllowanceControl", "MaxStepDownControl"): "MaterialAllowanceControl", "MaxStepDownControl"):
self.gui.get_object(objname).connect("changed", self.handle_process_settings_change) self.gui.get_object(objname).connect("changed", self.handle_process_settings_change)
self.gui.get_object("ProcessSettingName").connect("changed", self.handle_process_settings_change) self.gui.get_object("ProcessSettingName").connect("changed", self.handle_process_settings_change)
# load a processing configuration object # the process manager
default_settings = pycam.Gui.Settings.SettingsManager()
self.tool_list.extend(default_settings.get_tools())
self.process_settings_list.extend(default_settings.get_processes())
self.task_list.extend(default_settings.get_tasks())
self.process_table = self.gui.get_object("ProcessListTable") self.process_table = self.gui.get_object("ProcessListTable")
self.process_editor_table = self.gui.get_object("ProcessEditorWindowTable") self.process_editor_table = self.gui.get_object("ProcessEditorWindowTable")
self.process_editor_table.get_selection().connect("changed", self.switch_process_table_selection) self.process_editor_table.get_selection().connect("changed", self.switch_process_table_selection)
...@@ -628,6 +625,7 @@ class ProjectGui: ...@@ -628,6 +625,7 @@ class ProjectGui:
window_box.pack_start(self.menubar, False) window_box.pack_start(self.menubar, False)
window_box.reorder_child(self.menubar, 0) window_box.reorder_child(self.menubar, 0)
# some more initialization # some more initialization
self.load_settings()
self.update_toolpath_table() self.update_toolpath_table()
self.update_tool_table() self.update_tool_table()
self.update_tool_controls() self.update_tool_controls()
...@@ -635,7 +633,6 @@ class ProjectGui: ...@@ -635,7 +633,6 @@ class ProjectGui:
self.update_process_table() self.update_process_table()
self.update_tasklist_table() self.update_tasklist_table()
self.update_tasklist_controls() self.update_tasklist_controls()
self.load_processing_settings()
self.update_save_actions() self.update_save_actions()
self.update_unit_labels() self.update_unit_labels()
if not self.no_dialog: if not self.no_dialog:
...@@ -683,7 +680,7 @@ class ProjectGui: ...@@ -683,7 +680,7 @@ class ProjectGui:
return self._physics_cache return self._physics_cache
def update_save_actions(self): def update_save_actions(self):
self.gui.get_object("SaveProcessingTemplates").set_sensitive(not self.last_config_file is None) self.gui.get_object("SaveSettings").set_sensitive(not self.last_settings_file is None)
self.gui.get_object("SaveModel").set_sensitive(not self.last_model_file is None) self.gui.get_object("SaveModel").set_sensitive(not self.last_model_file is None)
def update_tasklist_controls(self, widget=None, data=None): def update_tasklist_controls(self, widget=None, data=None):
...@@ -706,7 +703,7 @@ class ProjectGui: ...@@ -706,7 +703,7 @@ class ProjectGui:
# update the task description # update the task description
lines = [] lines = []
task_index = self._treeview_get_active_index(self.tasklist_table, self.task_list) task_index = self._treeview_get_active_index(self.tasklist_table, self.task_list)
if not task_index is None: if (not task_index is None) and (task_index < len(self.task_list)):
task = self.task_list[task_index] task = self.task_list[task_index]
tool = task["tool"] tool = task["tool"]
process = task["process"] process = task["process"]
...@@ -737,7 +734,7 @@ class ProjectGui: ...@@ -737,7 +734,7 @@ class ProjectGui:
tasklist_model.clear() tasklist_model.clear()
# remove broken tasks from the list (tool or process was deleted) # remove broken tasks from the list (tool or process was deleted)
self.task_list = [task for task in self.task_list self.task_list = [task for task in self.task_list
if (task["tool"] in self.tool_list) and (task["process"] in self.process_settings_list)] if (task["tool"] in self.tool_list) and (task["process"] in self.process_list)]
counter = 0 counter = 0
for task in self.task_list: for task in self.task_list:
tasklist_model.append((counter, task["tool"]["name"], task["process"]["name"], task["enabled"])) tasklist_model.append((counter, task["tool"]["name"], task["process"]["name"], task["enabled"]))
...@@ -759,10 +756,10 @@ class ProjectGui: ...@@ -759,10 +756,10 @@ class ProjectGui:
self._treeview_button_event(self.tasklist_table, self.task_list, action, self.update_tasklist_table) self._treeview_button_event(self.tasklist_table, self.task_list, action, self.update_tasklist_table)
if action == "add": if action == "add":
tool_index = self._treeview_get_active_index(self.tool_table, self.tool_list) tool_index = self._treeview_get_active_index(self.tool_table, self.tool_list)
process_index = self._treeview_get_active_index(self.process_table, self.process_settings_list) process_index = self._treeview_get_active_index(self.process_table, self.process_list)
new_task = {} new_task = {}
new_task["tool"] = self.tool_list[tool_index] new_task["tool"] = self.tool_list[tool_index]
new_task["process"] = self.process_settings_list[process_index] new_task["process"] = self.process_list[process_index]
new_task["enabled"] = True new_task["enabled"] = True
self.task_list.append(new_task) self.task_list.append(new_task)
self.update_tasklist_table(self.task_list.index(new_task)) self.update_tasklist_table(self.task_list.index(new_task))
...@@ -881,7 +878,7 @@ class ProjectGui: ...@@ -881,7 +878,7 @@ class ProjectGui:
if state is None: if state is None:
state = event state = event
if state: if state:
process_index = self._treeview_get_active_index(self.process_table, self.process_settings_list) process_index = self._treeview_get_active_index(self.process_table, self.process_list)
if not process_index is None: if not process_index is None:
self._treeview_set_active_index(self.process_editor_table, process_index) self._treeview_set_active_index(self.process_editor_table, process_index)
self.gui.get_object("ProcessEditorWindow").show() self.gui.get_object("ProcessEditorWindow").show()
...@@ -1223,24 +1220,24 @@ class ProjectGui: ...@@ -1223,24 +1220,24 @@ class ProjectGui:
if filename: if filename:
self.load_model(pycam.Importers.STLImporter.ImportModel(filename)) self.load_model(pycam.Importers.STLImporter.ImportModel(filename))
def open_processing_settings_file(self, filename): def open_settings_file(self, filename):
""" This function is used by the commandline handler """ """ This function is used by the commandline handler """
self.last_config_file = filename self.last_settings_file = filename
self.load_processing_file(filename=filename) self.load_settings_file(filename=filename)
self.update_save_actions() self.update_save_actions()
@gui_activity_guard @gui_activity_guard
def load_processing_file(self, widget=None, filename=None): def load_settings_file(self, widget=None, filename=None):
if callable(filename): if callable(filename):
filename = filename() filename = filename()
if not filename: if not filename:
filename = self.get_filename_via_dialog("Loading processing settings ...", filename = self.get_filename_via_dialog("Loading settings ...",
mode_load=True, type_filter=FILTER_CONFIG) mode_load=True, type_filter=FILTER_CONFIG)
if filename: if filename:
self.last_config_file = filename self.last_settings_file = filename
self.update_save_actions() self.update_save_actions()
if filename: if filename:
self.load_processing_settings(filename) self.load_settings(filename)
def load_model(self, model): def load_model(self, model):
# load the new model only if the import worked # load the new model only if the import worked
...@@ -1253,42 +1250,16 @@ class ProjectGui: ...@@ -1253,42 +1250,16 @@ class ProjectGui:
self.append_to_queue(self.toggle_3d_view, value=True) self.append_to_queue(self.toggle_3d_view, value=True)
self.append_to_queue(self.update_view) self.append_to_queue(self.update_view)
def load_processing_settings(self, filename=None): def load_settings(self, filename=None):
settings = pycam.Gui.Settings.SettingsFileManager()
if not filename is None: if not filename is None:
self.processing_settings.reset("") settings.load_file(filename)
self.processing_settings.load_file(filename) self.tool_list = settings.get_tools()
# load the default config self.process_list = settings.get_processes()
self.processing_settings.enable_config() self.task_list = settings.get_tasks()
# reset the combobox self.update_tool_table()
#self.processing_config_selection.get_model().clear() self.update_process_table()
#for config_name in self.processing_settings.get_config_list(): self.update_tasklist_table()
# self.processing_config_selection.append_text(config_name)
def delete_processing_config(self, widget=None, section=None):
if callable(section):
section = section()
if section is None:
return
if section in self.processing_settings.get_config_list():
self.processing_settings.delete_config(section)
self.load_processing_settings()
self._visually_enable_specific_processing_config("")
def save_processing_config(self, widget=None, section=None):
if callable(section):
section = section()
if section is None:
return
self.processing_settings.store_config(section)
self.load_processing_settings()
self._visually_enable_specific_processing_config(section)
def _visually_enable_specific_processing_config(self, section):
# select the requested section in the drop-down list
# don't change the setting if not required - otherwise we will loop
current_text = self.processing_config_selection.get_child().get_text()
if section != current_text:
self.processing_config_selection.get_child().set_text(section)
def _load_process_settings_from_gui(self, settings=None): def _load_process_settings_from_gui(self, settings=None):
if settings is None: if settings is None:
...@@ -1342,23 +1313,23 @@ class ProjectGui: ...@@ -1342,23 +1313,23 @@ class ProjectGui:
@gui_activity_guard @gui_activity_guard
def handle_process_settings_change(self, widget=None, data=None): def handle_process_settings_change(self, widget=None, data=None):
current_index = self._treeview_get_active_index(self.process_editor_table, self.process_settings_list) current_index = self._treeview_get_active_index(self.process_editor_table, self.process_list)
if not current_index is None: if not current_index is None:
self._load_process_settings_from_gui(self.process_settings_list[current_index]) self._load_process_settings_from_gui(self.process_list[current_index])
self.update_process_table() self.update_process_table()
def update_process_table(self, new_index=None, skip_model_update=False): def update_process_table(self, new_index=None, skip_model_update=False):
# reset the model data and the selection # reset the model data and the selection
if new_index is None: if new_index is None:
# keep the old selection - this may return "None" if nothing is selected # keep the old selection - this may return "None" if nothing is selected
new_index = self._treeview_get_active_index(self.process_editor_table, self.process_settings_list) new_index = self._treeview_get_active_index(self.process_editor_table, self.process_list)
if not skip_model_update: if not skip_model_update:
# update the TreeModel data # update the TreeModel data
model = self.gui.get_object("ProcessList") model = self.gui.get_object("ProcessList")
model.clear() model.clear()
# columns: index, description # columns: index, description
for index in range(len(self.process_settings_list)): for index in range(len(self.process_list)):
process = self.process_settings_list[index] process = self.process_list[index]
items = (index, process["name"]) items = (index, process["name"])
model.append(items) model.append(items)
if not new_index is None: if not new_index is None:
...@@ -1366,7 +1337,7 @@ class ProjectGui: ...@@ -1366,7 +1337,7 @@ class ProjectGui:
# enable/disable the modification buttons # enable/disable the modification buttons
self.gui.get_object("ProcessListMoveUp").set_sensitive((not new_index is None) and (new_index > 0)) self.gui.get_object("ProcessListMoveUp").set_sensitive((not new_index is None) and (new_index > 0))
self.gui.get_object("ProcessListDelete").set_sensitive(not new_index is None) self.gui.get_object("ProcessListDelete").set_sensitive(not new_index is None)
self.gui.get_object("ProcessListMoveDown").set_sensitive((not new_index is None) and (new_index + 1 < len(self.process_settings_list))) self.gui.get_object("ProcessListMoveDown").set_sensitive((not new_index is None) and (new_index + 1 < len(self.process_list)))
# hide all controls if no process is defined # hide all controls if no process is defined
if new_index is None: if new_index is None:
self.gui.get_object("ProcessSettingsControlsBox").hide() self.gui.get_object("ProcessSettingsControlsBox").hide()
...@@ -1377,10 +1348,10 @@ class ProjectGui: ...@@ -1377,10 +1348,10 @@ class ProjectGui:
@gui_activity_guard @gui_activity_guard
def switch_process_table_selection(self, widget=None, data=None): def switch_process_table_selection(self, widget=None, data=None):
new_index = self._treeview_get_active_index(self.process_editor_table, self.process_settings_list) new_index = self._treeview_get_active_index(self.process_editor_table, self.process_list)
if not new_index is None: if not new_index is None:
self.gui.get_object("ProcessSettingsControlsBox").show() self.gui.get_object("ProcessSettingsControlsBox").show()
self._put_process_settings_to_gui(self.process_settings_list[new_index]) self._put_process_settings_to_gui(self.process_list[new_index])
self.update_process_table() self.update_process_table()
else: else:
self.gui.get_object("ProcessSettingsControlsBox").hide() self.gui.get_object("ProcessSettingsControlsBox").hide()
...@@ -1390,19 +1361,19 @@ class ProjectGui: ...@@ -1390,19 +1361,19 @@ class ProjectGui:
# "toggle" uses two parameters - all other actions have only one # "toggle" uses two parameters - all other actions have only one
if action is None: if action is None:
action = data action = data
self._treeview_button_event(self.process_editor_table, self.process_settings_list, action, self.update_process_table) self._treeview_button_event(self.process_editor_table, self.process_list, action, self.update_process_table)
# do some post-processing ... # do some post-processing ...
if action == "add": if action == "add":
# look for the first unused default name # look for the first unused default name
prefix = "New Process " prefix = "New Process "
index = 1 index = 1
# loop while the current name is in use # loop while the current name is in use
while [True for process in self.process_settings_list if process["name"] == "%s%d" % (prefix, index)]: while [True for process in self.process_list if process["name"] == "%s%d" % (prefix, index)]:
index += 1 index += 1
new_settings = self._load_process_settings_from_gui() new_settings = self._load_process_settings_from_gui()
new_settings["name"] = "%s%d" % (prefix, index) new_settings["name"] = "%s%d" % (prefix, index)
self.process_settings_list.append(new_settings) self.process_list.append(new_settings)
self.update_process_table(self.process_settings_list.index(new_settings)) self.update_process_table(self.process_list.index(new_settings))
self._put_process_settings_to_gui(new_settings) self._put_process_settings_to_gui(new_settings)
@gui_activity_guard @gui_activity_guard
...@@ -1458,7 +1429,7 @@ class ProjectGui: ...@@ -1458,7 +1429,7 @@ class ProjectGui:
self.gui.get_object("toolpath_down").set_sensitive((not new_index is None) and (new_index + 1 < len(self.toolpath))) self.gui.get_object("toolpath_down").set_sensitive((not new_index is None) and (new_index + 1 < len(self.toolpath)))
@gui_activity_guard @gui_activity_guard
def save_processing_settings_file(self, widget=None, filename=None): def save_settings_file(self, widget=None, filename=None):
no_dialog = False no_dialog = False
if callable(filename): if callable(filename):
filename = filename() filename = filename()
...@@ -1466,16 +1437,17 @@ class ProjectGui: ...@@ -1466,16 +1437,17 @@ class ProjectGui:
no_dialog = True no_dialog = True
else: else:
# we open a dialog # we open a dialog
filename = self.get_filename_via_dialog("Save processing settings to ...", filename = self.get_filename_via_dialog("Save settings to ...",
mode_load=False, type_filter=FILTER_CONFIG) mode_load=False, type_filter=FILTER_CONFIG)
if filename: if filename:
self.last_config_file = filename self.last_settings_file = filename
self.update_save_actions() self.update_save_actions()
# no filename given -> exit # no filename given -> exit
if not filename: if not filename:
return return
if not self.processing_settings.write_to_file(filename) and not no_dialog: settings = pycam.Gui.Settings.SettingsFileManager()
show_error_dialog(self.window, "Failed to save processing settings file") if not settings.write_to_file(filename, self.tool_list, self.process_list, self.task_list) and not no_dialog:
show_error_dialog(self.window, "Failed to save settings file")
def get_tool_instance(self, tool_settings): def get_tool_instance(self, tool_settings):
cutter_height = self.settings.get("maxz") - self.settings.get("minz") cutter_height = self.settings.get("maxz") - self.settings.get("minz")
......
...@@ -54,7 +54,7 @@ class Settings: ...@@ -54,7 +54,7 @@ class Settings:
return str(result) return str(result)
class SettingsManager: class SettingsFileManager:
DEFAULT_CONFIG = """ DEFAULT_CONFIG = """
[ToolDefault] [ToolDefault]
...@@ -81,7 +81,6 @@ torus_radius: 0.2 ...@@ -81,7 +81,6 @@ torus_radius: 0.2
[ProcessDefault] [ProcessDefault]
path_direction: x path_direction: x
safety_height: 5 safety_height: 5
step_down: 1
[Process0] [Process0]
name: Rough name: Rough
...@@ -104,6 +103,7 @@ name: Finish ...@@ -104,6 +103,7 @@ name: Finish
path_generator: DropCutter path_generator: DropCutter
path_postprocessor: ZigZagCutter path_postprocessor: ZigZagCutter
material_allowance: 0.0 material_allowance: 0.0
step_down: 1.0
overlap: 60 overlap: 60
[TaskDefault] [TaskDefault]
...@@ -134,7 +134,7 @@ process: 2 ...@@ -134,7 +134,7 @@ process: 2
"path_postprocessor": str, "path_postprocessor": str,
"safety_height": float, "safety_height": float,
"material_allowance": float, "material_allowance": float,
"overlap": float, "overlap": int,
"step_down": float, "step_down": float,
"tool": object, "tool": object,
"process": object, "process": object,
...@@ -160,6 +160,8 @@ process: 2 ...@@ -160,6 +160,8 @@ process: 2
"task": "Task", "task": "Task",
} }
DEFAULT_SUFFIX = "Default"
def __init__(self): def __init__(self):
self.config = None self.config = None
self._cache = {} self._cache = {}
...@@ -191,10 +193,11 @@ process: 2 ...@@ -191,10 +193,11 @@ process: 2
return False return False
return True return True
def write_to_file(self, filename): def write_to_file(self, filename, tools=None, processes=None, tasks=None):
text = self.get_config_text(tools, processes, tasks)
try: try:
fi = open(filename, "w") fi = open(filename, "w")
self.config.write(fi) fi.write(text)
fi.close() fi.close()
except IOError, err_msg: except IOError, err_msg:
print >> sys.stderr, "Failed to write configuration to file (%s): %s" % (filename, err_msg) print >> sys.stderr, "Failed to write configuration to file (%s): %s" % (filename, err_msg)
...@@ -224,7 +227,7 @@ process: 2 ...@@ -224,7 +227,7 @@ process: 2
value_raw = self.config.get(current_section_name, key) value_raw = self.config.get(current_section_name, key)
except ConfigParser.NoOptionError: except ConfigParser.NoOptionError:
try: try:
value_raw = self.config.get(prefix + "Default", key) value_raw = self.config.get(prefix + self.DEFAULT_SUFFIX, key)
except ConfigParser.NoOptionError: except ConfigParser.NoOptionError:
value_raw = None value_raw = None
if not value_raw is None: if not value_raw is None:
...@@ -245,3 +248,70 @@ process: 2 ...@@ -245,3 +248,70 @@ process: 2
self._cache[type_name] = item_list self._cache[type_name] = item_list
return self._cache[type_name][:] return self._cache[type_name][:]
def _value_to_string(self, lists, key, value):
value_type = self.SETTING_TYPES[key]
if value_type == bool:
if value:
return "1"
else:
return "0"
elif value_type == object:
try:
return lists[key].index(value)
except IndexError:
return None
else:
return str(value)
def get_config_text(self, tools=None, processes=None, tasks=None):
result = []
if tools is None:
tools = []
if processes is None:
processes = []
if tasks is None:
tasks = []
lists = {}
lists["tool"] = tools
lists["process"] = processes
lists["task"] = tasks
for type_name in lists.keys():
type_list = lists[type_name]
# generate "Default" section
common_keys = []
for key in self.CATEGORY_KEYS[type_name]:
try:
values = [item[key] for item in type_list]
except KeyError, err_msg:
values = None
# check if there are values and if they all have the same value
if values and (values.count(values[0]) == len(values)):
common_keys.append(key)
if common_keys:
section = "[%s%s]" % (self.SECTION_PREFIXES[type_name], self.DEFAULT_SUFFIX)
result.append(section)
for key in common_keys:
value = type_list[0][key]
value_string = self._value_to_string(lists, key, value)
if not value_string is None:
result.append("%s: %s" % (key, value_string))
# add an empty line to separate sections
result.append("")
# generate individual sections
for index in range(len(type_list)):
section = "[%s%d]" % (self.SECTION_PREFIXES[type_name], index)
result.append(section)
item = type_list[index]
for key in self.CATEGORY_KEYS[type_name]:
if key in common_keys:
# skip keys, that are listed in the "Default" section
continue
if item.has_key(key):
value = item[key]
value_string = self._value_to_string(lists, key, value)
if not value_string is None:
result.append("%s: %s" % (key, value_string))
# add an empty line to separate sections
result.append("")
return os.linesep.join(result)
...@@ -10,9 +10,9 @@ ...@@ -10,9 +10,9 @@
<menuitem action="Quit"/> <menuitem action="Quit"/>
</menu> </menu>
<menu action="SettingsMenu"> <menu action="SettingsMenu">
<menuitem action="LoadProcessingTemplates"/> <menuitem action="LoadSettings"/>
<menuitem action="SaveProcessingTemplates"/> <menuitem action="SaveSettings"/>
<menuitem action="SaveAsProcessingTemplates"/> <menuitem action="SaveAsSettings"/>
<separator /> <separator />
<menuitem action="GeneralSettings"/> <menuitem action="GeneralSettings"/>
</menu> </menu>
......
...@@ -2068,18 +2068,18 @@ This combination is added to the above task list.</property> ...@@ -2068,18 +2068,18 @@ This combination is added to the above task list.</property>
<property name="tooltip">Write all current toolpaths to a file.</property> <property name="tooltip">Write all current toolpaths to a file.</property>
<property name="stock_id">gtk-execute</property> <property name="stock_id">gtk-execute</property>
</object> </object>
<object class="GtkAction" id="LoadProcessingTemplates"> <object class="GtkAction" id="LoadSettings">
<property name="label">_Load Processing Settings</property> <property name="label">_Load Settings</property>
<property name="tooltip">Loads a set of processing templates from a file.</property> <property name="tooltip">Loads a set of processing templates from a file.</property>
<property name="stock_id">gtk-open</property> <property name="stock_id">gtk-open</property>
</object> </object>
<object class="GtkAction" id="SaveProcessingTemplates"> <object class="GtkAction" id="SaveSettings">
<property name="label">_Save Processing Settings</property> <property name="label">_Save Settings</property>
<property name="tooltip">Save the currently visible set of processing templates to a file.</property> <property name="tooltip">Save the currently visible set of processing templates to a file.</property>
<property name="stock_id">gtk-save</property> <property name="stock_id">gtk-save</property>
</object> </object>
<object class="GtkAction" id="SaveAsProcessingTemplates"> <object class="GtkAction" id="SaveAsSettings">
<property name="label">Save Processing Settings _as ...</property> <property name="label">Save Settings _as ...</property>
<property name="tooltip">Save the currently visible set of processing templates to a new file.</property> <property name="tooltip">Save the currently visible set of processing templates to a new file.</property>
<property name="stock_id">gtk-save-as</property> <property name="stock_id">gtk-save-as</property>
</object> </object>
...@@ -3739,6 +3739,8 @@ You should have received a copy of the GNU General Public License along with thi ...@@ -3739,6 +3739,8 @@ You should have received a copy of the GNU General Public License along with thi
<object class="GtkSpinButton" id="OverlapPercentControl"> <object class="GtkSpinButton" id="OverlapPercentControl">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="tooltip_text" translatable="yes">The distance between two neighbouring drill positions is based on the overlap value.
Use high values for fine-grained toolpaths.</property>
<property name="invisible_char">&#x2022;</property> <property name="invisible_char">&#x2022;</property>
<property name="adjustment">OverlapPercentValue</property> <property name="adjustment">OverlapPercentValue</property>
<property name="numeric">True</property> <property name="numeric">True</property>
...@@ -3769,6 +3771,11 @@ You should have received a copy of the GNU General Public License along with thi ...@@ -3769,6 +3771,11 @@ You should have received a copy of the GNU General Public License along with thi
<object class="GtkSpinButton" id="MaterialAllowanceControl"> <object class="GtkSpinButton" id="MaterialAllowanceControl">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="tooltip_text" translatable="yes">Material allowance determines the minimum distance that should be preserved between the tool and the model.
This value should be greater than zero for the first roughing operation.
The last finishing operation should have zero material allowance.
ODE is required for this setting.</property>
<property name="invisible_char">&#x2022;</property> <property name="invisible_char">&#x2022;</property>
<property name="adjustment">MaterialAllowanceValue</property> <property name="adjustment">MaterialAllowanceValue</property>
<property name="digits">2</property> <property name="digits">2</property>
...@@ -3787,6 +3794,7 @@ You should have received a copy of the GNU General Public License along with thi ...@@ -3787,6 +3794,7 @@ You should have received a copy of the GNU General Public License along with thi
<object class="GtkSpinButton" id="MaxStepDownControl"> <object class="GtkSpinButton" id="MaxStepDownControl">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="tooltip_text" translatable="yes">This value determines the maximum height of each PushCutter slice.</property>
<property name="invisible_char">&#x2022;</property> <property name="invisible_char">&#x2022;</property>
<property name="adjustment">MaxStepDownValue</property> <property name="adjustment">MaxStepDownValue</property>
<property name="digits">2</property> <property name="digits">2</property>
...@@ -3829,6 +3837,7 @@ You should have received a copy of the GNU General Public License along with thi ...@@ -3829,6 +3837,7 @@ You should have received a copy of the GNU General Public License along with thi
<object class="GtkSpinButton" id="SafetyHeightControl"> <object class="GtkSpinButton" id="SafetyHeightControl">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="tooltip_text" translatable="yes">The drill will return between lines and slices to the safe height.</property>
<property name="invisible_char">&#x2022;</property> <property name="invisible_char">&#x2022;</property>
<property name="adjustment">SafetyHeightValue</property> <property name="adjustment">SafetyHeightValue</property>
<property name="digits">1</property> <property name="digits">1</property>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment