Use freshness policy to auto-update.
[zeroinstall.git] / mainwindow.py
blob13b95af1492c39278e928441de010b108c87114d
1 import gtk
2 from iface_browser import InterfaceBrowser
3 import help_box
4 from gui import policy
5 from dialog import Dialog
6 from model import stable, testing, network_levels, SafeException
7 from freshness import freshness_levels, Freshness
9 class MainWindow(Dialog):
10 progress = None
11 browser = None
13 def __init__(self, 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 # Network use
21 hbox = gtk.HBox(False, 2)
22 self.vbox.pack_start(hbox, False, True, 0)
23 hbox.set_border_width(4)
25 network = gtk.combo_box_new_text()
26 for level in network_levels:
27 network.append_text(level.capitalize())
28 network.set_active(list(network_levels).index(policy.network_use))
29 hbox.pack_start(gtk.Label('Network use:'), False, True, 0)
30 hbox.pack_start(network, True, True, 2)
31 def set_network_use(combo):
32 policy.network_use = network_levels[network.get_active()]
33 policy.save_config()
34 policy.recalculate()
35 network.connect('changed', set_network_use)
37 hbox.show_all()
39 # Freshness
40 hbox = gtk.HBox(False, 2)
41 self.vbox.pack_start(hbox, False, True, 0)
42 hbox.set_border_width(4)
44 times = [x.time for x in freshness_levels]
45 if policy.freshness not in times:
46 index = len(freshness_levels)
47 freshness_levels.append(Freshness(policy.freshness,
48 '%d seconds' % policy.freshness))
49 times.append(policy.freshness)
50 freshness = gtk.combo_box_new_text()
51 for level in freshness_levels:
52 freshness.append_text(str(level))
53 freshness.set_active(times.index(policy.freshness))
54 hbox.pack_start(gtk.Label('Freshness:'), False, True, 0)
55 hbox.pack_start(freshness, True, True, 2)
56 def set_freshness(combo):
57 policy.freshness = freshness_levels[freshness.get_active()].time
58 policy.save_config()
59 policy.recalculate()
60 freshness.connect('changed', set_freshness)
62 button = gtk.Button('Refresh all now')
63 def refresh_all(b):
64 for x in policy.walk_interfaces():
65 policy.begin_iface_download(x, True)
66 button.connect('clicked', refresh_all)
67 hbox.pack_start(button, False, True, 2)
69 hbox.show_all()
71 # Tree view
72 self.browser = InterfaceBrowser()
73 self.vbox.pack_start(self.browser, True, True, 0)
74 self.browser.show()
76 # Select versions
77 hbox = gtk.HBox(False, 2)
78 self.vbox.pack_start(hbox, False, True, 0)
79 hbox.set_border_width(4)
81 button = gtk.Button()
82 self.browser.edit_properties.connect_proxy(button)
83 hbox.pack_start(button, False, True, 0)
85 stable_toggle = gtk.CheckButton('Help test new versions')
86 hbox.pack_start(stable_toggle, False, True, 0)
87 tips.set_tip(stable_toggle,
88 "Try out new versions as soon as they are available, instead of "
89 "waiting for them to be marked as 'stable'. "
90 "This sets the default policy. Click on 'Interface Properties...' "
91 "to set the policy for an individual interface.")
92 stable_toggle.set_active(policy.help_with_testing)
93 def toggle_stability(toggle):
94 policy.help_with_testing = toggle.get_active()
95 policy.save_config()
96 policy.recalculate()
97 stable_toggle.connect('toggled', toggle_stability)
99 hbox.show_all()
101 # Progress bar
102 self.progress = gtk.ProgressBar()
103 self.vbox.pack_start(self.progress, False, True, 0)
105 # Responses
107 self.add_button(gtk.STOCK_HELP, gtk.RESPONSE_HELP)
108 self.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)
109 self.add_button(gtk.STOCK_EXECUTE, gtk.RESPONSE_OK)
110 self.set_default_response(gtk.RESPONSE_OK)
112 def response(dialog, resp):
113 if resp == gtk.RESPONSE_CANCEL:
114 self.destroy()
115 elif resp == gtk.RESPONSE_OK:
116 import run
117 try:
118 run.execute(policy, prog, prog_args)
119 self.destroy()
120 except SafeException, ex:
121 box = gtk.MessageDialog(self, gtk.DIALOG_MODAL,
122 gtk.MESSAGE_ERROR, gtk.BUTTONS_OK,
123 str(ex))
124 box.run()
125 box.destroy()
126 elif resp == gtk.RESPONSE_HELP:
127 gui_help.display()
128 self.connect('response', response)
130 gui_help = help_box.HelpBox("Injector Help",
131 ('Overview', """
132 A program is made up of many different components, typically written by different \
133 groups of people. Each component is available in multiple versions. The injector is \
134 used when starting a program. Its job is to decide which implementation of each required \
135 component to use.
137 An interface describes what a component does. The injector starts with \
138 the interface for the program you want to run (like 'The Gimp') and chooses an \
139 implementation (like 'The Gimp 2.2.0'). However, this implementation \
140 will in turn depend on other interfaces, such as 'GTK' (which draws the menus \
141 and buttons). Thus, the injector must choose implementations of \
142 each dependancy (each of which may require further interfaces, and so on)."""),
144 ('List of interfaces', """
145 The main window displays all these interfaces, and the version of each chosen \
146 implementation. The top-most one represents the program you tried to run, and each direct \
147 child is a dependancy.
149 If you are happy with the choices shown, click on the Execute button to run the \
150 program."""),
152 ('Choosing different versions', """
153 There are three ways to control which implementations are chosen. You can adjust the \
154 network policy and the overall stability policy, which affect all interfaces, or you \
155 can edit the policy of individual interfaces.
157 The 'Network use' option controls how the injector uses the network. If off-line, \
158 the network is not used at all. If 'Minimal' is selected then the injector will use \
159 the network if needed, but only if it has no choice. It will run an out-of-date \
160 version rather than download a newer one. If 'Full' is selected, the injector won't \
161 worry about how much it downloads, but will always pick the version it thinks is best.
163 The overall stability policy can either be to prefer stable versions, or to help test \
164 new versions. Choose whichever suits you. Since different programmers have different \
165 ideas of what 'stable' means, you may wish to override this on a per-interface basis \
166 (see below).
168 To set the policy for an interface individually, select it and click on 'Interface \
169 Properties'. See that dialog's help text for more information."""))