1 # Copyright (C) 2009, Thomas Leonard
2 # See the README file for details, or visit http://0install.net.
4 import gtk
, gobject
, os
5 from zeroinstall
.injector
import model
, writer
6 from zeroinstall
import support
7 from zeroinstall
.gtkui
.treetips
import TreeTips
10 def _build_stability_menu(policy
, impl
):
13 upstream
= impl
.upstream_stability
or model
.testing
14 choices
= model
.stability_levels
.values()
19 if isinstance(new
, model
.Stability
):
20 impl
.user_stability
= new
22 impl
.user_stability
= None
23 writer
.save_feed(impl
.feed
)
26 item
= gtk
.MenuItem('Unset (%s)' % upstream
)
27 item
.connect('activate', lambda item
: set(None))
31 item
= gtk
.SeparatorMenuItem()
36 item
= gtk
.MenuItem(str(value
).capitalize())
37 item
.connect('activate', lambda item
, v
= value
: set(v
))
43 rox_filer
= 'http://rox.sourceforge.net/2005/interfaces/ROX-Filer'
55 class ImplTips(TreeTips
):
56 def __init__(self
, policy
, interface
):
58 self
.interface
= interface
60 def get_tooltip_text(self
):
62 if impl
.id.startswith('/'):
63 return _("Local: %s") % impl
.id
64 if impl
.id.startswith('package:'):
65 return _("Native package: %s") % impl
.id.split(':', 1)[1]
66 if self
.policy
.get_cached(impl
):
67 return _("Cached: %s") % self
.policy
.get_implementation_path(impl
)
69 src
= self
.policy
.fetcher
.get_best_source(impl
)
71 size
= support
.pretty_size(src
.size
)
72 return _("Not yet downloaded (%s)") % size
74 return _("No downloads available!")
76 class ImplementationList
:
82 def __init__(self
, policy
, interface
, widgets
):
83 self
.interface
= interface
86 self
.model
= gtk
.ListStore(object, str, str, str, # Item, arch, stability, version,
87 str, gobject
.TYPE_BOOLEAN
, str, str) # fetch, unusable, released, notes
89 self
.tree_view
= widgets
.get_widget('versions_list')
90 self
.tree_view
.set_model(self
.model
)
92 text
= gtk
.CellRendererText()
93 text_strike
= gtk
.CellRendererText()
95 stability
= gtk
.TreeViewColumn(_('Stability'), text
, text
= STABILITY
)
97 for column
in (gtk
.TreeViewColumn(_('Version'), text_strike
, text
= VERSION
, strikethrough
= UNUSABLE
),
98 gtk
.TreeViewColumn(_('Released'), text
, text
= RELEASED
),
100 gtk
.TreeViewColumn(_('Fetch'), text
, text
= FETCH
),
101 gtk
.TreeViewColumn(_('Arch'), text_strike
, text
= ARCH
, strikethrough
= UNUSABLE
),
102 gtk
.TreeViewColumn(_('Notes'), text
, text
= NOTES
)):
103 self
.tree_view
.append_column(column
)
105 tips
= ImplTips(policy
, interface
)
107 def motion(tree_view
, ev
):
108 if ev
.window
is not tree_view
.get_bin_window():
110 pos
= tree_view
.get_path_at_pos(int(ev
.x
), int(ev
.y
))
113 row
= self
.model
[path
]
114 if row
[ITEM
] is not tips
.item
:
115 tips
.prime(tree_view
, row
[ITEM
])
119 self
.tree_view
.connect('motion-notify-event', motion
)
120 self
.tree_view
.connect('leave-notify-event', lambda tv
, ev
: tips
.hide())
121 self
.tree_view
.connect('destroy', lambda tv
: tips
.hide())
123 def button_press(tree_view
, bev
):
124 if bev
.button
not in (1, 3):
126 pos
= tree_view
.get_path_at_pos(int(bev
.x
), int(bev
.y
))
129 path
, col
, x
, y
= pos
130 impl
= self
.model
[path
][ITEM
]
134 stability_menu
= gtk
.MenuItem('Rating')
135 stability_menu
.set_submenu(_build_stability_menu(self
.policy
, impl
))
136 stability_menu
.show()
137 menu
.append(stability_menu
)
139 if self
.policy
.get_cached(impl
):
141 os
.spawnlp(os
.P_WAIT
, '0launch',
142 '0launch', rox_filer
, '-d',
143 self
.policy
.get_implementation_path(impl
))
144 item
= gtk
.MenuItem('Open cached copy')
145 item
.connect('activate', lambda item
: open())
149 menu
.popup(None, None, None, bev
.button
, bev
.time
)
151 self
.tree_view
.connect('button-press-event', button_press
)
153 def get_selection(self
):
154 return self
.tree_view
.get_selection()
156 def set_items(self
, items
):
158 for item
, unusable
in items
:
159 new
= self
.model
.append()
160 self
.model
[new
][ITEM
] = item
161 self
.model
[new
][VERSION
] = item
.get_version()
162 self
.model
[new
][RELEASED
] = item
.released
or "-"
163 self
.model
[new
][FETCH
] = utils
.get_fetch_info(self
.policy
, item
)
164 if item
.user_stability
:
165 self
.model
[new
][STABILITY
] = str(item
.user_stability
).upper()
167 self
.model
[new
][STABILITY
] = item
.upstream_stability
or \
169 self
.model
[new
][ARCH
] = item
.arch
or 'any'
170 self
.model
[new
][UNUSABLE
] = bool(unusable
)
171 self
.model
[new
][NOTES
] = unusable