1 '''A module to handle a debug console'''
7 '''The window containing the debug info'''
9 self
.window
= gtk
.Window(gtk
.WINDOW_TOPLEVEL
)
10 self
.window
.set_title("debug")
11 self
.window
.connect("delete_event", self
.on_delete
)
12 self
.store
= DebugStore()
13 self
.view
= DebugView(self
.store
)
14 self
.scroll_view
= gtk
.ScrolledWindow()
15 self
.scroll_view
.add(self
.view
)
18 self
.vbox
= gtk
.VBox()
19 self
.filter_box
= gtk
.HBox()
20 self
.buttons_box
= gtk
.HBox()
21 self
.test_box
= gtk
.HBox()
23 self
.filter_entry
= gtk
.Entry()
24 self
.filter_btn
= gtk
.Button("Filter")
25 self
.filter_box
.pack_start(self
.filter_entry
)
26 self
.filter_box
.pack_start(self
.filter_btn
, False)
27 self
.vbox
.pack_start(self
.filter_box
, False)
29 self
.vbox
.pack_start(self
.scroll_view
)
31 self
.close_btn
= gtk
.Button("Close")
32 self
.buttons_box
.pack_end(self
.close_btn
, False)
33 self
.vbox
.pack_start(self
.buttons_box
, False)
35 self
.test_entry
= gtk
.Entry()
36 self
.test_add
= gtk
.Button("Add")
37 self
.test_box
.pack_start(self
.test_entry
)
38 self
.test_box
.pack_start(self
.test_add
, False)
39 self
.vbox
.pack_start(self
.test_box
, False)
42 self
.window
.add(self
.vbox
)
44 self
.filter_btn
.connect("clicked", self
.on_filter_clicked
)
45 self
.filter_entry
.connect("activate", self
.on_filter_clicked
)
46 self
.close_btn
.connect("clicked", self
.on_close
)
47 self
.test_add
.connect("clicked", self
.on_add
)
48 self
.test_entry
.connect("activate", self
.on_add
)
50 self
.store
.append([ "foo", "bar" ])
51 self
.store
.append([ "asd", "qwe" ])
53 self
.buffer = DebugBuffer(self
.store
)
56 '''shows the window'''
57 self
.window
.show_all()
59 def on_filter_clicked(self
, button
, data
=None):
60 '''used when the filter button is clicked'''
61 pattern
= self
.filter_entry
.get_text()
62 self
.view
.filter_caller(pattern
)
64 def on_add(self
, button
, data
=None):
65 caller
= self
.test_entry
.get_text()
66 self
.store
.append([caller
, "just a test"])
68 def on_close(self
, button
, data
=None):
72 def on_delete(self
, widget
, event
, data
=None):
77 class DebugView( gtk
.TextView
):
78 '''A TextView optimized for debug consoles'''
79 def __init__(self
, store
):
80 gtk
.TextView
.__init
__(self
)
82 self
.buffer = DebugBuffer(store
)
83 self
.set_buffer(self
.buffer)
85 self
.set_editable(False)
87 def filter_caller(self
, pattern
):
88 self
.store
.filter_caller(pattern
)
89 self
.buffer = DebugBuffer(self
.store
.filter)
90 self
.set_buffer(self
.buffer)
92 class DebugBuffer( gtk
.TextBuffer
):
93 '''A TextBuffer based on a ListStore'''
94 def __init__(self
, store
):
95 gtk
.TextBuffer
.__init
__(self
)
98 self
.create_tag("caller", weight
=pango
.WEIGHT_BOLD
)
99 self
.create_tag("message")
101 self
.iter = self
.get_start_iter()
103 self
.insert_with_tags_by_name(self
.iter, row
[0], "caller")
104 self
.insert_with_tags_by_name(self
.iter, ": " + row
[1], "message")
105 print row
[0], ":", row
[1]
107 store
.connect("row-changed", self
.on_store_insert
)
110 def on_store_insert(self
, model
, path
, iter):
111 caller
= model
.get_value(iter, 0)
112 message
= model
.get_value(iter, 1)
113 if caller
and message
:
114 self
.insert_with_tags_by_name(self
.iter, caller
, "caller")
115 self
.insert_with_tags_by_name(self
.iter, ": " + message
+ '\n', "message")
116 print caller
, ':', message
118 class DebugStore( gtk
.ListStore
):
119 '''A ListStore with filtering and more, optimized for debug'''
120 def __init__( self
):
122 gtk
.ListStore
.__init
__(self
, str, str) #caller, message
123 self
.filter = self
.filter_new()
126 def filter_caller( self
, name
):
127 '''displays only the messages whose caller matches "name"'''
129 self
.filter = self
.filter_new()
130 self
.filter.set_visible_func(filter_func
, name
)
132 def filter_func(model
, iter, name
):
133 '''returns true if the caller column matches name'''
134 caller
= model
.get_value(iter, 0)
137 if caller
.find(name
) == -1:
142 '''Manages debug informations, events and cleanups'''
145 self
.messages
= [] #list of messages, each one is a dict
147 self
.__event
_callbacks
= {}
149 def add(self
, message
):
150 '''add the message'''
151 #message is {'category': 'misc', 'message':'foo', 'priority':'low',...}
152 self
.messages
.append(message
)
153 self
.emit('message-added', message
)
156 '''get all messages'''
160 '''return the nth message'''
161 return self
.messages
[n
]
164 def emit(self
, event_name
, *args
):
165 '''emits the signal named event_name'''
166 for callback
in self
.__event
_callbacks
[event_name
]:
169 def connect(self
, event_name
, callback
):
170 '''connect the event called "event_name" with the callback'''
171 if event_name
not in self
.__event
_callbacks
:
172 self
.__event
_callbacks
[event_name
] = []
173 self
.__event
_callbacks
[event_name
].append(callback
)
175 def simple_print(message
):
179 if __name__
== '__main__':
180 debug_manager
= DebugManager()
181 debug_manager
.connect('message-added', simple_print
)
182 debug_manager
.add({'category':'core', 'message':'something happened'})