Holding the pointer over an interface in the main window shows a tooltip
[zeroinstall.git] / download_box.py
blob14ed17d81423e4cfdb4b5e9ec6a7d1a435d9e117
1 import gtk
2 import os
4 from zeroinstall.injector.model import SafeException
5 from zeroinstall.injector import download, run
6 from gui import policy, pretty_size
7 from dialog import Dialog
9 import warnings
10 warnings.filterwarnings('ignore', category = DeprecationWarning, module='download_box')
12 def download_with_gui(mainwindow, prog_args, run_afterwards):
13 """If all downloads are ready, runs the program. Otherwise,
14 hides mainwindow, shows the download progress box and then runs
15 it. On error, mainwindow is re-shown."""
16 downloads = []
17 for iface, impl in policy.get_uncached_implementations():
18 if not impl.download_sources:
19 raise SafeException("Implementation " + impl.id + " of "
20 "interface " + iface.get_name() + " cannot be "
21 "downloaded (no download locations given in "
22 "interface!")
23 dl = download.begin_impl_download(policy.get_best_source(impl),
24 force = True)
25 downloads.append((iface, dl))
26 def run_it():
27 policy.abort_all_downloads()
28 if not run_afterwards:
29 mainwindow.destroy()
30 return
31 try:
32 run.execute(policy, prog_args)
33 mainwindow.destroy()
34 except SafeException, ex:
35 box = gtk.MessageDialog(None, gtk.DIALOG_MODAL,
36 gtk.MESSAGE_ERROR, gtk.BUTTONS_OK,
37 str(ex))
38 box.run()
39 box.destroy()
40 mainwindow.show()
41 if downloads:
42 DownloadProgessBox(run_it, downloads, mainwindow).show()
43 else:
44 run_it()
46 class DownloadProgessBox(Dialog):
47 mainwindow = None
48 run_it = None
49 n_downloads = None
50 idle_timeout = None
51 errors = False
53 def __init__(self, run_it, downloads, mainwindow):
54 Dialog.__init__(self)
55 self.set_title('Downloading, please wait...')
56 self.mainwindow = mainwindow
57 self.run_it = run_it
58 self.n_downloads = 0
60 self.add_button(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)
62 table = gtk.Table(len(downloads) + 1, 3)
63 self.vbox.pack_start(table, False, False, 0)
64 table.set_row_spacings(4)
65 table.set_col_spacings(10)
66 table.set_border_width(10)
68 bars = []
70 row = 0
71 for iface, dl in downloads:
72 bar = gtk.ProgressBar()
73 bars.append((dl, bar))
74 table.attach(gtk.Label(iface.get_name()),
75 0, 1, row, row + 1)
76 table.attach(gtk.Label(pretty_size(dl.source.size)),
77 1, 2, row, row + 1)
78 table.attach(bar, 2, 3, row, row + 1)
79 row += 1
80 self.start_download(dl)
82 mainwindow.hide()
83 self.vbox.show_all()
85 def resp(box, resp):
86 for iface, dl in downloads:
87 dl.abort()
88 gtk.timeout_remove(self.idle_timeout)
89 self.idle_timeout = None
90 self.destroy()
91 mainwindow.show()
92 policy.recalculate()
93 self.connect('response', resp)
95 def update_bars():
96 if self.n_downloads == 0:
97 if not self.errors:
98 self.destroy()
99 self.run_it()
100 return False
101 for dl, bar in bars:
102 perc = dl.get_current_fraction()
103 bar.set_fraction(perc)
104 return True
106 self.idle_timeout = gtk.timeout_add(250, update_bars)
108 def start_download(self, dl):
109 error_stream = dl.start()
110 def error_ready(src, cond):
111 got = os.read(src.fileno(), 100)
112 if not got:
113 error_stream.close()
114 self.n_downloads -= 1
115 try:
116 data = dl.error_stream_closed()
117 policy.add_to_cache(dl.source, data)
118 except Exception, ex:
119 label = gtk.Label("Error getting '%s':\n%s" % (dl.url, ex))
120 label.set_padding(4, 4)
121 self.vbox.pack_start(label, False, True, 2)
122 label.show()
123 self.errors = True
124 return False
125 return False
126 dl.error_stream_data(got)
127 return True
129 self.n_downloads += 1
130 gtk.input_add(error_stream, gtk.gdk.INPUT_READ, error_ready)