1
# -*- coding: utf-8 -*-
2
# Copyright 2004-2005 Joe Wreschnig, Michael Urman, Iñigo Serna
4
# This program is free software; you can redistribute it and/or modify
5
# it under the terms of the GNU General Public License version 2 as
6
# published by the Free Software Foundation
8
# $Id: pluginwin.py 3464 2006-06-11 09:23:56Z piman $
20
from plugins import Manager
21
from qltk.views import HintedTreeView
23
class PluginWindow(qltk.Window):
26
def __new__(klass, parent):
27
if klass.__window is None:
28
return super(PluginWindow, klass).__new__(klass)
29
else: return klass.__window
31
def __init__(self, parent):
32
if type(self).__window: return
33
else: type(self).__window = self
34
super(PluginWindow, self).__init__()
35
self.set_title(_("Quod Libet Plugins"))
36
self.set_border_width(12)
37
self.set_resizable(False)
38
self.set_transient_for(parent)
40
hbox = gtk.HBox(spacing=12)
41
vbox = gtk.VBox(spacing=6)
43
sw = gtk.ScrolledWindow()
44
sw.set_policy(gtk.POLICY_NEVER, gtk.POLICY_ALWAYS)
46
model = gtk.ListStore(object, object)
48
tv.set_rules_hint(True)
50
render = gtk.CellRendererToggle()
51
def cell_data(col, render, model, iter):
53
render.set_active(row[1].enabled(row[0]))
54
render.connect('toggled', self.__toggled, model)
55
column = gtk.TreeViewColumn("enabled", render)
56
column.set_cell_data_func(render, cell_data)
57
tv.append_column(column)
59
render = gtk.CellRendererPixbuf()
60
def cell_data(col, render, model, iter):
61
icon = getattr(model[iter][0], 'PLUGIN_ICON', gtk.STOCK_EXECUTE)
62
render.set_property('stock-id', icon)
63
column = gtk.TreeViewColumn("image", render)
64
column.set_cell_data_func(render, cell_data)
65
tv.append_column(column)
67
render = gtk.CellRendererText()
68
render.set_property('ellipsize', pango.ELLIPSIZE_END)
69
render.set_property('xalign', 0.0)
70
column = gtk.TreeViewColumn("name", render)
71
def cell_data(col, render, model, iter):
72
render.set_property('text', model[iter][0].PLUGIN_NAME)
73
column.set_cell_data_func(render, cell_data)
74
column.set_expand(True)
75
tv.append_column(column)
78
sw.set_shadow_type(gtk.SHADOW_IN)
80
tv.set_headers_visible(False)
82
bbox = gtk.HBox(homogeneous=True, spacing=12)
83
errors = qltk.Button(_("Show _Errors"), gtk.STOCK_DIALOG_WARNING)
84
errors.set_focus_on_click(False)
85
bbox.pack_start(errors)
86
refresh = gtk.Button(stock=gtk.STOCK_REFRESH)
87
refresh.set_focus_on_click(False)
88
bbox.pack_start(refresh)
90
vbox.pack_start(bbox, expand=False)
91
vbox.set_size_request(250, -1)
92
hbox.pack_start(vbox, expand=False)
94
selection = tv.get_selection()
96
desc.set_alignment(0, 0)
97
desc.set_padding(6, 6)
98
desc.set_line_wrap(True)
99
desc.set_size_request(280, -1)
100
selection.connect('changed', self.__description, desc)
103
prefs.set_shadow_type(gtk.SHADOW_NONE)
105
lab.set_markup("<b>%s</b>" % _("Preferences"))
106
prefs.set_label_widget(lab)
108
vb2 = gtk.VBox(spacing=12)
109
vb2.pack_start(desc, expand=False)
110
vb2.pack_start(prefs, expand=False)
111
hbox.pack_start(vb2, expand=True)
115
selection.connect('changed', self.__preferences, prefs)
116
refresh.connect('clicked', self.__refresh, tv, desc, errors)
117
errors.connect('clicked', self.__show_errors)
118
tv.get_selection().emit('changed')
120
hbox.set_size_request(550, 350)
122
self.connect('destroy', self.__destroy)
125
def __destroy(self, *args):
126
type(self).__window = None
127
config.write(const.CONFIG)
129
def __description(self, selection, frame):
130
model, iter = selection.get_selected()
132
text = "<big>%s</big>\n" % util.escape(model[iter][0].PLUGIN_NAME)
133
try: text += "<small>%s</small>\n" %(
134
util.escape(model[iter][0].PLUGIN_VERSION))
135
except (TypeError, AttributeError): pass
136
try: text += "\n" + util.escape(model[iter][0].PLUGIN_DESC)
137
except (TypeError, AttributeError): pass
139
frame.set_markup(text)
141
def __preferences(self, selection, frame):
142
model, iter = selection.get_selected()
143
if frame.child: frame.child.destroy()
144
if iter and hasattr(model[iter][0], 'PluginPreferences'):
146
prefs = model[iter][0].PluginPreferences(self)
148
traceback.print_exc()
151
if isinstance(prefs, gtk.Window):
152
b = gtk.Button(stock=gtk.STOCK_PREFERENCES)
153
b.connect_object('clicked', gtk.Window.show, prefs)
154
b.connect_object('destroy', gtk.Window.destroy, prefs)
156
frame.child.set_border_width(6)
162
def __toggled(self, render, path, model):
163
render.set_active(not render.get_active())
166
pm.enable(row[0], render.get_active())
168
model.row_changed(row.path, row.iter)
170
def __refresh(self, activator, view, desc, errors):
171
model, sel = view.get_selection().get_selected()
172
if sel: sel = model[sel][0]
176
for pm in Manager.instances.values():
178
for plugin in pm.list():
179
plugins.append((plugin.PLUGIN_NAME, plugin, pm))
180
failures = failures or bool(pm.list_failures())
183
for plugin in plugins:
184
it = model.append(row=plugin[1:])
186
view.get_selection().select_iter(it)
188
desc.set_text(_("No plugins found."))
189
errors.set_sensitive(failures)
191
def __show_errors(self, activator):
192
try: self.__win.present()
193
except AttributeError:
194
self.__win = qltk.Window()
195
self.__win.set_title(_("Plugin Errors") + "- Quod Libet")
196
self.__win.set_border_width(12)
197
self.__win.set_transient_for(qltk.get_top_parent(self))
198
self.__win.set_default_size(400, 250)
200
scrolledwin = gtk.ScrolledWindow()
201
self.__win.add(scrolledwin)
202
vbox = gtk.VBox(spacing=6)
203
scrolledwin.add_with_viewport(vbox)
204
scrolledwin.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
205
scrolledwin.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse('#fff'))
208
for pm in Manager.instances.values():
209
failures.update(pm.list_failures())
210
keys = failures.keys()
211
show_expanded = len(keys) <= 3
212
for key in sorted(keys):
213
expander = gtk.Expander("<b>%s</b>" % key)
214
expander.set_use_markup(True)
215
if show_expanded: expander.set_expanded(True)
217
# second line is always the __rescan line; don't show it
218
message = failures[key][0:1] + failures[key][2:]
219
failure = gtk.Label(''.join(message).strip())
220
failure.set_alignment(0, 0)
221
failure.set_padding(3, 3)
222
failure.set_selectable(True)
224
vbox.pack_start(expander, expand=False)
225
expander.add(failure)
227
scrolledwin.show_all()
228
def delwin(*args): del self.__win
229
self.__win.connect("destroy", delwin)