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