Nicer error reporting if interface is missing.
[zeroinstall.git] / gui.py
blobdafcb4bb8f9013ed527788282ffdacc12faa1135
1 import gtk
2 from iface_browser import InterfaceBrowser
3 import help_box
4 from dialog import Dialog
5 from policy import policy
6 from model import stable, testing, network_levels, SafeException
8 gtk.rc_parse_string('style "scrolled" { '
9 'GtkScrolledWindow::scrollbar-spacing = 0}\n'
10 'class "GtkScrolledWindow" style : gtk "scrolled"\n')
12 class MainWindow(Dialog):
13 def __init__(self, root_interface, prog, prog_args):
14 Dialog.__init__(self)
15 self.set_title('Dependency Injector')
16 self.set_default_size(400, 300)
18 tips = gtk.Tooltips()
20 # Message
21 label = gtk.Label('Need to download interface definitions...')
22 self.vbox.pack_start(label, False, True, 0)
23 label.set_padding(8, 8)
24 label.show()
26 # Network use
27 hbox = gtk.HBox(False, 2)
28 self.vbox.pack_start(hbox, False, True, 0)
29 hbox.set_border_width(4)
31 network = gtk.combo_box_new_text()
32 for level in network_levels:
33 network.append_text(level.capitalize())
34 network.set_active(list(network_levels).index(policy.network_use))
35 hbox.pack_start(gtk.Label('Network use:'), False, True, 0)
36 hbox.pack_start(network, False, True, 2)
37 def set_network_use(combo):
38 policy.network_use = network_levels[network.get_active()]
39 policy.save_config()
40 policy.recalculate()
41 network.connect('changed', set_network_use)
43 hbox.show_all()
45 # Tree view
46 browser = InterfaceBrowser(root_interface)
47 self.vbox.pack_start(browser, True, True, 0)
48 browser.show()
50 # Select versions
51 hbox = gtk.HBox(False, 2)
52 self.vbox.pack_start(hbox, False, True, 0)
53 hbox.set_border_width(4)
55 button = gtk.Button()
56 browser.edit_properties.connect_proxy(button)
57 hbox.pack_start(button, False, True, 0)
59 stable_toggle = gtk.CheckButton('Help test new versions')
60 hbox.pack_start(stable_toggle, False, True, 0)
61 tips.set_tip(stable_toggle,
62 "Try out new versions as soon as they are available, instead of "
63 "waiting for them to be marked as 'stable'. "
64 "This sets the default policy. Click on 'Interface Properties...' "
65 "to set the policy for an individual interface.")
66 stable_toggle.set_active(policy.help_with_testing)
67 def toggle_stability(toggle):
68 policy.help_with_testing = toggle.get_active()
69 policy.save_config()
70 policy.recalculate()
71 stable_toggle.connect('toggled', toggle_stability)
73 hbox.show_all()
75 # Responses
77 self.add_button(gtk.STOCK_HELP, gtk.RESPONSE_HELP)
78 self.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)
79 self.add_button(gtk.STOCK_EXECUTE, gtk.RESPONSE_OK)
80 self.set_default_response(gtk.RESPONSE_OK)
82 def response(dialog, resp):
83 if resp == gtk.RESPONSE_CANCEL:
84 self.destroy()
85 elif resp == gtk.RESPONSE_OK:
86 import run
87 try:
88 run.execute(root_interface, prog, prog_args)
89 self.destroy()
90 except SafeException, ex:
91 box = gtk.MessageDialog(self, gtk.DIALOG_MODAL,
92 gtk.MESSAGE_ERROR, gtk.BUTTONS_OK,
93 str(ex))
94 box.run()
95 box.destroy()
96 elif resp == gtk.RESPONSE_HELP:
97 gui_help.display()
98 self.connect('response', response)
100 gui_help = help_box.HelpBox("Injector Help",
101 ('Overview', """
102 A program is made up of many different components, typically written by different \
103 groups of people. Each component is available in multiple versions. The injector is \
104 used when starting a program. Its job is to decide which implementation of each required \
105 component to use.
107 An interface describes what a component does. The injector starts with \
108 the interface for the program you want to run (like 'The Gimp') and chooses an \
109 implementation (like 'The Gimp 2.2.0'). However, this implementation \
110 will in turn depend on other interfaces, such as 'GTK' (which draws the menus \
111 and buttons). Thus, the injector must choose implementations of \
112 each dependancy (each of which may require further interfaces, and so on)."""),
114 ('List of interfaces', """
115 The main window displays all these interfaces, and the version of each chosen \
116 implementation. The top-most one represents the program you tried to run, and each direct \
117 child is a dependancy.
119 If you are happy with the choices shown, click on the Execute button to run the \
120 program."""),
122 ('Choosing different versions', """
123 There are three ways to control which implementations are chosen. You can adjust the \
124 network policy and the overall stability policy, which affect all interfaces, or you \
125 can edit the policy of individual interfaces.
127 The 'Network use' option controls how the injector uses the network. If off-line, \
128 the network is not used at all. If 'Minimal' is selected then the injector will use \
129 the network if needed, but only if it has no choice. It will run an out-of-date \
130 version rather than download a newer one. If 'Full' is selected, the injector won't \
131 worry about how much it downloads, but will always pick the version it thinks is best.
133 The overall stability policy can either be to prefer stable versions, or to help test \
134 new versions. Choose whichever suits you. Since different programmers have different \
135 ideas of what 'stable' means, you may wish to override this on a per-interface basis \
136 (see below).
138 To set the policy for an interface individually, select it and click on 'Interface \
139 Properties'. See that dialog's help text for more information."""))