Removed GUI object.
[zeroinstall.git] / zeroinstall / 0launch-gui / mainwindow.py
blob634ccfc005cbbff554556184ffb8dd51d21cf448
1 import gtk
2 from logging import warn
3 import os, sys
4 from zeroinstall import SafeException
5 from zeroinstall.support import tasks
6 from iface_browser import InterfaceBrowser
7 import help_box
8 import dialog
10 tips = gtk.Tooltips()
12 SHOW_PREFERENCES = 0
14 class MainWindow:
15 progress = None
16 browser = None
17 window = None
18 cancel_download_and_run = None
20 def __init__(self, policy, widgets, download_only):
21 policy.watchers.append(lambda: self.window.set_response_sensitive(gtk.RESPONSE_OK, policy.solver.ready))
23 self.window = widgets.get_widget('main')
24 self.window.set_default_size(gtk.gdk.screen_width() * 2 / 5, 300)
26 self.progress = widgets.get_widget('progress')
28 cache = widgets.get_widget('show_cache')
29 cache.connect('clicked',
30 lambda b: os.spawnlp(os.P_WAIT, sys.argv[0], sys.argv[0], '-c'))
32 widgets.get_widget('refresh').connect('clicked', lambda b: policy.refresh_all())
34 # Tree view
35 self.browser = InterfaceBrowser(policy, widgets)
37 prefs = widgets.get_widget('preferences')
38 self.window.action_area.set_child_secondary(prefs, True)
40 # Glade won't let me add this to the template!
41 if download_only:
42 run_button = dialog.MixedButton("_Download", gtk.STOCK_EXECUTE, button = gtk.ToggleButton())
43 else:
44 run_button = dialog.MixedButton("_Run", gtk.STOCK_EXECUTE, button = gtk.ToggleButton())
45 self.window.add_action_widget(run_button, gtk.RESPONSE_OK)
46 run_button.show_all()
47 run_button.set_flags(gtk.CAN_DEFAULT)
49 self.window.set_default_response(gtk.RESPONSE_OK)
50 self.window.default_widget.grab_focus()
52 def response(dialog, resp):
53 if resp in (gtk.RESPONSE_CANCEL, gtk.RESPONSE_DELETE_EVENT):
54 self.window.destroy()
55 sys.exit(1)
56 elif resp == gtk.RESPONSE_OK:
57 if self.cancel_download_and_run:
58 self.cancel_download_and_run.trigger()
59 if run_button.get_active():
60 self.cancel_download_and_run = tasks.Blocker("cancel downloads")
61 self.download_and_run(run_button, self.cancel_download_and_run)
62 elif resp == gtk.RESPONSE_HELP:
63 gui_help.display()
64 elif resp == SHOW_PREFERENCES:
65 import preferences
66 preferences.show_preferences(policy)
67 self.window.connect('response', response)
69 def destroy(self):
70 self.window.destroy()
72 def show(self):
73 self.window.show()
75 def set_response_sensitive(self, response, sensitive):
76 self.window.set_response_sensitive(response, sensitive)
78 @tasks.async
79 def download_and_run(self, run_button, cancelled):
80 try:
81 downloaded = policy.download_uncached_implementations()
83 if downloaded:
84 # We need to wait until everything is downloaded...
85 blockers = [downloaded, cancelled]
86 yield blockers
87 tasks.check(blockers)
89 if cancelled.happened:
90 policy.abort_all_downloads()
91 return
93 if self.policy.get_uncached_implementations():
94 dialog.alert('Not all downloads succeeded; cannot run program.')
95 else:
96 from zeroinstall.injector import selections
97 sels = selections.Selections(policy)
98 doc = sels.toDOM()
99 reply = doc.toxml('utf-8')
100 sys.stdout.write(('Length:%8x\n' % len(reply)) + reply)
101 self.window.destroy()
102 sys.exit(0) # Success
103 except SafeException, ex:
104 run_button.set_active(False)
105 policy.handler.report_error(ex)
106 except Exception, ex:
107 run_button.set_active(False)
108 import traceback
109 traceback.print_exc()
110 policy.handler.report_error(ex)
112 gui_help = help_box.HelpBox("Injector Help",
113 ('Overview', """
114 A program is made up of many different components, typically written by different \
115 groups of people. Each component is available in multiple versions. The injector is \
116 used when starting a program. Its job is to decide which implementation of each required \
117 component to use.
119 An interface describes what a component does. The injector starts with \
120 the interface for the program you want to run (like 'The Gimp') and chooses an \
121 implementation (like 'The Gimp 2.2.0'). However, this implementation \
122 will in turn depend on other interfaces, such as 'GTK' (which draws the menus \
123 and buttons). Thus, the injector must choose implementations of \
124 each dependency (each of which may require further interfaces, and so on)."""),
126 ('List of interfaces', """
127 The main window displays all these interfaces, and the version of each chosen \
128 implementation. The top-most one represents the program you tried to run, and each direct \
129 child is a dependency. The 'Fetch' column shows the amount of data that needs to be \
130 downloaded, or '(cached)' if it is already on this computer.
132 If you are happy with the choices shown, click on the Download (or Run) button to \
133 download (and run) the program."""),
135 ('Choosing different versions', """
136 To control which implementations (versions) are chosen you can click on Preferences \
137 and adjust the network policy and the overall stability policy. These settings affect \
138 all programs run using Zero Install.
140 Alternatively, you can edit the policy of an individual interface by selecting it \
141 and clicking on the 'Interface Properties' button. \
142 See that dialog's help text for more information.
144 Right-click on an interface in the list for a menu.
145 """),
147 ('Reporting bugs', """
148 To report a bug, right-click over the interface which you think contains the problem \
149 and choose 'Report a Bug...' from the menu. If you don't know which one is the cause, \
150 choose the top one (i.e. the program itself). The program's author can reassign the \
151 bug if necessary, or switch to using a different version of the library.
152 """),
154 ('The cache', """
155 Each version of a program that is downloaded is stored in the Zero Install cache. This \
156 means that it won't need to be downloaded again each time you run the program. Click on \
157 the 'Show Cache' button to see what is currently in the cache, or to remove versions \
158 you no longer need to save disk space."""),