#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright (C) 2008 Adriano Monteiro Marques
#
# Author: Francesco Piccinno <stack.box@gmail.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program 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 program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
"""
This module contains:
- HIGRichList like firefox one
- HIGRichRow a row for HIGRichList
- PluginRow a custom HIGRichRow for HIGRichList
"""
import gtk
import pango
import gobject
from higwidgets.higbuttons import HIGButton
from umit.core.I18N import _
class HIGRichRow(gtk.EventBox):
"""
Represent a single row for HIGRichList
"""
__gtype_name__ = "HIGRichRow"
__gsignals__ = {
# Emitted when the user activate (selected)
'activate' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),
# Emitted when the user click with mouse
'clicked' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, ()),
# Emitted when the user click with the right button
'popup' : (gobject.SIGNAL_RUN_LAST, gobject.TYPE_NONE, \
(gtk.gdk.Event,))
}
def __init__(self, tree):
"""
Create a HIGRichRow
@param tree a PluginRichList object to use as parent
"""
assert isinstance(tree, HIGRichList), "must be a HIGRichList object"
gtk.EventBox.__init__(self)
self.tree = tree
self.__create_widgets()
self.__pack_widgets()
self._vbox.show()
def __create_widgets(self):
self._vbox = gtk.VBox()
def __pack_widgets(self):
self.add(self._vbox)
def do_expose_event(self, evt):
"Override this function"
gtk.EventBox.do_expose_event(self, evt)
alloc = self.allocation
cr = self.window.cairo_create()
# Only draw an end-line
cr.set_line_width(0.5)
cr.set_dash([1, 1], 1)
cr.move_to(0, alloc.height)
cr.line_to(alloc.width, alloc.height)
cr.stroke()
return True
def do_realize(self):
gtk.EventBox.do_realize(self)
self.active = False
def do_button_press_event(self, evt):
if (evt.button == 1) and \
(evt.type == gtk.gdk._2BUTTON_PRESS) and \
(self.tree.change_selection(self)):
self.active = True
self.emit('clicked')
elif (evt.type == gtk.gdk.BUTTON_PRESS) and \
(self.tree.change_selection(self)):
self.active = True
if evt.button == 3:
self.emit('popup', evt)
def get_active(self):
return self._active
def set_active(self, value):
self._active = value
self.emit('activate')
if self.flags() & gtk.REALIZED:
if value:
self.modify_bg(gtk.STATE_NORMAL, \
self.style.base[gtk.STATE_PRELIGHT])
else:
self.modify_bg(gtk.STATE_NORMAL, self.style.white)
def get_vbox(self):
return self._vbox
active = property(get_active, set_active)
vbox = property(get_vbox)
class PluginRow(HIGRichRow):
"""
A custom HIGRichRow to contains Plugin informations
"""
__gtype_name__ = "PluginRow"
def __init__(self, tree, reader):
"""
Create a PluginRow
@param tree a PluginRichList object to use as parent
@param reader a PluginrReader object to be represented
"""
HIGRichRow.__init__(self, tree)
self._reader = reader
self._enabled = False
self._message = reader.description
self._show_progress = False
self._show_include = False
self._activatable = True
self._saturate = False
self.__create_widgets()
self.__pack_widgets()
self.enabled = self._reader.enabled
self.connect('activate', self.__on_activate)
self.show_all()
self.progressbar.hide()
self.box_act.hide()
self.versions_button.hide()
def __create_widgets(self):
self.image = gtk.image_new_from_pixbuf(self._reader.get_logo())
self.label = gtk.Label('')
self.label.set_ellipsize(pango.ELLIPSIZE_END)
self.versions_model = gtk.ListStore(str, str)
self.versions_button = gtk.ComboBox(self.versions_model)
rend = gtk.CellRendererPixbuf()
self.versions_button.pack_start(rend, False)
self.versions_button.add_attribute(rend, 'stock-id', 0)
rend = gtk.CellRendererText()
self.versions_button.pack_end(rend)
self.versions_button.add_attribute(rend, 'text', 1)
self.img_play = gtk.image_new_from_stock(gtk.STOCK_MEDIA_PLAY, \
gtk.ICON_SIZE_BUTTON)
self.img_stop = gtk.image_new_from_stock(gtk.STOCK_MEDIA_STOP, \
gtk.ICON_SIZE_BUTTON)
self.action_btn = HIGButton('')
self.uninstall_btn = HIGButton(_("Uninstall"), gtk.STOCK_CLEAR)
self.preference_btn = HIGButton(stock=gtk.STOCK_PREFERENCES)
self.progressbar = gtk.ProgressBar()
def __pack_widgets(self):
# Visible part
hbox = gtk.HBox(False, 4)
hbox.set_border_width(4)
hbox.pack_start(self.image, False, False, 0)
vbox = gtk.VBox(False, 2)
mhbox = gtk.HBox(False, 2)
self.label.set_alignment(0, 0.5)
mhbox.pack_start(self.label)
minibox = gtk.VBox()
minibox.pack_start(self.versions_button, False, False, 0)
mhbox.pack_start(minibox, False, False)
vbox.pack_start(mhbox)
vbox.pack_start(self.progressbar, False, False, 0)
hbox.pack_start(vbox)
self.vbox.pack_start(hbox, False, False, 0)
# Buttons part
align = gtk.Alignment(0, 0.5)
align.add(self.preference_btn)
self.box_act = gtk.HBox(False, 2)
self.box_act.pack_start(align, True, True, 0)
self.box_act.pack_start(self.uninstall_btn, False, False, 0)
self.box_act.pack_start(self.action_btn, False, False, 0)
self.box_act.set_border_width(4)
self.vbox.pack_start(self.box_act, False, False, 0)
def __on_activate(self, widget):
if not self._activatable:
self.box_act.hide()
return
if self._show_progress:
self.box_act.hide()
self.progressbar.show()
else:
self.progressbar.hide()
if self.active:
self.box_act.show()
else:
self.box_act.hide()
def get_enabled(self):
return self._enabled
def set_enabled(self, val):
self._enabled = val
# We need more testing on color/saturate on enabled
if self._enabled:
self.action_btn.set_label(_("Disable"))
self.action_btn.set_image(self.img_stop)
#
color = self.style.text[gtk.STATE_NORMAL]
self.saturate = False
else:
self.action_btn.set_label(_("Enable"))
self.action_btn.set_image(self.img_play)
#
color = self.style.text[gtk.STATE_INSENSITIVE]
self.saturate = True
self.label.set_text( \
"<span color=\"%s\">"
"<span size=\"x-large\" weight=\"bold\">%s</span>" \
" %s" \
"\n<tt>%s</tt>" \
"</span>" % \
( \
color.to_string(), \
self._reader.name, \
self._reader.version, \
self._message \
) \
)
self.label.set_use_markup(True)
def get_reader(self):
return self._reader
enabled = property(get_enabled, set_enabled)
reader = property(get_reader)
def get_message(self):
return self._message
def set_message(self, value):
"""
If not defined don't update
"""
if value is not None:
self._message = value
# Used to update the label
self.enabled = self.enabled
def get_progress(self):
if self._show_progress:
return self.progressbar.get_fraction()
return None
def set_progress(self, val):
self.box_act.hide()
if not val or val < .0:
self._show_progress = False
self.progressbar.set_fraction(0)
self.progressbar.hide()
else:
self._show_progress = True
self.progressbar.set_fraction(val)
self.progressbar.set_text('%d %%' % int(val * 100))
self.progressbar.show()
def get_include(self):
if self._show_include:
id = self.versions_button.get_active() -1
if id >= 0:
return True
else:
return False
def set_include(self, value):
self._show_include = value
if value:
self.versions_button.show()
else:
self.versions_button.hide()
def get_activatable(self):
return self._activatable
def set_activatable(self, value):
self._activatable = value
self.__on_activate(self)
def get_saturate(self):
return self._saturate
def set_saturate(self, val):
self._saturate = val
if self._saturate:
logo = self._reader.get_logo()
logo.saturate_and_pixelate(logo, 0.3, False)
self.image.set_from_pixbuf(logo)
else:
self.image.set_from_pixbuf(self._reader.get_logo())
message = property(get_message, set_message)
progress = property(get_progress, set_progress)
show_include = property(get_include, set_include)
activatable = property(get_activatable, set_activatable)
saturate = property(get_saturate, set_saturate)
class HIGRichList(gtk.ScrolledWindow):
"""
A simil-treeview widget like firefox RichList
"""
def __init__(self):
"""
Create a HIGRichList object
"""
gtk.ScrolledWindow.__init__(self)
self.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
self.set_shadow_type(gtk.SHADOW_ETCHED_IN)
self.vbox = gtk.VBox()
self.add_with_viewport(self.vbox)
# We set the background of viewport to white
self.get_child().modify_bg(gtk.STATE_NORMAL, \
self.get_child().style.white)
self.prev_sel = None
self.show_all()
def append_row(self, widget):
"""
Append a row to the tree
@param widget a HIGRichRow type object
"""
assert isinstance(widget, HIGRichRow), "must be a HIGRichRow object"
self.vbox.pack_start(widget, False, False, 0)
def remove_row(self, widget):
"""
Remove a row from the tree
@param widget a HIGRichRow type object
"""
assert isinstance(widget, HIGRichRow), "must be a HIGRichRow object"
self.vbox.remove(widget)
def clear(self):
"""
Remove all the row
"""
def remove(widget, parent):
#
widget.hide()
parent.remove(widget)
self.vbox.foreach(remove, self.vbox)
def get_rows(self):
return len(self.vbox)
def foreach(self, callback, userdata):
"Foreach in any widgets"
self.vbox.foreach(callback, userdata)
def change_selection(self, row):
"""
Change the selected item in the tree
@return True if selection was changed
"""
assert row is not None
if self.prev_sel:
self.prev_sel.active = False
self.prev_sel = row
# Grab the focus!
self.grab_focus()
# Scroll to active item
adj = self.get_vadjustment()
alloc = row.get_allocation()
if alloc.y < adj.value:
adj.set_value(alloc.y)
elif alloc.y + alloc.height > adj.value + adj.page_size:
adj.set_value(alloc.y)
return True
|