Commit 5a003841 authored by sumpfralle's avatar sumpfralle

added a simple log window


git-svn-id: https://pycam.svn.sourceforge.net/svnroot/pycam/trunk@530 bbaffbd6-741e-11dd-a85d-61de82d9cad9
parent 659ece8a
...@@ -166,6 +166,7 @@ class ProjectGui: ...@@ -166,6 +166,7 @@ class ProjectGui:
("Quit", self.destroy, None, "<Control>q"), ("Quit", self.destroy, None, "<Control>q"),
("GeneralSettings", self.toggle_preferences_window, None, "<Control>p"), ("GeneralSettings", self.toggle_preferences_window, None, "<Control>p"),
("Toggle3DView", self.toggle_3d_view, None, "<Control><Shift>v"), ("Toggle3DView", self.toggle_3d_view, None, "<Control><Shift>v"),
("ToggleLogWindow", self.toggle_log_window, None, "<Control>l"),
("HelpIntroduction", self.show_help, "Introduction", "F1"), ("HelpIntroduction", self.show_help, "Introduction", "F1"),
("HelpSupportedFormats", self.show_help, "SupportedFormats", None), ("HelpSupportedFormats", self.show_help, "SupportedFormats", None),
("HelpModelTransformations", self.show_help, "ModelTransformations", None), ("HelpModelTransformations", self.show_help, "ModelTransformations", None),
...@@ -181,7 +182,7 @@ class ProjectGui: ...@@ -181,7 +182,7 @@ class ProjectGui:
("BugTracker", self.show_help, "http://sourceforge.net/tracker/?group_id=237831&atid=1104176", None), ("BugTracker", self.show_help, "http://sourceforge.net/tracker/?group_id=237831&atid=1104176", None),
("FeatureRequest", self.show_help, "http://sourceforge.net/tracker/?group_id=237831&atid=1104179", None)): ("FeatureRequest", self.show_help, "http://sourceforge.net/tracker/?group_id=237831&atid=1104179", None)):
item = self.gui.get_object(objname) item = self.gui.get_object(objname)
if objname == "Toggle3DView": if objname in ("Toggle3DView", "ToggleLogWindow"):
action = "toggled" action = "toggled"
else: else:
action = "activate" action = "activate"
...@@ -212,6 +213,14 @@ class ProjectGui: ...@@ -212,6 +213,14 @@ class ProjectGui:
# TODO: fix this ugly hack! # TODO: fix this ugly hack!
self.gui.get_object("AboutWindowButtons").get_children()[-1].connect("clicked", self.toggle_about_window, False) self.gui.get_object("AboutWindowButtons").get_children()[-1].connect("clicked", self.toggle_about_window, False)
self.about_window.connect("delete-event", self.toggle_about_window, False) self.about_window.connect("delete-event", self.toggle_about_window, False)
# "log" window
self.log_window = self.gui.get_object("LogWindow")
self.log_window.set_default_size(500, 400)
self.log_window.connect("delete-event", self.toggle_log_window, False)
self.log_window.connect("destroy", self.toggle_log_window, False)
self.gui.get_object("LogWindowClose").connect("clicked", self.toggle_log_window, False)
self.gui.get_object("LogWindowClear").connect("clicked", self.clear_log_window)
self.log_model = self.gui.get_object("LogWindowList")
# set defaults # set defaults
self.model = None self.model = None
self.toolpath = pycam.Toolpath.ToolPathList() self.toolpath = pycam.Toolpath.ToolPathList()
...@@ -511,6 +520,7 @@ class ProjectGui: ...@@ -511,6 +520,7 @@ class ProjectGui:
self.window.add_accel_group(self._accel_group) self.window.add_accel_group(self._accel_group)
self.about_window.add_accel_group(self._accel_group) self.about_window.add_accel_group(self._accel_group)
self.preferences_window.add_accel_group(self._accel_group) self.preferences_window.add_accel_group(self._accel_group)
self.log_window.add_accel_group(self._accel_group)
# load menu data # load menu data
gtk_menu_file = get_data_file_location(GTKMENU_FILE) gtk_menu_file = get_data_file_location(GTKMENU_FILE)
if gtk_menu_file is None: if gtk_menu_file is None:
...@@ -536,6 +546,8 @@ class ProjectGui: ...@@ -536,6 +546,8 @@ class ProjectGui:
if not self.no_dialog: if not self.no_dialog:
# register a logging handler for displaying error messages # register a logging handler for displaying error messages
pycam.Utils.log.add_gtk_gui(self.window, logging.ERROR) pycam.Utils.log.add_gtk_gui(self.window, logging.ERROR)
# register a callback for the log window
pycam.Utils.log.add_hook(self.add_log_message)
self.window.show() self.window.show()
def update_all_controls(self): def update_all_controls(self):
...@@ -986,6 +998,33 @@ class ProjectGui: ...@@ -986,6 +998,33 @@ class ProjectGui:
# don't close the window - just hide it (for "delete-event") # don't close the window - just hide it (for "delete-event")
return True return True
def add_log_message(self, title, message, record=None):
timestamp = datetime.datetime.fromtimestamp(record.created).strftime("%H:%M")
self.log_model.append((timestamp, title, message))
@gui_activity_guard
def clear_log_window(self, widget=None):
self.log_model.clear()
@gui_activity_guard
def toggle_log_window(self, widget=None, value=None, action=None):
toggle_log_checkbox = self.gui.get_object("ToggleLogWindow")
checkbox_state = toggle_log_checkbox.get_active()
if value is None:
new_state = checkbox_state
else:
if action is None:
new_state = value
else:
new_state = action
if new_state:
self.log_window.show()
else:
self.log_window.hide()
toggle_log_checkbox.set_active(new_state)
# don't destroy the window with a "destroy" event
return True
@gui_activity_guard @gui_activity_guard
def toggle_3d_view(self, widget=None, value=None): def toggle_3d_view(self, widget=None, value=None):
toggle_3d_checkbox = self.gui.get_object("Toggle3DView") toggle_3d_checkbox = self.gui.get_object("Toggle3DView")
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
</menu> </menu>
<menu action="WindowMenu"> <menu action="WindowMenu">
<menuitem action="Toggle3DView"/> <menuitem action="Toggle3DView"/>
<menuitem action="ToggleLogWindow"/>
</menu> </menu>
<menu action="HelpMenu"> <menu action="HelpMenu">
<menuitem action="HelpIntroduction"/> <menuitem action="HelpIntroduction"/>
......
...@@ -179,6 +179,16 @@ ...@@ -179,6 +179,16 @@
</row> </row>
</data> </data>
</object> </object>
<object class="GtkListStore" id="LogWindowList">
<columns>
<!-- column-name timestamp -->
<column type="gchararray"/>
<!-- column-name type -->
<column type="gchararray"/>
<!-- column-name message -->
<column type="gchararray"/>
</columns>
</object>
<object class="GtkWindow" id="ProjectWindow"> <object class="GtkWindow" id="ProjectWindow">
<property name="title" translatable="yes">PyCAM</property> <property name="title" translatable="yes">PyCAM</property>
<property name="destroy_with_parent">True</property> <property name="destroy_with_parent">True</property>
...@@ -5526,4 +5536,123 @@ Any selected group of dimensions will be scaled accordingly.</property> ...@@ -5526,4 +5536,123 @@ Any selected group of dimensions will be scaled accordingly.</property>
<property name="upper">1000</property> <property name="upper">1000</property>
<property name="step_increment">1</property> <property name="step_increment">1</property>
</object> </object>
<object class="GtkToggleAction" id="ToggleLogWindow">
<property name="label">_Log Window</property>
<property name="tooltip">Show the event protocol of PyCAM.</property>
<property name="stock_id">gtk-dialog-info</property>
<property name="always_show_image">True</property>
</object>
<object class="GtkDialog" id="LogWindow">
<property name="border_width">5</property>
<property name="title" translatable="yes">PyCAM event log</property>
<property name="type_hint">normal</property>
<property name="has_separator">False</property>
<child internal-child="vbox">
<object class="GtkVBox" id="dialog-vbox6">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<property name="spacing">2</property>
<child>
<object class="GtkScrolledWindow" id="scrolledwindow2">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hscrollbar_policy">automatic</property>
<property name="vscrollbar_policy">automatic</property>
<property name="shadow_type">etched-in</property>
<child>
<object class="GtkTreeView" id="LogWindowTable">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="model">LogWindowList</property>
<property name="search_column">1</property>
<property name="enable_grid_lines">vertical</property>
<child>
<object class="GtkTreeViewColumn" id="LogWindowColumn0">
<property name="title">Time</property>
<property name="sort_column_id">0</property>
<child>
<object class="GtkCellRendererText" id="LogWindowColumnTime"/>
<attributes>
<attribute name="text">0</attribute>
</attributes>
</child>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="LogWindowColumn1">
<property name="title">Type</property>
<property name="sort_column_id">1</property>
<child>
<object class="GtkCellRendererText" id="LogWindowColumnType"/>
<attributes>
<attribute name="text">1</attribute>
</attributes>
</child>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="LogWindowColumn2">
<property name="title">Message</property>
<property name="sort_column_id">2</property>
<child>
<object class="GtkCellRendererText" id="LogWindowColumnMessage"/>
<attributes>
<attribute name="text">2</attribute>
</attributes>
</child>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="position">1</property>
</packing>
</child>
<child internal-child="action_area">
<object class="GtkHButtonBox" id="dialog-action_area4">
<property name="visible">True</property>
<property name="layout_style">end</property>
<child>
<object class="GtkButton" id="LogWindowClear">
<property name="label">gtk-clear</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_stock">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="LogWindowClose">
<property name="label">gtk-close</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_stock">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="pack_type">end</property>
<property name="position">0</property>
</packing>
</child>
</object>
</child>
<action-widgets>
<action-widget response="0">LogWindowClear</action-widget>
<action-widget response="0">LogWindowClose</action-widget>
</action-widgets>
</object>
</interface> </interface>
...@@ -48,6 +48,13 @@ def add_stream(stream, level=None): ...@@ -48,6 +48,13 @@ def add_stream(stream, level=None):
logstream.setLevel(level) logstream.setLevel(level)
log.addHandler(logstream) log.addHandler(logstream)
def add_hook(callback, level=None):
log = get_logger()
loghook = HookHandler(callback)
if not level is None:
loghook.setLevel(level)
log.addHandler(loghook)
def add_gtk_gui(parent_window, level=None): def add_gtk_gui(parent_window, level=None):
log = get_logger() log = get_logger()
loggui = GTKHandler(parent_window) loggui = GTKHandler(parent_window)
...@@ -80,3 +87,15 @@ class GTKHandler(logging.Handler): ...@@ -80,3 +87,15 @@ class GTKHandler(logging.Handler):
window.run() window.run()
window.destroy() window.destroy()
class HookHandler(logging.Handler):
def __init__(self, callback, **kwargs):
logging.Handler.__init__(self, **kwargs)
self.callback = callback
def emit(self, record):
message = self.format(record)
print dir(record)
message_type = record.levelname
self.callback(message_type, message, record=record)
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