244 lines
7.6 KiB
Ruby
Executable File
244 lines
7.6 KiB
Ruby
Executable File
#
|
|
# File:: log_window.rb
|
|
# Description::
|
|
#
|
|
# Author:: David Muir <david.muir@rockstarnorth.com>
|
|
# Date:: 12 January 2009
|
|
#
|
|
|
|
#----------------------------------------------------------------------------
|
|
# Uses
|
|
#----------------------------------------------------------------------------
|
|
require 'pipeline/log/log'
|
|
require 'pipeline/os/path'
|
|
require 'thread'
|
|
require 'wx'
|
|
|
|
#----------------------------------------------------------------------------
|
|
# Implementation
|
|
#----------------------------------------------------------------------------
|
|
module Pipeline
|
|
module GUI
|
|
|
|
#
|
|
# == Description
|
|
# Generic log window dialog that integrates with our Pipeline::Log
|
|
# objects for displaying log messages to users.
|
|
#
|
|
# === Example Usage
|
|
# # To auto-popup the display of the log dialog:
|
|
# Pipeline::GUI::LogWindow::show_dialog( true ) do
|
|
# # Do something that will log messages, dialog only displayed on
|
|
# # errors.
|
|
# end
|
|
#
|
|
# # To force the display of the log dialog:
|
|
# Pipeline::GUI::LogWindow::show_dialog( ) do
|
|
# # Do something that will log messages
|
|
# end
|
|
#
|
|
class LogWindow < Wx::App
|
|
THREAD_TIMER_ID = Wx::ID_HIGHEST + 1
|
|
|
|
#---------------------------------------------------------------------
|
|
# Class Methods
|
|
#---------------------------------------------------------------------
|
|
def initialize( log, auto_popup, title = 'Log', &block )
|
|
super( )
|
|
@log = log
|
|
@auto_popup = auto_popup
|
|
@title = title
|
|
@proc = Proc.new( ) do
|
|
yield
|
|
end
|
|
end
|
|
|
|
#
|
|
# Use this method to explicitly display a log dialog box. Only
|
|
# log messages generated after this call will be displayed.
|
|
#
|
|
def LogWindow::show_dialog( auto_popup = false, log = Pipeline::LogSystem::instance().rootlog, title = 'Pipeline Log' )
|
|
begin
|
|
dlg = LogWindow.new( log, auto_popup, title ) do
|
|
yield if ( block_given? )
|
|
end
|
|
dlg.main_loop( )
|
|
rescue Exception => ex
|
|
raise unless ( 'exit' == ex.message )
|
|
end
|
|
end
|
|
|
|
#---------------------------------------------------------------------
|
|
# Instance Methods
|
|
#---------------------------------------------------------------------
|
|
def on_init( )
|
|
Wx::Timer::every( 25 ) do
|
|
Thread::pass( )
|
|
end
|
|
dlg = LogWindowDialog::new( @log, @title, @auto_popup )
|
|
dlg.show( ) unless ( @auto_popup )
|
|
|
|
script_thread = Thread.new do
|
|
@proc.call( )
|
|
exit( ) if ( @auto_popup and ( not dlg.is_shown ) )
|
|
end
|
|
script_thread.join( )
|
|
end
|
|
end
|
|
|
|
|
|
#
|
|
# == Description
|
|
# Generic log window dialog that integrates with our Pipeline::Log
|
|
# objects for displaying log messages to users.
|
|
#
|
|
# === Example Usage
|
|
# # To auto-popup the display of the log dialog on error messages:
|
|
# Pipeline::GUI::LogWindow::show_dialog( true ) do
|
|
# # Do something that will log messages
|
|
# end
|
|
#
|
|
# # To force the display of the log dialog:
|
|
# Pipeline::GUI::LogWindow::show_dialog( ) do
|
|
# # Do something that will log messages
|
|
# end
|
|
#
|
|
class LogWindowDialog < Wx::Dialog
|
|
|
|
#
|
|
# == Description
|
|
# Internally used Log4r::Formatter to format log messages for our
|
|
# LogWindowOutputter class below.
|
|
#
|
|
class LogWindowFormatter < Log4r::Formatter
|
|
def initialize( hash = {} )
|
|
super( hash )
|
|
end
|
|
|
|
#
|
|
# Pass the Log4r event object straight over to outputter, rather
|
|
# than serialising it into a String. This saves us having to parse
|
|
# a log message formatted String using Regexp or similar.
|
|
#
|
|
def format( event )
|
|
event
|
|
end
|
|
end
|
|
|
|
#
|
|
# == Description
|
|
# Internally used Log4r::Outputter to log messages into our log
|
|
# window.
|
|
#
|
|
class LogWindowOutputter < Log4r::Outputter
|
|
attr_reader :dialog
|
|
|
|
def initialize( dialog, _name, hash = {} )
|
|
super( _name, hash )
|
|
@dialog = dialog
|
|
end
|
|
|
|
#--------------------------------------------------------------------
|
|
# Private
|
|
#--------------------------------------------------------------------
|
|
private
|
|
def write( data )
|
|
# Pass the log data straight to our Log Window for processing.
|
|
@dialog.append_message( data )
|
|
end
|
|
end
|
|
|
|
#--------------------------------------------------------------------
|
|
# Attributes
|
|
#--------------------------------------------------------------------
|
|
attr_reader :auto_popup
|
|
|
|
#
|
|
# Constructor.
|
|
#
|
|
def initialize( log, title, auto_popup )
|
|
super( nil, Wx::ID_ANY, title, Wx::DEFAULT_POSITION, Wx::Size.new(500,550),
|
|
Wx::DEFAULT_DIALOG_STYLE | Wx::DIALOG_NO_PARENT | Wx::MAXIMIZE_BOX | Wx::RESIZE_BORDER | Wx::CLIP_CHILDREN )
|
|
@log = log
|
|
@auto_popup = auto_popup
|
|
|
|
c = Pipeline::Config::instance( )
|
|
icon = Wx::Icon.new( )
|
|
icon.load_file( OS::Path.combine( c.toolslib, 'data', 'icons', 'rs_icon.ico' ), Wx::BITMAP_TYPE_ICO )
|
|
set_icon( icon )
|
|
|
|
#-----------------------------------------------------------------
|
|
# WIDGETS
|
|
#-----------------------------------------------------------------
|
|
@txtCtrl = Wx::TextCtrl.new( self, Wx::ID_ANY, '',
|
|
Wx::DEFAULT_POSITION, Wx::DEFAULT_SIZE,
|
|
Wx::TE_MULTILINE | Wx::TE_RICH2 | Wx::TE_AUTO_URL )
|
|
btnClose = Wx::Button.new( self, Wx::ID_ANY, 'Close' )
|
|
btnClose.set_default( )
|
|
|
|
#-----------------------------------------------------------------
|
|
# EVENTS
|
|
#-----------------------------------------------------------------
|
|
evt_button( btnClose.get_id( ) ) do |event|
|
|
close( )
|
|
end
|
|
evt_close( ) do |event|
|
|
@log.remove( @outputter )
|
|
event.skip( ) # continue closing
|
|
exit( )
|
|
end
|
|
|
|
#-----------------------------------------------------------------
|
|
# LOG OUTPUTTER INIT
|
|
#-----------------------------------------------------------------
|
|
@outputter = LogWindowOutputter.new( self, 'log_window' )
|
|
@outputter.formatter = LogWindowFormatter.new( )
|
|
@log.add( @outputter )
|
|
|
|
#-----------------------------------------------------------------
|
|
# LAYOUT
|
|
#-----------------------------------------------------------------
|
|
sizer_vert = Wx::BoxSizer.new( Wx::VERTICAL )
|
|
sizer_bottom = Wx::BoxSizer.new( Wx::HORIZONTAL )
|
|
|
|
sizer_bottom.add_spacer( 1 )
|
|
sizer_bottom.add( btnClose, 1, Wx::ALL | Wx::ALIGN_RIGHT )
|
|
|
|
sizer_vert.add( @txtCtrl, 20, Wx::ALL | Wx::EXPAND | Wx::GROW, 1 )
|
|
sizer_vert.add( sizer_bottom, 0, Wx::BOTTOM )
|
|
set_sizer( sizer_vert )
|
|
end
|
|
|
|
#
|
|
# Append a log message into our window. Typically called by a log
|
|
# outputter object (e.g. LogWindowOutputter).
|
|
#
|
|
def append_message( event )
|
|
@txtCtrl.set_default_style( Wx::TextAttr.new( Wx::BLACK ) )
|
|
@txtCtrl.append_text( Time.now.strftime( '%Y-%m-%d %H:%M:%S ' ) )
|
|
case event.level
|
|
when 5, 4 # fatal, error
|
|
@txtCtrl.set_default_style( Wx::TextAttr.new( Wx::RED ) )
|
|
show( ) if ( @auto_popup )
|
|
when 3 # warning
|
|
@txtCtrl.set_default_style( Wx::TextAttr.new( Wx::Colour.new( 255, 127, 0 ) ) )
|
|
when 2 # info
|
|
@txtCtrl.set_default_style( Wx::TextAttr.new( Wx::Colour.new( 0, 140, 30 ) ) )
|
|
when 1 # debug
|
|
@txtCtrl.set_default_style( Wx::TextAttr.new( Wx::BLUE ) )
|
|
else # info and catch all
|
|
@txtCtrl.set_default_style( Wx::TextAttr.new( Wx::BLACK ) )
|
|
end
|
|
@txtCtrl.append_text( "#{Log4r::LNAMES[event.level]}" )
|
|
@txtCtrl.set_default_style( Wx::TextAttr.new( Wx::BLACK ) )
|
|
@txtCtrl.append_text( " #{event.logger.name}" ) if ( event.methods.include?( 'logger' ) )
|
|
@txtCtrl.append_text( " at #{event.tracer[0]}" ) unless ( event.tracer.nil? )
|
|
@txtCtrl.append_text( ": #{event.data}\n" )
|
|
end
|
|
end
|
|
|
|
end # GUI module
|
|
end # Pipeline module
|
|
|
|
# log_window.rb
|