Commit 90b37076 authored by sumpfralle's avatar sumpfralle

improved xml state handling


git-svn-id: https://pycam.svn.sourceforge.net/svnroot/pycam/trunk@1199 bbaffbd6-741e-11dd-a85d-61de82d9cad9
parent 262eaa26
...@@ -46,6 +46,7 @@ import pycam.Utils ...@@ -46,6 +46,7 @@ import pycam.Utils
import pycam.Plugins import pycam.Plugins
from pycam import VERSION from pycam import VERSION
import pycam.Physics.ode_physics import pycam.Physics.ode_physics
import pycam.Utils.xml_handling
GTKBUILD_FILE = "pycam-project.ui" GTKBUILD_FILE = "pycam-project.ui"
GTKMENU_FILE = "menubar.xml" GTKMENU_FILE = "menubar.xml"
...@@ -151,7 +152,7 @@ class EventCore(pycam.Gui.Settings.Settings): ...@@ -151,7 +152,7 @@ class EventCore(pycam.Gui.Settings.Settings):
self.event_handlers = {} self.event_handlers = {}
self.ui_sections = {} self.ui_sections = {}
self.chains = {} self.chains = {}
self.xml_dumps = [] self.state_dumps = []
def register_event(self, event, func, *args): def register_event(self, event, func, *args):
if not event in self.event_handlers: if not event in self.event_handlers:
...@@ -300,6 +301,26 @@ class EventCore(pycam.Gui.Settings.Settings): ...@@ -300,6 +301,26 @@ class EventCore(pycam.Gui.Settings.Settings):
else: else:
log.debug("Called an unknown chain: %s" % name) log.debug("Called an unknown chain: %s" % name)
def dump_state(self):
result = []
self.call_chain("state_dump", result)
root = ET.Element("pycam")
for match, element in result:
parent = root
if match:
chain = match.split("/")
for component in chain:
if parent.find(component):
parent = parent.find(component)
else:
item = ET.SubElement(parent, component)
parent = item
parent.append(element)
return os.linesep.join(pycam.Utils.xml_handling.get_xml_lines(parent))
def reset_state(self):
pass
class ProjectGui(object): class ProjectGui(object):
...@@ -398,22 +419,6 @@ class ProjectGui(object): ...@@ -398,22 +419,6 @@ class ProjectGui(object):
self._store_undo_state) self._store_undo_state)
self.settings.register_event("model-change-after", self.settings.register_event("model-change-after",
lambda: self.settings.emit_event("visual-item-updated")) lambda: self.settings.emit_event("visual-item-updated"))
def dump_xml():
result = []
self.settings.call_chain("xml_dump", result)
root = ET.Element("pycam")
for match, element in result:
parent = root
if match:
found = root.findall(match)
if found:
parent = found[0]
else:
log.debug("Failed to find XML parent: %s" % str(match))
parent.append(element)
# for DEBUGGING
#print ET.tostring(parent)
self.settings.register_event("visual-item-updated", dump_xml)
# set the availability of ODE # set the availability of ODE
self.enable_ode_control = self.gui.get_object("SettingEnableODE") self.enable_ode_control = self.gui.get_object("SettingEnableODE")
self.settings.add_item("enable_ode", self.enable_ode_control.get_active, self.settings.add_item("enable_ode", self.enable_ode_control.get_active,
...@@ -988,14 +993,15 @@ class ProjectGui(object): ...@@ -988,14 +993,15 @@ class ProjectGui(object):
# no filename given -> exit # no filename given -> exit
if not filename: if not filename:
return return
settings = pycam.Gui.Settings.ProcessSettings() settings = self.settings.dump_state()
if not settings.write_to_file(filename, self.settings.get("tools"), try:
self.settings.get("processes"), self.settings.get("bounds"), out_file = open(filename, "w")
self.settings.get("tasks")): out_file.write(settings)
log.error("Failed to save settings file") out_file.close()
else:
log.info("Task settings written to %s" % filename) log.info("Task settings written to %s" % filename)
self.add_to_recent_file_list(filename) self.add_to_recent_file_list(filename)
except IOError:
log.error("Failed to save settings file")
def add_to_recent_file_list(self, filename): def add_to_recent_file_list(self, filename):
# Add the item to the recent files list - if it already exists. # Add the item to the recent files list - if it already exists.
......
...@@ -145,13 +145,13 @@ class Bounds(pycam.Plugins.ListPluginBase): ...@@ -145,13 +145,13 @@ class Bounds(pycam.Plugins.ListPluginBase):
self._switch_bounds() self._switch_bounds()
self._update_model_list() self._update_model_list()
self._event_handlers.append(("bounds-changed", "visual-item-updated")) self._event_handlers.append(("bounds-changed", "visual-item-updated"))
self.core.register_chain("xml_dump", self.dump_xml) self.core.register_chain("state_dump", self.dump_state)
self.register_event_handlers(self._event_handlers) self.register_event_handlers(self._event_handlers)
return True return True
def teardown(self): def teardown(self):
if self.gui: if self.gui:
self.core.unregister_chain("xml_dump", self.dump_xml) self.core.unregister_chain("state_dump", self.dump_state)
self.core.unregister_ui("main", self.gui.get_object("BoundsBox")) self.core.unregister_ui("main", self.gui.get_object("BoundsBox"))
self.unregister_gtk_handlers(self._gtk_handlers) self.unregister_gtk_handlers(self._gtk_handlers)
self.unregister_event_handlers(self._event_handlers) self.unregister_event_handlers(self._event_handlers)
...@@ -390,10 +390,10 @@ class Bounds(pycam.Plugins.ListPluginBase): ...@@ -390,10 +390,10 @@ class Bounds(pycam.Plugins.ListPluginBase):
new_text: new_text:
self._treemodel[path][self.COLUMN_NAME] = new_text self._treemodel[path][self.COLUMN_NAME] = new_text
def dump_xml(self, result): def dump_state(self, result):
root = ET.Element("bounds-list") root = ET.Element("bounds-list")
for bounds in self: for bounds in self:
root.append(bounds.dump_xml()) root.append(bounds.get_xml())
result.append((None, root)) result.append((None, root))
...@@ -466,19 +466,3 @@ class BoundsDict(pycam.Plugins.ObjectWithAttributes): ...@@ -466,19 +466,3 @@ class BoundsDict(pycam.Plugins.ObjectWithAttributes):
high[index] += offset high[index] += offset
return low, high return low, high
def dump_xml(self, name):
leaf = ET.Element("bounds")
leaf.set("name", repr(name))
parameters = ET.SubElement(leaf, "parameters")
for key in self:
if "Models" == key:
models = self["Models"]
if len(models) > 0:
models_leaf = ET.SubElement(parameters, "Models")
for model in models:
name = self.core.get("models").get_attr(model, "name")
ET.SubElement(models_leaf, "model", text=name)
else:
parameters.set(key, repr(self[key]))
return leaf
...@@ -20,6 +20,7 @@ You should have received a copy of the GNU General Public License ...@@ -20,6 +20,7 @@ You should have received a copy of the GNU General Public License
along with PyCAM. If not, see <http://www.gnu.org/licenses/>. along with PyCAM. If not, see <http://www.gnu.org/licenses/>.
""" """
import xml.etree.ElementTree as ET
import pycam.Plugins import pycam.Plugins
import pycam.Gui.ControlsGTK import pycam.Gui.ControlsGTK
...@@ -111,13 +112,20 @@ class GCodeSafetyHeight(pycam.Plugins.PluginBase): ...@@ -111,13 +112,20 @@ class GCodeSafetyHeight(pycam.Plugins.PluginBase):
self.safety_height.get_widget(), weight=20) self.safety_height.get_widget(), weight=20)
self.core.add_item("gcode_safety_height", self.core.add_item("gcode_safety_height",
self.safety_height.get_value, self.safety_height.set_value) self.safety_height.get_value, self.safety_height.set_value)
self.core.register_chain("state_dump", self.dump_state)
return True return True
def teardown(self): def teardown(self):
self.core.unregister_chain("state_dump", self.dump_state)
self.core.add_item("gcode_safety_height", lambda value: None, self.core.add_item("gcode_safety_height", lambda value: None,
lambda: None) lambda: None)
self.safety_height.destroy() self.safety_height.destroy()
def dump_state(self, result):
item = ET.Element("gcode_safety_height")
item.text = "%f" % self.core.get("gcode_safety_height")
result.append(("settings/gcode", item))
class GCodeFilenameExtension(pycam.Plugins.PluginBase): class GCodeFilenameExtension(pycam.Plugins.PluginBase):
...@@ -154,6 +162,7 @@ class GCodeStepWidth(pycam.Plugins.PluginBase): ...@@ -154,6 +162,7 @@ class GCodeStepWidth(pycam.Plugins.PluginBase):
table.widget) table.widget)
self.core.register_ui_section("gcode_step_width", self.core.register_ui_section("gcode_step_width",
table.add_widget, table.clear_widgets) table.add_widget, table.clear_widgets)
self.controls = []
for key in "xyz": for key in "xyz":
control = pycam.Gui.ControlsGTK.InputNumber(digits=8, start=0.0001, control = pycam.Gui.ControlsGTK.InputNumber(digits=8, start=0.0001,
increment=0.00005) increment=0.00005)
...@@ -163,8 +172,22 @@ class GCodeStepWidth(pycam.Plugins.PluginBase): ...@@ -163,8 +172,22 @@ class GCodeStepWidth(pycam.Plugins.PluginBase):
control.get_value, control.set_value) control.get_value, control.set_value)
self.core.register_ui("gcode_step_width", key.upper(), self.core.register_ui("gcode_step_width", key.upper(),
control.get_widget(), weight="xyz".index(key)) control.get_widget(), weight="xyz".index(key))
self.controls.append(control)
return True return True
def teardown(self):
while self.controls:
self.core.unregister_ui("gcode_step_width", self.controls.pop())
for key in "xyz":
self.core.add_item("gcode_minimum_step_%s" % key, lambda: None,
lambda value: None)
def dump_state(self, result):
for key in "xyz":
item = ET.Element("gcode_minimum_step_%s" % key)
item.text = "%f" % self.core.get("gcode_minimum_step_%s" % key)
result.append(("settings/gcode", item))
class GCodeSpindle(pycam.Plugins.PluginBase): class GCodeSpindle(pycam.Plugins.PluginBase):
......
...@@ -32,6 +32,7 @@ except (ImportError, RuntimeError): ...@@ -32,6 +32,7 @@ except (ImportError, RuntimeError):
import gtk import gtk
import math import math
import xml.etree.ElementTree as ET
from pycam.Gui.OpenGLTools import draw_complete_model_view from pycam.Gui.OpenGLTools import draw_complete_model_view
from pycam.Geometry.Point import Point from pycam.Geometry.Point import Point
...@@ -212,6 +213,7 @@ class OpenGLWindow(pycam.Plugins.PluginBase): ...@@ -212,6 +213,7 @@ class OpenGLWindow(pycam.Plugins.PluginBase):
# handlers # handlers
self.register_gtk_handlers(self._gtk_handlers) self.register_gtk_handlers(self._gtk_handlers)
self.register_event_handlers(self._event_handlers) self.register_event_handlers(self._event_handlers)
self.core.register_chain("state_dump", self.dump_state)
# show the window - the handlers _must_ be registered before "show" # show the window - the handlers _must_ be registered before "show"
self.area.show() self.area.show()
toggle_3d.set_active(True) toggle_3d.set_active(True)
...@@ -221,6 +223,7 @@ class OpenGLWindow(pycam.Plugins.PluginBase): ...@@ -221,6 +223,7 @@ class OpenGLWindow(pycam.Plugins.PluginBase):
def teardown(self): def teardown(self):
if self.gui: if self.gui:
self.core.unregister_chain("state_dump", self.dump_state)
self.core.unregister_ui("preferences", self.core.unregister_ui("preferences",
self.gui.get_object("OpenGLPrefTab")) self.gui.get_object("OpenGLPrefTab"))
toggle_3d = self.gui.get_object("Toggle3DView") toggle_3d = self.gui.get_object("Toggle3DView")
...@@ -241,6 +244,23 @@ class OpenGLWindow(pycam.Plugins.PluginBase): ...@@ -241,6 +244,23 @@ class OpenGLWindow(pycam.Plugins.PluginBase):
self.container.remove(self.area) self.container.remove(self.area)
self.area = None self.area = None
def dump_state(self, result):
# register all visible items ("show_model", ...) and OpenGL settings
for name in self._display_items.keys() + ["view_light", "view_shadow",
"view_polygon", "view_perspective", "drill_progress_max_fps"]:
item = ET.Element(name)
item.text = repr(bool(self.core.get(name)))
result.append(("settings/items", item))
# register all colors
for name in self._color_settings:
item = ET.Element(name)
color = self.core.get(name)
for index, color_key in enumerate(("red", "green", "blue",
"alpha")):
sub = ET.SubElement(item, color_key)
sub.text = str(color[index])
result.append(("settings/colors", item))
def update_view(self, widget=None, data=None): def update_view(self, widget=None, data=None):
if self.is_visible: if self.is_visible:
self.paint() self.paint()
......
...@@ -107,12 +107,12 @@ class Processes(pycam.Plugins.ListPluginBase): ...@@ -107,12 +107,12 @@ class Processes(pycam.Plugins.ListPluginBase):
("process-strategy-changed", self._store_process_settings)) ("process-strategy-changed", self._store_process_settings))
self.register_gtk_handlers(self._gtk_handlers) self.register_gtk_handlers(self._gtk_handlers)
self.register_event_handlers(self._event_handlers) self.register_event_handlers(self._event_handlers)
self.core.register_chain("xml_dump", self.dump_xml) self.core.register_chain("state_dump", self.dump_state)
return True return True
def teardown(self): def teardown(self):
if self.gui: if self.gui:
self.core.unregister_chain("xml_dump", self.dump_xml) self.core.unregister_chain("state_dump", self.dump_state)
self.core.unregister_ui("main", self.gui.get_object("ProcessBox")) self.core.unregister_ui("main", self.gui.get_object("ProcessBox"))
self.core.unregister_ui_section("process_path_parameters") self.core.unregister_ui_section("process_path_parameters")
self.core.unregister_ui("process_parameters", self.core.unregister_ui("process_parameters",
...@@ -263,7 +263,7 @@ class Processes(pycam.Plugins.ListPluginBase): ...@@ -263,7 +263,7 @@ class Processes(pycam.Plugins.ListPluginBase):
self.append(new_process) self.append(new_process)
self.select(new_process) self.select(new_process)
def dump_xml(self, result): def dump_state(self, result):
root = ET.Element("processes") root = ET.Element("processes")
for process in self: for process in self:
root.append(process.get_xml()) root.append(process.get_xml())
......
...@@ -132,12 +132,12 @@ class Tasks(pycam.Plugins.ListPluginBase): ...@@ -132,12 +132,12 @@ class Tasks(pycam.Plugins.ListPluginBase):
self._update_widgets() self._update_widgets()
self._update_table() self._update_table()
self._task_switch() self._task_switch()
self.core.register_chain("xml_dump", self.dump_xml) self.core.register_chain("state_dump", self.dump_state)
self.core.set("tasks", self) self.core.set("tasks", self)
return True return True
def teardown(self): def teardown(self):
self.core.unregister_chain("xml_dump", self.dump_xml) self.core.unregister_chain("state_dump", self.dump_state)
if self.gui: if self.gui:
self.core.unregister_ui("main", self.gui.get_object("TaskBox")) self.core.unregister_ui("main", self.gui.get_object("TaskBox"))
self.core.unregister_ui("task_parameters", self.core.unregister_ui("task_parameters",
...@@ -358,7 +358,7 @@ class Tasks(pycam.Plugins.ListPluginBase): ...@@ -358,7 +358,7 @@ class Tasks(pycam.Plugins.ListPluginBase):
progress.finish() progress.finish()
return result return result
def dump_xml(self, result): def dump_state(self, result):
root = ET.Element("tasks") root = ET.Element("tasks")
for task in self: for task in self:
root.append(task.get_xml()) root.append(task.get_xml())
......
...@@ -126,12 +126,12 @@ class Tools(pycam.Plugins.ListPluginBase): ...@@ -126,12 +126,12 @@ class Tools(pycam.Plugins.ListPluginBase):
self.register_event_handlers(self._event_handlers) self.register_event_handlers(self._event_handlers)
self._update_widgets() self._update_widgets()
self._tool_switch() self._tool_switch()
self.core.register_chain("xml_dump", self.dump_xml) self.core.register_chain("state_dump", self.dump_state)
return True return True
def teardown(self): def teardown(self):
if self.gui: if self.gui:
self.core.unregister_chain("xml_dump", self.dump_xml) self.core.unregister_chain("state_dump", self.dump_state)
self.core.unregister_ui("main", self.gui.get_object("ToolBox")) self.core.unregister_ui("main", self.gui.get_object("ToolBox"))
self.core.unregister_ui_section("tool_speed") self.core.unregister_ui_section("tool_speed")
self.core.unregister_ui_section("tool_size") self.core.unregister_ui_section("tool_size")
...@@ -286,7 +286,7 @@ class Tools(pycam.Plugins.ListPluginBase): ...@@ -286,7 +286,7 @@ class Tools(pycam.Plugins.ListPluginBase):
self.append(new_tool) self.append(new_tool)
self.select(new_tool) self.select(new_tool)
def dump_xml(self, result): def dump_state(self, result):
root = ET.Element("tools") root = ET.Element("tools")
for tool in self: for tool in self:
root.append(tool.get_xml()) root.append(tool.get_xml())
......
...@@ -20,9 +20,11 @@ You should have received a copy of the GNU General Public License ...@@ -20,9 +20,11 @@ You should have received a copy of the GNU General Public License
along with PyCAM. If not, see <http://www.gnu.org/licenses/>. along with PyCAM. If not, see <http://www.gnu.org/licenses/>.
""" """
import xml.etree.ElementTree as ET
import pycam.Plugins import pycam.Plugins
class Units(pycam.Plugins.PluginBase): class Units(pycam.Plugins.PluginBase):
UI_FILE = "units.ui" UI_FILE = "units.ui"
...@@ -58,15 +60,22 @@ class Units(pycam.Plugins.PluginBase): ...@@ -58,15 +60,22 @@ class Units(pycam.Plugins.PluginBase):
(self.unit_change_window, "delete_event", (self.unit_change_window, "delete_event",
self.change_unit_apply, False))) self.change_unit_apply, False)))
self.register_gtk_handlers(self._gtk_handlers) self.register_gtk_handlers(self._gtk_handlers)
self.core.register_chain("state_dump", self.dump_state)
return True return True
def teardown(self): def teardown(self):
if self.gui: if self.gui:
self.core.unregister_chain("state_dump", self.dump_state)
self.core.unregister_ui("preferences_general", self.core.unregister_ui("preferences_general",
self.gui.get_object("UnitPrefBox")) self.gui.get_object("UnitPrefBox"))
self.unregister_gtk_handlers(self._gtk_handlers) self.unregister_gtk_handlers(self._gtk_handlers)
# TODO: reset setting "unit" back to a default value? # TODO: reset setting "unit" back to a default value?
def dump_state(self, result):
item = ET.Element("unit")
item.text = self.core.get("unit")
result.append(("settings", item))
def change_unit_init(self, widget=None): def change_unit_init(self, widget=None):
new_unit = self.gui.get_object("unit_control").get_active_text() new_unit = self.gui.get_object("unit_control").get_active_text()
if self._last_unit is None: if self._last_unit is None:
......
...@@ -42,3 +42,26 @@ def get_xml(item, name="value", ignore_self=False): ...@@ -42,3 +42,26 @@ def get_xml(item, name="value", ignore_self=False):
leaf.text=repr(item) leaf.text=repr(item)
return leaf return leaf
def get_xml_lines(item):
lines = []
content = ET.tostring(item)
content = content.replace("><", ">\n<")
indent = 0
for line in content.split("\n"):
indented = False
if line.startswith("</"):
indent -= 2
indented = True
lines.append(" " * indent + line)
if indented:
pass
elif line.endswith("/>"):
pass
elif line.startswith("</"):
indent -= 2
elif "</" in line:
pass
else:
indent += 2
return lines
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