<commit_before>import gtk, os, gobject, sys
import gtk.glade

from zeroinstall.injector.iface_cache import iface_cache
from zeroinstall.injector.policy import Policy
from zeroinstall.injector import download, handler
from zeroinstall.injector.model import SafeException
from zeroinstall.injector.reader import InvalidInterface
from zeroinstall.support import tasks
import dialog
from checking import CheckingBox

version = '0.31'

# Singleton Policy
policy = None

gladefile = os.path.join(os.path.dirname(__file__), 'zero-install.glade')

# Wrapped for glade widget tree that throws a sensible exception if the widget isn't found
class Template:
	def __init__(self, root):
		self.widgets = gtk.glade.XML(gladefile, root)
		self.root = root
	
	def get_widget(self, name = None):
		if not name:
			name = self.root
		widget = self.widgets.get_widget(name)
		assert widget, "Widget '%s' not found in glade file '%s'" % (name, gladefile)
		return widget

class GUIHandler(handler.Handler):
	dl_callbacks = None		# Download -> [ callback ]
	pulse = None
	policy = None

	def __init__(self, policy):
		handler.Handler.__init__(self)
		self.policy = policy

	def downloads_changed(self):
		if self.monitored_downloads and self.pulse is None:
			def pulse():
				if self.policy.checking:
					self.policy.checking.progress.pulse()
				else:
					self.policy.window.progress.pulse()
				return True
			self.pulse = gobject.timeout_add(50, pulse)
			self.policy.window.progress.show()
		elif len(self.monitored_downloads) == 0:
			if self.pulse:
				gobject.source_remove(self.pulse)
				self.policy.window.progress.hide()
				self.pulse = None
				
			if self.policy.checking:
				self.policy.checking.updates_done(self.policy.versions_changed())

	def confirm_trust_keys(self, interface, sigs, iface_xml):
		import trust_box
		return trust_box.confirm_trust(interface, sigs, iface_xml, parent = self.policy.checking or self.policy.window.window)
	
	def report_error(self, ex):
		dialog.alert(None, str(ex))

class GUIPolicy(Policy):
	window = None
	checking = None		# GtkDialog ("Checking for updates...")
	original_implementation = None
	download_only = None
	widgets = None		# Glade

	def __init__(self, interface, download_only, refresh, src = False, restrictions = None):
		Policy.__init__(self, interface, GUIHandler(self), src = src)
		self.solver.record_details = True
		global policy
		assert policy is None
		policy = self

		self.widgets = Template('main')

		if restrictions:
			for r in restrictions:
				self.root_restrictions.append(r)

		self.download_only = download_only

		import mainwindow
		self.window = mainwindow.MainWindow(download_only)
		root = iface_cache.get_interface(self.root)
		self.window.browser.set_root(root)

		if refresh:
			# If we have feeds then treat this as a refresh,
			# even if we've never seen the main interface before.
			# Used the first time the GUI is used, for example.
			if root.name is not None or root.feeds:
				self.checking = CheckingBox(root)

			self.refresh_all(force = False)

		self.watchers.append(self.update_display)
	
	def show_details(self):
		"""The checking box has disappeared. Should we show the details window, or
		just run the program right now?"""
		if self.checking.show_details_clicked.happened:
			return True		# User clicked on the Details button
		if not self.ready:
			return True		# Not ready to start (can't find an implementation)
		if self.versions_changed():
			return True		# Confirm that the new version should be used
		if self.get_uncached_implementations():
			return True		# Need to download something; check first
		return False

	def store_icon(self, interface, stream):
		Policy.store_icon(self, interface, stream)
		if self.window:
			self.window.browser.build_tree()
	
	def update_display(self):
		self.window.set_response_sensitive(gtk.RESPONSE_OK, self.ready)

	def main(self):
		solved = tasks.Task(self.solve_with_downloads(), "solve")

		if self.checking:
			self.checking.show()

			error = None
			blockers = [solved.finished, self.checking.show_details_clicked, self.checking.cancelled]
			yield blockers
			try:
				tasks.check(blockers)
			except Exception, ex:
				error = ex

			self.checking.updates_done(self.versions_changed())

			show_details = self.show_details() or error
			self.checking = None
			if show_details:
				self.window.show()
				if error:
					dialog.alert(self.window.window, "Failed to check for updates: %s" % ex)
				yield []
			else:
				from zeroinstall.injector import selections
				sels = selections.Selections(policy)
				doc = sels.toDOM()
				reply = doc.toxml('utf-8')
				sys.stdout.write(('Length:%8x\n' % len(reply)) + reply)
				self.window.destroy()
				sys.exit(0)			# Success
		else:
			self.window.show()
			yield []
	
	def abort_all_downloads(self):
		for dl in self.handler.monitored_downloads.values():
			dl.abort()
	
	def set_original_implementations(self):
		assert self.original_implementation is None
		self.original_implementation = policy.implementation.copy()

	def versions_changed(self):
		"""Return whether we have now chosen any different implementations.
		If so, we want to show the dialog to the user to confirm the new ones."""
		if not self.ready:
			return True
		if not self.original_implementation:
			return True		# Shouldn't happen?
		if len(self.original_implementation) != len(self.implementation):
			return True
		for iface in self.original_implementation:
			old = self.original_implementation[iface]
			if old is None:<commit_msg>Better exception handling in GUI.<commit_after>import gtk, os, gobject, sys
import gtk.glade

