Source

vlmaddon / view / widgets.py

Full commit
#!/usr/bin/env python

#    This file is part of the vectorlinux multimedia bonus disc.
#
#    This is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License v2 as published by
#    the Free Software Foundation.
#
#    This file is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this file.  If not, see <http://www.gnu.org/licenses/>.

import gtk
import gobject
import glib
from .utils import repository
from .utils import vl
import os

__author__ = 'Moises Henriquez'
__author_email__ = 'moc.liamg@xnl.E0M'[::-1]


def _(str):
    return str

def get_data_path():
    basepath = os.path.dirname(os.path.abspath(__file__))
    basepath = os.path.dirname(basepath)
    return os.path.join(basepath, 'data')

class CategoryPanel(gtk.TreeView):
    """
    Tree used to display software categories

    Arguments:
        repo - a repository object containing a pool of apps
        cache - a PackageCache object
        detail_view - a FancyAppList object
    """
    def __init__(self, repo, cache, detail_view):
        gtk.TreeView.__init__(self)
        self.model = gtk.ListStore(gtk.gdk.Pixbuf, str, bool)
        self.set_model(self.model)
        pb = FancyPixbuf('emblem-app-installed')
#        pb = gtk.CellRendererPixbuf()
        col = gtk.TreeViewColumn('None', pb, pixbuf = 0, overlay=2)
        col.set_fixed_width(36)
        col.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
        self.append_column(col)
        rend = gtk.CellRendererText()
        col = gtk.TreeViewColumn(None, rend)
        col.add_attribute(rend, 'text', 1)

        self.set_headers_visible(False)
        self.connect('cursor-changed', self.click_event)
        self._repo = repo
        self.repo = []
        self.view = detail_view
        self.cache = cache
        self.append_column(col)
        for app in repo:
            self.repo.append(app)

    def refresh_view(self):
        #        sel = self.get_selection().get_selected_rows()[1][0][0]
        self.show_category(self._get_selected())
#        self.show_category(sel)

    def _get_selected(self):
        row = self.get_selection().get_selected_rows()[1][0][0]
        return self.model[row][1]

    def click_event(self, column):
        row = column.get_selection().get_selected_rows()[1][0][0]
        sel = self.model[row][1]
        self.show_category(sel)
        return

    def show_category(self, category):
        model = self.view.get_model()
        model.clear()
	cache = self.cache

        if category == _('All'):
            for app in self.repo:
                if 'deps' not in app.location:
                    _overlay = cache.is_app_installed(app.name)
                    _sdesc = app.summary
                    self.view.list_app(app_name = app.name,
                            app_short_description = _sdesc,
                            installed_indicator = _overlay)
        elif category == _('Graphics'):
            for app in self.repo:
                _overlay = cache.is_app_installed(app.name)
                _sdesc = app.summary
                if 'Graphics' in app.location:
                    self.view.list_app(
                            app_name = app.name,
                            app_short_description = _sdesc,
                            installed_indicator = _overlay)

        elif category == _('Audio'):
            for app in self.repo:
                _overlay = cache.is_app_installed(app.name)
                _sdesc = app.summary
                if 'Audio' in app.location:
                    self.view.list_app(
                            app_name = app.name,
                            app_short_description = _sdesc,
                            installed_indicator = _overlay)
        elif category == _('Video'):
            for app in self.repo:
                _overlay = cache.is_app_installed(app.name)
                _sdesc = app.summary
                if 'Video' in app.location:
                    self.view.list_app(
                            app_name = app.name,
                            app_short_description = _sdesc,
                            installed_indicator = _overlay)
        elif category == _('Bonus'):
            for app in self.repo:
                _overlay = cache.is_app_installed(app.name)
                _sdesc = app.summary
                if 'Bonus' in app.location:
                    self.view.list_app(
                            app_name = app.name,
                            app_short_description = _sdesc,
                            installed_indicator = _overlay)
        elif category == _('Installed Only'):
            for app in self.repo:
                _overlay = cache.is_app_installed(app.name)
                if _overlay is True:
                    if 'deps' not in app.location:
                        self.view.list_app(
                                app_name = app.name,
                                app_short_description = app.summary,
                                installed_indicator = _overlay)
        else:
            for app in self.repo:
                _overlay = cache.is_app_installed(app.name)
                _sdesc = app.summary
                if app.location not in (
                        'Audio',
                        'Video',
                        'Graphics',
                        'Bonus',
                        'deps',
                        './AudioApps',
                        './VideoApps',
                        './deps'):
                    self.view.list_app(
                            app_name = app.name,
                            app_short_description = _sdesc,
                            installed_indicator = _overlay)

    def add_category(self, icon = None, label='', overlay=False):
        if icon is None:
            self.model.append([None, label, overlay])
            return
        self.model.append([
            gtk.gdk.pixbuf_new_from_file_at_size(
                icon, 32, 32), label, overlay])
        #        self.model.append([Icon, label])
        return

