Starting to refactor. Created DebugManager, still not "connected"
[debug_console.git] / DebugWindow.py
blobfc6ffe22776a89f971bc76bc02740cfc24fa391f
1 '''A module to handle a debug console'''
2 import gtk
3 import pango
6 class DebugWindow():
7 '''The window containing the debug info'''
8 def __init__(self):
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)
55 def show( self ):
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):
69 gtk.main_quit()
70 return False
72 def on_delete(self, widget, event, data=None):
73 gtk.main_quit()
74 return False
77 class DebugView( gtk.TextView ):
78 '''A TextView optimized for debug consoles'''
79 def __init__(self, store):
80 gtk.TextView.__init__(self)
81 self.store = store
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)
96 self.store = store
98 self.create_tag("caller", weight=pango.WEIGHT_BOLD)
99 self.create_tag("message")
101 self.iter = self.get_start_iter()
102 for row in store:
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 ):
121 '''constructor'''
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"'''
128 del self.filter
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)
135 if not caller:
136 return False
137 if caller.find(name) == -1:
138 return False
139 return True
141 class DebugManager:
142 '''Manages debug informations, events and cleanups'''
143 def __init__(self):
144 '''constructor'''
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)
155 def get_all(self):
156 '''get all messages'''
157 return self.messages
159 def get_n(self, n):
160 '''return the nth message'''
161 return self.messages[n]
163 #Event handling
164 def emit(self, event_name, *args):
165 '''emits the signal named event_name'''
166 for callback in self.__event_callbacks[event_name]:
167 callback(*args)
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):
176 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'})
183 app = DebugWindow()
184 app.show()
185 gtk.main()