Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Bower components Debian packages RPM packages NuGet packages

beebox / crossover   deb

Repository URL to install this package:

Version: 18.5.0-1 

/ opt / cxoffice / lib / python / cxmenuwidget.py

# (c) Copyright 2009-2012. CodeWeavers, Inc.

import traceback

import gobject
import gtk

import cxlog

import cxmenu

import cxguitools
import pyop

# for localization
from cxutils import cxgettext as _

_COLUMN_PATH = 0
_COLUMN_SHOW = 1
_COLUMN_DIRNAME = 2
_COLUMN_BASENAME = 3
_COLUMN_ICON_PIXBUF = 4
_COLUMN_SORTPATH = 5

class MenuEditor(gtk.VBox):
    __gtype_name__ = 'MenuEditor'

    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_show_toggle)
        elif hasattr(self.mode_renderer, 'set_sensitive'):
            self.mode_renderer.set_sensitive(False)

        self.prefs = cxmenu.MenuPrefs(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, gtk.gdk.Pixbuf,
                                       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_SORTPATH, gtk.SORT_ASCENDING)

        self.mode_renderer = gtk.CellRendererToggle()
        mode_column = gtk.TreeViewColumn(_("Show"), self.mode_renderer)
        mode_column.add_attribute(self.mode_renderer, 'active', _COLUMN_SHOW)
        mode_column.set_sort_column_id(_COLUMN_SHOW)
        self.treeview.append_column(mode_column)

        icon_renderer = gtk.CellRendererPixbuf()
        basename_renderer = gtk.CellRendererText()
        basename_column = gtk.TreeViewColumn(_("Menu Name"))
        basename_column.set_resizable(True)
        basename_column.pack_start(icon_renderer, False)
        basename_column.pack_end(basename_renderer, True)
        basename_column.add_attribute(basename_renderer, 'text', _COLUMN_BASENAME)
        basename_column.add_attribute(icon_renderer, 'pixbuf', _COLUMN_ICON_PIXBUF)
        basename_column.set_sort_column_id(_COLUMN_BASENAME)
        self.treeview.append_column(basename_column)

        dir_renderer = gtk.CellRendererText()
        dir_column = gtk.TreeViewColumn(_("Path"), dir_renderer)
        dir_column.set_resizable(True)
        dir_column.add_attribute(dir_renderer, 'text', _COLUMN_DIRNAME)
        dir_column.set_sort_column_id(_COLUMN_SORTPATH)
        self.treeview.append_column(dir_column)

        self.pack_start(self.scrolledview, expand=True, fill=True, padding=0)

        self.pulse_timer = None

        self.treeview.connect('row-activated', self.on_row_activate)

    def get_selection(self):
        _model, treeiter = self.treeview.get_selection().get_selected()

        if treeiter is None:
            return None

        path = self.liststore.get_value(treeiter, _COLUMN_PATH)
        return path

    def _on_selection_changed(self, _treeselection, user_function):
        # pylint: disable=R0201
        user_function()

    def connect_selection_changed(self, user_function):
        self.treeview.get_selection().connect('changed', self._on_selection_changed, user_function)

    def on_row_activate(self, _treeview, treepath, _view_column):
        treeiter = self.liststore.get_iter(treepath)
        path = self.liststore.get_value(treeiter, _COLUMN_PATH)
        self.prefs[path].start()

    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 menus of %(bottlename)s\u2026") % {'bottlename': self.prefs.bottlename})
        operation = RefreshMenusOp(self, success_notify, failure_notify)
        pyop.sharedOperationQueue.enqueue(operation)

    def recreate_menus(self, success_notify, failure_notify):
        if self.pulse_timer:
            return
        self.pulse_start(_(u"Recreating the menus in %(bottlename)s\u2026") % {'bottlename': self.prefs.bottlename})
        operation = RecreateMenusOp(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 menus in %(bottlename)s\u2026") % {'bottlename': self.prefs.bottlename})
        operation = CommitMenusOp(self, success_notify, failure_notify)
        pyop.sharedOperationQueue.enqueue(operation)

    def update_menulist(self):
        "read the list of menus from self.prefs"
        self.liststore.clear()

        for menu in self.prefs.itervalues():
            path = menu.path
            if path.startswith('StartMenu'):
                topleveldir = _("Start Menu")
            elif path.startswith('Desktop'):
                topleveldir = _("Desktop")
            else:
                cxlog.warn("Ignoring unrecognized path %s" % cxlog.to_str(path))
                continue
            basename = path.split('/', 1)[1]
            if '/' in basename:
                dirname, basename = basename.rsplit('/', 1)
                dirname = '%s/%s' % (topleveldir, dirname)
            else:
                dirname = topleveldir
            if basename.endswith('.lnk') or basename.endswith('.pif') or \
                    basename.endswith('.url'):
                basename = basename[0:-4]
            sortname = '%s/0/%s' % (dirname.replace('/', '/1/'), basename)
            icon_filename = menu.iconfile
            icon = None
            if icon_filename:
                try:
                    icon = gtk.gdk.pixbuf_new_from_file(icon_filename)
                except gobject.GError:
                    cxlog.warn("couldn't load icon file %s:\n%s" % (cxlog.debug_str(icon_filename), traceback.format_exc()))
            if icon is None:
                icon = cxguitools.get_std_icon('crossover')
            if icon is not None:
                icon = icon.scale_simple(24, 24, gtk.gdk.INTERP_BILINEAR)
            self.liststore.append((path, menu.mode == 'install', dirname, basename, icon, sortname))

        # 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_show_toggle(self, _cellrenderer, treepath):
        treeiter = self.liststore.get_iter(treepath)
        path = self.liststore.get_value(treeiter, _COLUMN_PATH)

        prev_show = (self.prefs[path].new_mode == 'install')

        if prev_show:
            self.prefs[path].new_mode = 'ignore'
        else:
            self.prefs[path].new_mode = 'install'

        self.liststore.set_value(treeiter, _COLUMN_SHOW, not prev_show)

class RefreshMenusOp(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_menulist()
        if self.error_text is None:
            self.success_notify()
        else:
            self.failure_notify(self.error_text)

class RecreateMenusOp(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_menus()
            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_menulist()
        if self.error_text is None:
            self.success_notify()
        else:
            self.failure_notify(self.error_text)

class CommitMenusOp(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)