class FancyPixbuf(gtk.CellRendererPixbuf):
    """ Fancy pixbuf that can display an overlay icon
    by setting it's 'overlay' property to True. 
    Used to indicate when an app is installed in the system
    """
    OFFSET_X = 14
    OFFSET_Y = 16
    OVERLAY_SIZE = 16

    __gproperties__ = {
            'overlay' : (bool, 'overlay', 
                'Show an overlay icon',
                False, 
                gobject.PARAM_READWRITE)
            }
    def __init__(self, overlay_icon_name):
        gtk.CellRendererPixbuf.__init__(self)
        icons = gtk.icon_theme_get_default()
        icons.append_search_path(
                '/usr/share/icons/Tango/16x16/emblems/')
        icons.append_search_path(os.path.join(get_data_path(),
            'emblems'))

        self.overlay = False
        try:
            self._installed = icons.load_icon(
                    overlay_icon_name,
                    self.OVERLAY_SIZE,
                    0)
        except glib.GError:
            ## Maybe the icon was not found
            self._installed = icons.load_icon(
                    'app-installed', self.OVERLAY_SIZE, 0)
        return

    def do_set_property(self, pspec, value):
        setattr(self, pspec.name, value)
        return

    def do_get_property(self, pspec):
        return getattr(self, pspec.name)

    def do_render(self, window, widget,
            background_area, cell_area,
            expose_area, flags):
        gtk.CellRendererPixbuf.do_render(self,
                window,
                widget,
                background_area,
                cell_area,
                expose_area, 
                flags)
        overlay = self.get_property('overlay')
        if overlay:
            dest_x = cell_area.x + self.OFFSET_X
            dest_y = cell_area.y + self.OFFSET_Y
            window.draw_pixbuf(None,
                    self._installed,            # overlay
                    0, 0,                       # src pixbuf
                    dest_x, dest_y,             # dest in window
                    -1, -1,                     # size
                    0, 0, 0)                    # dither

gobject.type_register(FancyPixbuf)

class FancyAppList(gtk.TreeView):
    """
    Fancy treeview used for displaying apps on the screen.
    To add a row:
    model = FantyAppList.get_model()
    model.append([False, 'your app', pixbuf, False])
    """
    def __init__(self):
        gtk.TreeView.__init__(self)
        self.set_headers_visible(False)
        fp = FancyPixbuf('emblem-app-installed')
        tg = gtk.CellRendererToggle()
        col_tg = gtk.TreeViewColumn('Toggle', 
                tg,
                active = 0)
        col_icon = gtk.TreeViewColumn('Icon',
                fp,
                pixbuf = 2,     # Icon path
                overlay = 3     # overlay value : True or False
                )
        col_icon.set_fixed_width(36)
        col_icon.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
        crt = gtk.CellRendererText()
        col_app = gtk.TreeViewColumn('App', crt,
                markup = 1)

        # Add the columns
        for col in (col_tg, col_icon, col_app):
            self.append_column(col)

        # Add the model
        model = gtk.ListStore(bool, str, gtk.gdk.Pixbuf, bool)
        self.set_model(model)
        tg.connect('toggled', self.toggle_event, model)

    def toggle_event(self, cell, path, model):
        model[path][0] = not model[path][0]
        return

    def list_app(self, default_state = False,
            app_name = str,
            app_short_description = str,
            app_icon_path = None,
            installed_indicator = False):
        if app_icon_path is None:
            app_icon_path = os.path.join(get_data_path(),
                    'icons/applications-other.png')

            pic = gtk.gdk.pixbuf_new_from_file_at_size(
                    app_icon_path, 32, 32)
            markup = '<b>%s</b>\n'% app_name + ' '*4 + \
                    '<small>%s</small>'% app_short_description
            self.get_model().append([
                default_state,
                markup,
                pic,
                installed_indicator])
        return