from zeroinstall.injector.iface_cache import iface_cache
from zeroinstall.injector.policy import Policy
from zeroinstall.injector import download, handler
from zeroinstall.injector.model import SafeException
from zeroinstall.injector.reader import InvalidInterface
from zeroinstall.support import tasks
import dialog
from checking import CheckingBox

version = '0.31'

# Singleton Policy
policy = None

gladefile = os.path.join(os.path.dirname(__file__), 'zero-install.glade')

# Wrapped for glade widget tree that throws a sensible exception if the widget isn't found
class Template:
	def __init__(self, root):
		self.widgets = gtk.glade.XML(gladefile, root)
		self.root = root
	
	def get_widget(self, name = None):
		if not name:
			name = self.root
		widget = self.widgets.get_widget(name)
		assert widget, "Widget '%s' not found in glade file '%s'" % (name, gladefile)
		return widget

class GUIHandler(handler.Handler):
	dl_callbacks = None		# Download -> [ callback ]
	pulse = None
	policy = None

	def __init__(self, policy):
		handler.Handler.__init__(self)
		self.policy = policy

	def downloads_changed(self):
		if self.monitored_downloads and self.pulse is None:
			def pulse():
				if self.policy.checking:
					self.policy.checking.progress.pulse()
				else:
					self.policy.window.progress.pulse()
				return True
			self.pulse = gobject.timeout_add(50, pulse)
			self.policy.window.progress.show()
		elif len(self.monitored_downloads) == 0:
			if self.pulse:
				gobject.source_remove(self.pulse)
				self.policy.window.progress.hide()
				self.pulse = None
				
			if self.policy.checking:
				self.policy.checking.updates_done(self.policy.versions_changed())

	def confirm_trust_keys(self, interface, sigs, iface_xml):
		import trust_box
		return trust_box.confirm_trust(interface, sigs, iface_xml, parent = self.policy.checking or self.policy.window.window)
	
	def report_error(self, ex):
		dialog.alert(None, str(ex))

class GUIPolicy(Policy):
	window = None
	checking = None		# GtkDialog ("Checking for updates...")
	original_implementation = None
	download_only = None
	widgets = None		# Glade

	def __init__(self, interface, download_only, refresh, src = False, restrictions = None):
		Policy.__init__(self, interface, GUIHandler(self), src = src)
		self.solver.record_details = True
		global policy
		assert policy is None
		policy = self

		self.widgets = Template('main')

		if restrictions:
			for r in restrictions:
				self.root_restrictions.append(r)

		self.download_only = download_only

		import mainwindow
		self.window = mainwindow.MainWindow(download_only)
		root = iface_cache.get_interface(self.root)
		self.window.browser.set_root(root)

		if refresh:
			# If we have feeds then treat this as a refresh,
			# even if we've never seen the main interface before.
			# Used the first time the GUI is used, for example.
			if root.name is not None or root.feeds:
				self.checking = CheckingBox(root)

			self.refresh_all(force = False)

		self.watchers.append(self.update_display)
	
	def show_details(self):
		"""The checking box has disappeared. Should we show the details window, or
		just run the program right now?"""
		if self.checking.show_details_clicked.happened:
			return True		# User clicked on the Details button
		if not self.ready:
			return True		# Not ready to start (can't find an implementation)
		if self.versions_changed():
			return True		# Confirm that the new version should be used
		if self.get_uncached_implementations():
			return True		# Need to download something; check first
		return False

	def store_icon(self, interface, stream):
		Policy.store_icon(self, interface, stream)
		if self.window:
			self.window.browser.build_tree()
	
	def update_display(self):
		self.window.set_response_sensitive(gtk.RESPONSE_OK, self.ready)

	def main(self):
		solved = tasks.Task(self.solve_with_downloads(), "solve_with_downloads")

		if self.checking:
			self.checking.show()

			error = None
			blockers = [solved.finished, self.checking.show_details_clicked, self.checking.cancelled]
			yield blockers
			try:
				tasks.check(blockers)
			except Exception, ex:
				error = ex

			self.checking.updates_done(self.versions_changed())

			show_details = self.show_details() or error
			self.checking = None
			if show_details:
				self.window.show()
				if error:
					dialog.alert(self.window.window, "Failed to check for updates: %s" % ex)
				yield []
			else:
				from zeroinstall.injector import selections
				sels = selections.Selections(policy)
				doc = sels.toDOM()
				reply = doc.toxml('utf-8')
				sys.stdout.write(('Length:%8x\n' % len(reply)) + reply)
				self.window.destroy()
				sys.exit(0)			# Success
		else:
			self.window.show()
			yield solved.finished
			try:
				tasks.check(solved.finished)
			except Exception, ex:
				import traceback
				traceback.print_exc()
				dialog.alert(self.window.window, str(ex))
			yield []
	
	def abort_all_downloads(self):
		for dl in self.handler.monitored_downloads.values():
			dl.abort()
	
	def set_original_implementations(self):
		assert self.original_implementation is None
		self.original_implementation = policy.implementation.copy()

	def versions_changed(self):
		"""Return whether we have now chosen any different implementations.
		If so, we want to show the dialog to the user to confirm the new ones."""
		if not self.ready:
			return True
		if not self.original_implementation:
			return True		# Shouldn't happen?
		if len(self.original_implementation) != len(self.implementation):
			return True
		for iface in self.original_implementation:
			old = self.original_implementation[iface]
			if old is None:
{'fraction_non_alphanumeric': 0.09557711132864644, 'fraction_numerical': 0.0016018510278544096, 'mean_word_length': 4.039461883408071, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 6}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 29, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2738598', 'n_tokens_mistral': 4049, 'n_tokens_neox': 3447, 'n_words': 979}