Commit 624c80ee authored by sumpfralle's avatar sumpfralle

moved log window to separete plugin


git-svn-id: https://pycam.svn.sourceforge.net/svnroot/pycam/trunk@1114 bbaffbd6-741e-11dd-a85d-61de82d9cad9
parent c10383ec
<?xml version="1.0"?>
<interface>
<!-- interface-requires gtk+ 2.12 -->
<!-- interface-naming-policy project-wide -->
<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="GtkDialog" id="LogWindow">
<property name="border_width">5</property>
<property name="title" translatable="yes">PyCAM event log</property>
<property name="role">pycam-log</property>
<property name="type_hint">normal</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="clickable">True</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="clickable">True</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="clickable">True</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="LogWindowCopyToClipboard">
<property name="label">gtk-copy</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="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">1</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">2</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">LogWindowCopyToClipboard</action-widget>
<action-widget response="0">LogWindowClear</action-widget>
<action-widget response="0">LogWindowClose</action-widget>
</action-widgets>
</object>
<object class="GtkToggleAction" id="ToggleLogWindow">
<property name="label">_Log Window</property>
<property name="short_label">_Log Window</property>
<property name="tooltip">Show the event protocol of PyCAM.</property>
</object>
<object class="GtkWindow" id="DummyWindow">
<child>
<object class="GtkEventBox" id="StatusBarEventBox">
<property name="visible">True</property>
<child>
<object class="GtkHBox" id="hbox37">
<property name="visible">True</property>
<child>
<object class="GtkImage" id="StatusBarWarning">
<property name="stock">gtk-dialog-warning</property>
</object>
<packing>
<property name="expand">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkStatusbar" id="StatusBar">
<property name="visible">True</property>
<property name="spacing">2</property>
</object>
<packing>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</object>
</child>
</object>
</interface>
...@@ -179,16 +179,6 @@ ...@@ -179,16 +179,6 @@
</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="GtkListStore" id="GCodeCornerStyleList"> <object class="GtkListStore" id="GCodeCornerStyleList">
<columns> <columns>
<!-- column-name name --> <!-- column-name name -->
...@@ -3516,139 +3506,6 @@ Any selected group of dimensions will be scaled accordingly.</property> ...@@ -3516,139 +3506,6 @@ Any selected group of dimensions will be scaled accordingly.</property>
<object class="GtkAction" id="FeatureRequest"> <object class="GtkAction" id="FeatureRequest">
<property name="label">Re_quest a Feature</property> <property name="label">Re_quest a Feature</property>
</object> </object>
<object class="GtkToggleAction" id="ToggleLogWindow">
<property name="label">_Log Window</property>
<property name="tooltip">Show the event protocol of PyCAM.</property>
</object>
<object class="GtkDialog" id="LogWindow">
<property name="border_width">5</property>
<property name="title" translatable="yes">PyCAM event log</property>
<property name="role">pycam-log</property>
<property name="type_hint">normal</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="LogWindowCopyToClipboard">
<property name="label">gtk-copy</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="tooltip_text" translatable="yes">Copy the content of the log to the clipboard.</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="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">1</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">2</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">LogWindowCopyToClipboard</action-widget>
<action-widget response="0">LogWindowClear</action-widget>
<action-widget response="0">LogWindowClose</action-widget>
</action-widgets>
</object>
<object class="GtkAction" id="HelpHotkeys"> <object class="GtkAction" id="HelpHotkeys">
<property name="label">_Keyboard Shortcuts</property> <property name="label">_Keyboard Shortcuts</property>
</object> </object>
...@@ -7265,36 +7122,7 @@ upon interesting bugs and weird results.</property> ...@@ -7265,36 +7122,7 @@ upon interesting bugs and weird results.</property>
</packing> </packing>
</child> </child>
<child> <child>
<object class="GtkEventBox" id="StatusBarEventBox"> <placeholder/>
<property name="visible">True</property>
<child>
<object class="GtkHBox" id="hbox37">
<property name="visible">True</property>
<child>
<object class="GtkImage" id="StatusBarWarning">
<property name="stock">gtk-dialog-warning</property>
</object>
<packing>
<property name="expand">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkStatusbar" id="StatusBar">
<property name="visible">True</property>
<property name="spacing">2</property>
</object>
<packing>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="position">2</property>
</packing>
</child> </child>
</object> </object>
</child> </child>
......
...@@ -381,7 +381,6 @@ class ProjectGui(object): ...@@ -381,7 +381,6 @@ class ProjectGui(object):
("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"),
("ToggleProcessPoolWindow", self.toggle_process_pool_window, None, None), ("ToggleProcessPoolWindow", self.toggle_process_pool_window, None, None),
("UndoButton", self._restore_undo_state, None, "<Control>z"), ("UndoButton", self._restore_undo_state, None, "<Control>z"),
("CopyModelToClipboard", self.copy_model_to_clipboard, None, "<Control>c"), ("CopyModelToClipboard", self.copy_model_to_clipboard, None, "<Control>c"),
...@@ -407,8 +406,7 @@ class ProjectGui(object): ...@@ -407,8 +406,7 @@ class ProjectGui(object):
("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 in ("Toggle3DView", "ToggleLogWindow", if objname in ("Toggle3DView", "ToggleProcessPoolWindow"):
"ToggleProcessPoolWindow"):
action = "toggled" action = "toggled"
else: else:
action = "activate" action = "activate"
...@@ -450,7 +448,6 @@ class ProjectGui(object): ...@@ -450,7 +448,6 @@ class ProjectGui(object):
self.preferences_window.connect("delete-event", self.toggle_preferences_window, False) self.preferences_window.connect("delete-event", self.toggle_preferences_window, False)
self._preferences_window_position = None self._preferences_window_position = None
self._preferences_window_visible = False self._preferences_window_visible = False
self._log_window_position = None
# "about" window # "about" window
self.about_window = self.gui.get_object("AboutWindow") self.about_window = self.gui.get_object("AboutWindow")
self.about_window.set_version(VERSION) self.about_window.set_version(VERSION)
...@@ -463,16 +460,6 @@ class ProjectGui(object): ...@@ -463,16 +460,6 @@ class ProjectGui(object):
# 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.gui.get_object("LogWindowCopyToClipboard").connect("clicked",
self.copy_log_to_clipboard)
self.log_model = self.gui.get_object("LogWindowList")
# "process pool" window # "process pool" window
self.process_pool_window = self.gui.get_object("ProcessPoolWindow") self.process_pool_window = self.gui.get_object("ProcessPoolWindow")
self.process_pool_window.set_default_size(500, 400) self.process_pool_window.set_default_size(500, 400)
...@@ -487,7 +474,7 @@ class ProjectGui(object): ...@@ -487,7 +474,7 @@ class ProjectGui(object):
self._accel_group = uimanager.get_accel_group() self._accel_group = uimanager.get_accel_group()
self.settings.add_item("gtk-accel-group", lambda: self._accel_group) self.settings.add_item("gtk-accel-group", lambda: self._accel_group)
for window in (self.window, self.about_window, self.preferences_window, for window in (self.window, self.about_window, self.preferences_window,
self.log_window, self.process_pool_window): self.process_pool_window):
window.add_accel_group(self._accel_group) window.add_accel_group(self._accel_group)
# set defaults # set defaults
self.toolpath = pycam.Toolpath.ToolpathList() self.toolpath = pycam.Toolpath.ToolpathList()
...@@ -518,7 +505,6 @@ class ProjectGui(object): ...@@ -518,7 +505,6 @@ class ProjectGui(object):
item = self.gui.get_object(name + "Tab") item = self.gui.get_object(name + "Tab")
self.settings.register_ui("main", name, item, tab_names.index(name)) self.settings.register_ui("main", name, item, tab_names.index(name))
main_window = self.gui.get_object("WindowBox") main_window = self.gui.get_object("WindowBox")
event_bar = self.gui.get_object("StatusBarEventBox")
def clear_main_window(): def clear_main_window():
main_window.foreach(lambda x: main_window.remove(x)) main_window.foreach(lambda x: main_window.remove(x))
def add_main_window_item(item, name, **extra_args): def add_main_window_item(item, name, **extra_args):
...@@ -527,12 +513,10 @@ class ProjectGui(object): ...@@ -527,12 +513,10 @@ class ProjectGui(object):
args.update(extra_args) args.update(extra_args)
main_window.pack_start(item, **args) main_window.pack_start(item, **args)
main_tab.unparent() main_tab.unparent()
event_bar.unparent()
self.settings.register_ui_section("main_window", add_main_window_item, self.settings.register_ui_section("main_window", add_main_window_item,
clear_main_window) clear_main_window)
self.settings.register_ui("main_window", "Tabs", main_tab, -20, self.settings.register_ui("main_window", "Tabs", main_tab, -20,
args_dict={"expand": True, "fill": True}) args_dict={"expand": True, "fill": True})
self.settings.register_ui("main_window", "Status", event_bar, 100)
# unit control (mm/inch) # unit control (mm/inch)
unit_field = self.gui.get_object("unit_control") unit_field = self.gui.get_object("unit_control")
unit_field.connect("changed", self.change_unit_init) unit_field.connect("changed", self.change_unit_init)
...@@ -992,10 +976,6 @@ class ProjectGui(object): ...@@ -992,10 +976,6 @@ class ProjectGui(object):
if cpu_cores is None: if cpu_cores is None:
cpu_cores = "unknown" cpu_cores = "unknown"
self.gui.get_object("AvailableCores").set_label(str(cpu_cores)) self.gui.get_object("AvailableCores").set_label(str(cpu_cores))
# status bar
self.status_bar = self.gui.get_object("StatusBar")
self.gui.get_object("StatusBarEventBox").connect("button-press-event",
self.toggle_log_window)
# set the icons (in different sizes) for all windows # set the icons (in different sizes) for all windows
gtk.window_set_default_icon_list(*get_icons_pixbuffers()) gtk.window_set_default_icon_list(*get_icons_pixbuffers())
# load menu data # load menu data
...@@ -1058,8 +1038,6 @@ class ProjectGui(object): ...@@ -1058,8 +1038,6 @@ class ProjectGui(object):
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()
self.toggle_3d_view(value=True) self.toggle_3d_view(value=True)
...@@ -1774,75 +1752,6 @@ class ProjectGui(object): ...@@ -1774,75 +1752,6 @@ class ProjectGui(object):
# 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")
# avoid the ugly character for a linefeed
message = " ".join(message.splitlines())
try:
message = message.encode("utf-8")
except UnicodeDecodeError:
# remove all non-ascii characters
clean_char = lambda c: (32 <= ord(c) < 128) and c or " "
message = "".join([clean_char(char) for char in message])
self.log_model.append((timestamp, title, message))
# update the status bar (if the GTK interface is still active)
if not self.status_bar.window is None:
# remove the last message from the stack (probably not necessary)
self.status_bar.pop(0)
# push the new message
try:
self.status_bar.push(0, message)
except TypeError:
new_message = re.sub("[^\w\s]", "", message)
self.status_bar.push(0, new_message)
# highlight the "warning" icon for warnings/errors
if record and record.levelno > 20:
self.gui.get_object("StatusBarWarning").show()
@gui_activity_guard
def copy_log_to_clipboard(self, widget=None):
content = []
def copy_row(model, path, it, content):
columns = []
for column in range(model.get_n_columns()):
columns.append(model.get_value(it, column))
content.append(" ".join(columns))
self.log_model.foreach(copy_row, content)
self.clipboard.set_text(os.linesep.join(content))
self.gui.get_object("StatusBarWarning").hide()
@gui_activity_guard
def clear_log_window(self, widget=None):
self.log_model.clear()
self.gui.get_object("StatusBarWarning").hide()
@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
elif isinstance(value, gtk.gdk.Event):
# someone clicked at the status bar -> toggle the window state
new_state = not checkbox_state
else:
if action is None:
new_state = value
else:
new_state = action
if new_state:
if self._log_window_position:
self.log_window.move(*self._log_window_position)
self.log_window.show()
else:
self._log_window_position = self.log_window.get_position()
self.log_window.hide()
toggle_log_checkbox.set_active(new_state)
self.gui.get_object("StatusBarWarning").hide()
# don't destroy the window with a "destroy" event
return True
@gui_activity_guard @gui_activity_guard
def toggle_process_pool_window(self, widget=None, value=None, action=None): def toggle_process_pool_window(self, widget=None, value=None, action=None):
toggle_process_pool_checkbox = self.gui.get_object("ToggleProcessPoolWindow") toggle_process_pool_checkbox = self.gui.get_object("ToggleProcessPoolWindow")
......
# -*- coding: utf-8 -*-
"""
$Id$
Copyright 2011 Lars Kruse <devel@sumpfralle.de>
This file is part of PyCAM.
PyCAM is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
PyCAM is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with PyCAM. If not, see <http://www.gnu.org/licenses/>.
"""
import os
import datetime
import pycam.Plugins
class Log(pycam.Plugins.PluginBase):
UI_FILE = "log.ui"
def setup(self):
if self.gui:
import gtk
self._gtk = gtk
# menu item and shortcut
actiongroup = self._gtk.ActionGroup("log")
log_action = self.gui.get_object("ToggleLogWindow")
log_action.connect("toggled", self.toggle_log_window)
key, mod = self._gtk.accelerator_parse("<Control>l")
# TODO: move the "<pycam>" accel path somewhere else
accel_path = "<pycam>/ToggleLogWindow"
log_action.set_accel_path(accel_path)
self._gtk.accel_map_change_entry(accel_path, key, mod, True)
actiongroup.add_action(log_action)
self.core.get("gtk-uimanager").insert_action_group(actiongroup, pos=-1)
# status bar
self.status_bar = self.gui.get_object("StatusBar")
self.gui.get_object("StatusBarEventBox").connect("button-press-event",
self.toggle_log_window)
event_bar = self.gui.get_object("StatusBarEventBox")
event_bar.unparent()
self.core.register_ui("main_window", "Status", event_bar, 100)
# "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.gui.get_object("LogWindowCopyToClipboard").connect("clicked",
self.copy_log_to_clipboard)
self.log_model = self.gui.get_object("LogWindowList")
# window state
self._log_window_position = None
# register a callback for the log window
pycam.Utils.log.add_hook(self.add_log_message)
return True
def add_log_message(self, title, message, record=None):
timestamp = datetime.datetime.fromtimestamp(
record.created).strftime("%H:%M")
# avoid the ugly character for a linefeed
message = " ".join(message.splitlines())
try:
message = message.encode("utf-8")
except UnicodeDecodeError:
# remove all non-ascii characters
clean_char = lambda c: (32 <= ord(c) < 128) and c or " "
message = "".join([clean_char(char) for char in message])
self.log_model.append((timestamp, title, message))
# update the status bar (if the GTK interface is still active)
if not self.status_bar.window is None:
# remove the last message from the stack (probably not necessary)
self.status_bar.pop(0)
# push the new message
try:
self.status_bar.push(0, message)
except TypeError:
new_message = re.sub("[^\w\s]", "", message)
self.status_bar.push(0, new_message)
# highlight the "warning" icon for warnings/errors
if record and record.levelno > 20:
self.gui.get_object("StatusBarWarning").show()
def copy_log_to_clipboard(self, widget=None):
content = []
def copy_row(model, path, it, content):
columns = []
for column in range(model.get_n_columns()):
columns.append(model.get_value(it, column))
content.append(" ".join(columns))
self.log_model.foreach(copy_row, content)
self.clipboard.set_text(os.linesep.join(content))
self.gui.get_object("StatusBarWarning").hide()
def clear_log_window(self, widget=None):
self.log_model.clear()
self.gui.get_object("StatusBarWarning").hide()
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
elif isinstance(value, self._gtk.gdk.Event):
# someone clicked at the status bar -> toggle the window state
new_state = not checkbox_state
else:
if action is None:
new_state = value
else:
new_state = action
if new_state:
if self._log_window_position:
self.log_window.move(*self._log_window_position)
self.log_window.show()
else:
self._log_window_position = self.log_window.get_position()
self.log_window.hide()
toggle_log_checkbox.set_active(new_state)
self.gui.get_object("StatusBarWarning").hide()
# don't destroy the window with a "destroy" event
return True
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