# (c) Copyright 2009-2011, 2015. CodeWeavers, Inc.
import traceback
import gobject
import gtk
import cxnsplugin
import pyop
# for localization
from cxutils import cxgettext as _
_COLUMN_DLLKEY = 0
_COLUMN_ENABLED = 1
_COLUMN_BASENAME = 2
_COLUMN_NAME = 3
class PluginEditor(gtk.VBox):
__gtype_name__ = 'PluginEditor'
bottlename = None
managed = None
prefs = None
def set_bottle(self, bottlename, managed):
if self.bottlename:
raise ValueError("bottle is already set")
self.bottlename = bottlename
self.managed = managed
if not self.managed:
self.mode_renderer.connect('toggled', self.on_enable_toggle)
elif hasattr(self.mode_renderer, 'set_sensitive'):
self.mode_renderer.set_sensitive(False)
self.prefs = cxnsplugin.PluginPrefs(bottlename, managed)
def __init__(self):
gtk.VBox.__init__(self)
self.progbar = gtk.ProgressBar()
self.pack_start(self.progbar, expand=True, fill=False, padding=0)
self.liststore = gtk.ListStore(gobject.TYPE_STRING, gobject.TYPE_BOOLEAN,
gobject.TYPE_STRING, gobject.TYPE_STRING)
self.treeview = gtk.TreeView(self.liststore)
self.treeview.show()
self.scrolledview = gtk.ScrolledWindow()
self.scrolledview.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
self.scrolledview.add(self.treeview)
self.liststore.set_sort_column_id(_COLUMN_BASENAME, gtk.SORT_ASCENDING)
self.mode_renderer = gtk.CellRendererToggle()
mode_column = gtk.TreeViewColumn(_("Enabled"), self.mode_renderer)
mode_column.add_attribute(self.mode_renderer, 'active', _COLUMN_ENABLED)
mode_column.set_sort_column_id(_COLUMN_ENABLED)
self.treeview.append_column(mode_column)
dll_renderer = gtk.CellRendererText()
dll_column = gtk.TreeViewColumn(_("Dll"), dll_renderer)
dll_column.set_resizable(True)
dll_column.add_attribute(dll_renderer, 'text', _COLUMN_BASENAME)
dll_column.set_sort_column_id(_COLUMN_BASENAME)
self.treeview.append_column(dll_column)
name_renderer = gtk.CellRendererText()
name_column = gtk.TreeViewColumn(_("Name"), name_renderer)
name_column.set_resizable(True)
name_column.add_attribute(name_renderer, 'text', _COLUMN_NAME)
name_column.set_sort_column_id(_COLUMN_NAME)
self.treeview.append_column(name_column)
self.pack_start(self.scrolledview, expand=True, fill=True, padding=0)
self.pulse_timer = None
def pulse(self):
self.progbar.pulse()
return True
def pulse_start(self, text):
self.progbar.set_text(text)
self.progbar.show()
self.pulse_timer = gobject.timeout_add(100, self.pulse)
self.scrolledview.set_sensitive(False)
def pulse_stop(self):
if self.pulse_timer:
gobject.source_remove(self.pulse_timer)
self.pulse_timer = None
self.progbar.hide()
self.scrolledview.set_sensitive(True)
def refresh(self, success_notify, failure_notify):
if self.pulse_timer:
return
self.pulse_start(_(u"Reading the plugins of %(bottlename)s\u2026") % {'bottlename': self.prefs.bottlename})
operation = RefreshPluginsOp(self, success_notify, failure_notify)
pyop.sharedOperationQueue.enqueue(operation)
def recreate_plugins(self, success_notify, failure_notify):
if self.pulse_timer:
return
self.pulse_start(_(u"Recreating the plugins in %(bottlename)s\u2026") % {'bottlename': self.prefs.bottlename})
operation = RecreatePluginsOp(self, success_notify, failure_notify)
pyop.sharedOperationQueue.enqueue(operation)
def commit(self, success_notify, failure_notify):
if self.pulse_timer:
return
self.pulse_start(_(u"Updating the plugins in %(bottlename)s\u2026") % {'bottlename': self.prefs.bottlename})
operation = CommitPluginsOp(self, success_notify, failure_notify)
pyop.sharedOperationQueue.enqueue(operation)
def update_pluginlist(self):
"read the list of plugins from self.prefs"
self.liststore.clear()
for plugin in self.prefs.values():
self.liststore.append((plugin.dllkey, plugin.mode == 'install',
plugin.basename, plugin.name))
# Don't pad the progress bar next time we show it; we want the treeview
# to fill that space.
self.set_child_packing(self.progbar, False, False, 0, gtk.PACK_START)
self.scrolledview.show()
def on_enable_toggle(self, _cellrenderer, treepath):
treeiter = self.liststore.get_iter(treepath)
dllkey = self.liststore.get_value(treeiter, _COLUMN_DLLKEY)
prev_show = (self.prefs[dllkey].new_mode == 'install')
if prev_show:
self.prefs[dllkey].new_mode = 'ignore'
else:
self.prefs[dllkey].new_mode = 'install'
self.liststore.set_value(treeiter, _COLUMN_ENABLED, not prev_show)
class RefreshPluginsOp(pyop.PythonOperation):
def __init__(self, editor, success_notify, failure_notify):
pyop.PythonOperation.__init__(self)
self.editor = editor
self.success_notify = success_notify
self.failure_notify = failure_notify
self.error_text = None
def main(self):
self.error_text = None
try:
self.editor.prefs.refresh()
except Exception: # pylint: disable=W0703
self.error_text = traceback.format_exc()
def finish(self):
self.editor.pulse_stop()
self.editor.update_pluginlist()
if self.error_text is None:
self.success_notify()
else:
self.failure_notify(self.error_text)
class RecreatePluginsOp(pyop.PythonOperation):
def __init__(self, editor, success_notify, failure_notify):
pyop.PythonOperation.__init__(self)
self.editor = editor
self.success_notify = success_notify
self.failure_notify = failure_notify
self.error_text = None
def main(self):
self.error_text = None
try:
self.editor.prefs.recreate_plugins()
self.editor.prefs.refresh()
except Exception: # pylint: disable=W0703
self.error_text = traceback.format_exc()
def finish(self):
self.editor.pulse_stop()
self.editor.update_pluginlist()
if self.error_text is None:
self.success_notify()
else:
self.failure_notify(self.error_text)
class CommitPluginsOp(pyop.PythonOperation):
def __init__(self, editor, success_notify, failure_notify):
pyop.PythonOperation.__init__(self)
self.editor = editor
self.success_notify = success_notify
self.failure_notify = failure_notify
self.error_text = None
def main(self):
self.error_text = None
try:
self.editor.prefs.commit()
except Exception: # pylint: disable=W0703
self.error_text = traceback.format_exc()
def finish(self):
self.editor.pulse_stop()
if self.error_text is None:
self.success_notify()
else:
self.failure_notify(self.error_text)