require "rabbit/gtk" require "rabbit/keys" require "rabbit/logger/base" module Rabbit module Logger class GUI include Base attr_accessor :start_gui_main_loop_automatically def initialize(level=nil, width=450, height=400) super(*[level].compact) @width = width @height = height @start_gui_main_loop_automatically = false init_dialog end def clear_buffer @buffer.text = "" end def quit @dialog.destroy end private def do_log(severity, prog_name, message) # ::STDERR.puts(format_severity(severity)) # ::STDERR.puts(GLib.filename_from_utf8(message)) @current_severity = severity init_dialog if @dialog.destroyed? @dialog.show_all log_severity(severity) log_prog_name(prog_name) log_message(message) if @start_gui_main_loop_automatically and Gtk.main_level.zero? Thread.new {Gtk.main} end end def log_severity(severity) append("[") name = Severity::MARK_TABLE[severity] append(_(name), name) append("]\n") end def log_prog_name(prog_name) if prog_name append("#{prog_name}: ", "prog_name") end end def log_message(message) append(message, "message") append("\n") end def append(text, *tags) iter = @buffer.get_iter_at(offset: -1) @buffer.insert(iter, text.encode("UTF-8"), tags: tags) end def title _("Rabbit Error Dialog") end def init_dialog(width=@width, height=@height) @dialog = Gtk::Dialog.new(title: title, buttons: [ [Gtk::Stock::CLEAR, :cancel], [Gtk::Stock::CLOSE, :close], ]) @dialog.child.add(init_buffer) @dialog.set_default_size(width, height) @dialog.title = title set_dialog_delete set_dialog_response set_dialog_accel_group end def set_dialog_delete @dialog.signal_connect("destroy") do |widget, event| exit(false) if @current_severity >= Severity::FATAL true end end def set_dialog_response @dialog.signal_connect("response") do |widget, event| case event when Gtk::ResponseType::CANCEL clear_buffer when Gtk::ResponseType::CLOSE quit end true end end def set_dialog_accel_group accel_group = Gtk::AccelGroup.new mod = Gdk::ModifierType.new flags = Gtk::AccelFlags::VISIBLE Keys::QUIT_KEYS.each do |val| accel_group.connect(val, mod, flags) do @dialog.signal_emit("response", Gtk::ResponseType::CLOSE) true end end @dialog.add_accel_group(accel_group) end def init_buffer textview = Gtk::TextView.new textview.set_editable(false) textview.set_wrap_mode(:word) @buffer = textview.buffer create_tags scrolled_window = Gtk::ScrolledWindow.new scrolled_window.set_policy(:automatic, :automatic) scrolled_window.add(textview) scrolled_window end def create_tags @buffer.create_tag("DEBUG", "weight" => :bold, "foreground" => "blue") @buffer.create_tag("INFO", "foreground" => "blue") @buffer.create_tag("WARNING", "foreground" => "red") @buffer.create_tag("ERROR", "weight" => :bold, "foreground" => "red") @buffer.create_tag("FATAL", "foreground" => "yellow", "background" => "black") @buffer.create_tag("UNKNOWN", "weight" => :bold, "foreground" => "yellow", "background" => "black") @buffer.create_tag("ANY", "weight" => :bold) @buffer.create_tag("prog_name", "weight" => :bold, "foreground" => "blue", "left_margin" => 10) @buffer.create_tag("message", "weight" => :bold, "left_margin" => 10, "right_margin" => 10) end end end end