1 import gtk
, os
, gobject
, sys
4 from zeroinstall
.injector
.iface_cache
import iface_cache
5 from zeroinstall
.injector
.policy
import Policy
6 from zeroinstall
.injector
import download
, handler
7 from zeroinstall
.injector
.model
import SafeException
8 from zeroinstall
.injector
.reader
import InvalidInterface
9 from zeroinstall
.support
import tasks
11 from checking
import CheckingBox
18 gladefile
= os
.path
.join(os
.path
.dirname(__file__
), 'zero-install.glade')
20 # Wrapped for glade widget tree that throws a sensible exception if the widget isn't found
22 def __init__(self
, root
):
23 self
.widgets
= gtk
.glade
.XML(gladefile
, root
)
26 def get_widget(self
, name
= None):
29 widget
= self
.widgets
.get_widget(name
)
30 assert widget
, "Widget '%s' not found in glade file '%s'" % (name
, gladefile
)
33 class GUIHandler(handler
.Handler
):
34 monitored_downloads
= None
35 dl_callbacks
= None # Download -> [ callback ]
39 def __init__(self
, policy
):
40 handler
.Handler
.__init
__(self
)
43 def downloads_changed(self
):
44 if self
.monitored_downloads
and self
.pulse
is None:
46 if self
.policy
.checking
:
47 self
.policy
.checking
.progress
.pulse()
49 self
.policy
.window
.progress
.pulse()
51 self
.pulse
= gobject
.timeout_add(50, pulse
)
52 self
.policy
.window
.progress
.show()
53 elif len(self
.monitored_downloads
) == 0:
55 gobject
.source_remove(self
.pulse
)
56 self
.policy
.window
.progress
.hide()
59 if self
.policy
.checking
:
60 self
.policy
.checking
.updates_done(self
.policy
.versions_changed())
62 def confirm_trust_keys(self
, interface
, sigs
, iface_xml
):
64 return trust_box
.confirm_trust(interface
, sigs
, iface_xml
, parent
= self
.policy
.checking
or self
.policy
.window
.window
)
66 def report_error(self
, ex
):
67 dialog
.alert(None, str(ex
))
69 class GUIPolicy(Policy
):
71 checking
= None # GtkDialog ("Checking for updates...")
72 original_implementation
= None
74 widgets
= None # Glade
76 def __init__(self
, interface
, download_only
, refresh
, src
= False, restrictions
= None):
77 Policy
.__init
__(self
, interface
, GUIHandler(self
), src
= src
)
78 self
.solver
.record_details
= True
83 self
.widgets
= Template('main')
86 for r
in restrictions
:
87 self
.root_restrictions
.append(r
)
89 self
.download_only
= download_only
92 self
.window
= mainwindow
.MainWindow(download_only
)
93 root
= iface_cache
.get_interface(self
.root
)
94 self
.window
.browser
.set_root(root
)
97 # If we have feeds then treat this as a refresh,
98 # even if we've never seen the main interface before.
99 # Used the first time the GUI is used, for example.
100 if root
.name
is not None or root
.feeds
:
101 self
.checking
= CheckingBox(root
)
103 self
.refresh_all(force
= False)
105 self
.watchers
.append(self
.update_display
)
107 def show_details(self
):
108 """The checking box has disappeared. Should we show the details window, or
109 just run the program right now?"""
110 if self
.checking
.show_details
:
111 return True # User clicked on the Details button
113 return True # Not ready to start (can't find an implementation)
114 if self
.versions_changed():
115 return True # Confirm that the new version should be used
116 if self
.get_uncached_implementations():
117 return True # Need to download something; check first
120 def store_icon(self
, interface
, stream
):
121 Policy
.store_icon(self
, interface
, stream
)
123 self
.window
.browser
.build_tree()
125 def update_display(self
):
126 self
.window
.set_response_sensitive(gtk
.RESPONSE_OK
, self
.ready
)
129 solved
= tasks
.Task(self
.solve_with_downloads(), "solve")
134 yield solved
.finished
136 self
.checking
.updates_done(self
.versions_changed())
138 #dialog.wait_for_no_windows()
140 show_details
= self
.show_details()
146 raise Exception("STOP")
148 task
= tasks
.Task(policy
.download_impls(), "download implementations")
155 def abort_all_downloads(self
):
156 for dl
in self
.handler
.monitored_downloads
.values():
159 def set_original_implementations(self
):
160 assert self
.original_implementation
is None
161 self
.original_implementation
= policy
.implementation
.copy()
163 def versions_changed(self
):
164 """Return whether we have now chosen any different implementations.
165 If so, we want to show the dialog to the user to confirm the new ones."""
168 if not self
.original_implementation
:
169 return True # Shouldn't happen?
170 if len(self
.original_implementation
) != len(self
.implementation
):
172 for iface
in self
.original_implementation
:
173 old
= self
.original_implementation
[iface
]
176 new
= self
.implementation
.get(iface
, None)