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 dl_callbacks
= None # Download -> [ callback ]
38 def __init__(self
, policy
):
39 handler
.Handler
.__init
__(self
)
42 def downloads_changed(self
):
43 if self
.monitored_downloads
and self
.pulse
is None:
45 if self
.policy
.checking
:
46 self
.policy
.checking
.progress
.pulse()
48 self
.policy
.window
.progress
.pulse()
50 self
.pulse
= gobject
.timeout_add(50, pulse
)
51 self
.policy
.window
.progress
.show()
52 elif len(self
.monitored_downloads
) == 0:
54 gobject
.source_remove(self
.pulse
)
55 self
.policy
.window
.progress
.hide()
58 if self
.policy
.checking
:
59 self
.policy
.checking
.updates_done(self
.policy
.versions_changed())
61 def confirm_trust_keys(self
, interface
, sigs
, iface_xml
):
63 return trust_box
.confirm_trust(interface
, sigs
, iface_xml
, parent
= self
.policy
.checking
or self
.policy
.window
.window
)
65 def report_error(self
, ex
):
66 dialog
.alert(None, str(ex
))
68 class GUIPolicy(Policy
):
70 checking
= None # GtkDialog ("Checking for updates...")
71 original_implementation
= None
73 widgets
= None # Glade
75 def __init__(self
, interface
, download_only
, refresh
, src
= False, restrictions
= None):
76 Policy
.__init
__(self
, interface
, GUIHandler(self
), src
= src
)
77 self
.solver
.record_details
= True
82 self
.widgets
= Template('main')
85 for r
in restrictions
:
86 self
.root_restrictions
.append(r
)
88 self
.download_only
= download_only
91 self
.window
= mainwindow
.MainWindow(download_only
)
92 root
= iface_cache
.get_interface(self
.root
)
93 self
.window
.browser
.set_root(root
)
96 # If we have feeds then treat this as a refresh,
97 # even if we've never seen the main interface before.
98 # Used the first time the GUI is used, for example.
99 if root
.name
is not None or root
.feeds
:
100 self
.checking
= CheckingBox(root
)
102 self
.refresh_all(force
= False)
104 self
.watchers
.append(self
.update_display
)
106 def show_details(self
):
107 """The checking box has disappeared. Should we show the details window, or
108 just run the program right now?"""
109 if self
.checking
.show_details
:
110 return True # User clicked on the Details button
112 return True # Not ready to start (can't find an implementation)
113 if self
.versions_changed():
114 return True # Confirm that the new version should be used
115 if self
.get_uncached_implementations():
116 return True # Need to download something; check first
119 def store_icon(self
, interface
, stream
):
120 Policy
.store_icon(self
, interface
, stream
)
122 self
.window
.browser
.build_tree()
124 def update_display(self
):
125 self
.window
.set_response_sensitive(gtk
.RESPONSE_OK
, self
.ready
)
128 solved
= tasks
.Task(self
.solve_with_downloads(), "solve")
133 yield solved
.finished
# TODO: Show Details
134 tasks
.check(solved
.finished
)
136 self
.checking
.updates_done(self
.versions_changed())
138 #dialog.wait_for_no_windows()
140 show_details
= self
.show_details()
146 from zeroinstall
.injector
import selections
147 sels
= selections
.Selections(policy
)
149 reply
= doc
.toxml('utf-8')
150 sys
.stdout
.write(('Length:%8x\n' % len(reply
)) + reply
)
151 self
.window
.destroy()
152 sys
.exit(0) # Success
157 def abort_all_downloads(self
):
158 for dl
in self
.handler
.monitored_downloads
.values():
161 def set_original_implementations(self
):
162 assert self
.original_implementation
is None
163 self
.original_implementation
= policy
.implementation
.copy()
165 def versions_changed(self
):
166 """Return whether we have now chosen any different implementations.
167 If so, we want to show the dialog to the user to confirm the new ones."""
170 if not self
.original_implementation
:
171 return True # Shouldn't happen?
172 if len(self
.original_implementation
) != len(self
.implementation
):
174 for iface
in self
.original_implementation
:
175 old
= self
.original_implementation
[iface
]
178 new
= self
.implementation
.get(iface
, None)