Exemple #1
0
class Handler:

	def __init__(self, builder):
		self.queue = Queue.Queue()
		self.debugger = Engine(self.queue)
		self.debugger.start()
		self.builder = builder
		self.codeview = self.setup_codeview()
		self.watchesview = self.setup_watchesview()
		self.open_file = None
		glib.timeout_add(200, self.handle_queue)

	def delete_window(self, *args):
		print "Waiting for socket to close..."
		self.debugger.signal = 'kill'
		Gtk.main_quit(*args)

	def handle_queue(self):
		time.sleep(0.1) #doesn't work without it
		try:
			msg = self.queue.get_nowait()
		except Queue.Empty:
			msg = ''
		if (msg):
			if 'console' in msg:
				self.update_console(msg['console'])
			if 'stack' in msg:
				self.update_stack(msg['stack'])
			if 'code' in msg:
				self.update_codeview(msg['code'])
			if 'watchview' in msg:
				self.update_watchesview(msg['watchview'])

		self.update_buttons()
		self.set_status('Status: ' + str(self.debugger.status))
		return True

	def update_buttons(self):
		listen_button = self.builder.get_object("button_listen")
		status = self.debugger.status
		if (status == 'idle'):
			listen_button.set_sensitive(True)
			listen_button.set_label('Listen')
		elif (status == 'listening'):
			listen_button.set_sensitive(False)
			listen_button.set_label('Listening...')
		elif (status == 'running'):
			listen_button.set_sensitive(True)
			listen_button.set_label('Stop')



# BUTTONS ACTIONS

	def run(self, button):
		self.debugger.xrun()

	def step_over(self, button):
		self.debugger.step_over()

	def step_into(self, button):
		self.debugger.step_into()

	def listen(self, button):
		status = self.debugger.status
		if (status == 'idle'):
			self.debugger.signal = "listen"
		elif (status == 'listening'):
			self.debugger.signal = "stop=listening"
		elif (status == 'running'):
			self.debugger.signal = "stop"



# CONSOLE & STATUS

	def update_console(self, text):
		self.builder.get_object("console").get_buffer().set_text(text)

	def update_stack(self, text):
		s = text.replace('\x00', '')
		stack_iter = list(ElementTree.XML(s).iter())
		stack_str = ''
		for e in stack_iter:
			temp = e.get('filename')
			if temp:
				stack_str += temp + '\n'
		self.builder.get_object("stack").get_buffer().set_text(stack_str)

	def set_status(self, text):
		context_id = Gtk.Statusbar().get_context_id("Connection");
		self.builder.get_object("statusbar_main").push(context_id, text)

	def execute_command(self, widget, event):
		if (event.keyval ==	65293):
			r = self.debugger.execute(widget.get_text())
			self.update_console(r)



# WATCHES VIEW

	def add_watch(self, widget, event):
		if (event.keyval ==	65293):
			self.debugger.add_watch(widget.get_text())


	def setup_watchesview(self):
		v = self.builder.get_object("watches")
		renderer = Gtk.CellRendererText()
		v.append_column(Gtk.TreeViewColumn(None, renderer, text=0))
		return v


	def update_watchesview(self, watches):
		XMLNS = "urn:debugger_protocol_v1"
		elements = dict()
		for s in watches:
			xml_data = watches[s].replace('\x00', '')
			response_element = ElementTree.XML(xml_data)
			elements[s] = list(response_element).pop()

		store = Gtk.TreeStore(str)
		self.prepareStore(elements, None, store)
		self.watchesview.set_model(store)


	def prepareStore(self, elements, parent, store):
		for e in elements:
			if (type(elements) == type(dict())):
				tag = elements[e]
			else:
				tag = e

			tag_name = tag.get('name')
			if (tag_name == None):
				tag_name = e

			copy = ''
			if tag.text:
				if tag.get('encoding') == 'base64':
					copy = base64.b64decode(str(tag.text))
				else:
					copy = tag.text

			value_type = tag.get('type')
			new_parent = store.append(parent, [str(tag_name) + " (" + str(value_type) + "): " + str(copy)])
			if len(tag) > 0:
				self.prepareStore(tag, new_parent, store)



# CODEVIEW

	def setup_codeview(self):
		codeview = self.builder.get_object("treeview1")
		renderer = Gtk.CellRendererText()
		codeview.append_column(Gtk.TreeViewColumn(None, renderer, text=0, foreground=4, background=2))
		codeview.append_column(Gtk.TreeViewColumn(None, renderer, text=1, foreground=5, background=3))
		return codeview


	def update_codeview(self, response):
		(lineno, filename) = self.get_attributes(response)
		if self.load_sourcecode_file(filename[1]):
			self.codeview.get_selection().select_path(int(lineno[1]) - 1)
			self.codeview.scroll_to_cell((int(lineno[1]) - 1), None, False, 0.0, 0.0)

		self.update_console(response)


	def get_attributes(self, s):
		# neccessary for etree to work
		s = s.replace('\x00', '')

		element = ElementTree.XML(s)
		tag = element.iter()
		tag.next(); # <response></response>

		return tag.next().items()


	def load_sourcecode_file(self, filename):
		file_to_open = filename.replace('file://', '')
		if (self.open_file != file_to_open):
			store = Gtk.ListStore(int, str, str, str, str, str)
			try:
				f = open(file_to_open, 'r')
			except IOError:
				print "Couldn't open file!"
				return None
			self.open_file = file_to_open
			line_number = 1
			for line in f:
				store.append([
					line_number,
					line.replace('\n', ''),
					"#eeeeee",
					"#ffffff",
					"#bbbbbb",
					"#333333"
				])
				line_number += 1
			f.close()
			self.codeview.set_model(store)

		return file_to_open