4881: Convert bottombar gramplets to use the thumbnailer

svn: r17400
This commit is contained in:
Nick Hall 2011-05-03 21:33:19 +00:00
parent 3f54758147
commit 8f361f33b8
8 changed files with 65 additions and 81 deletions

View File

@ -61,6 +61,14 @@ try:
except ImportError:
GCONF = False
#-------------------------------------------------------------------------
#
# Constants
#
#-------------------------------------------------------------------------
SIZE_NORMAL = 0
SIZE_LARGE = 1
#-------------------------------------------------------------------------
#
# __get_gconf_string
@ -108,7 +116,7 @@ def __get_gconf_bool(key):
# __build_thumb_path
#
#-------------------------------------------------------------------------
def __build_thumb_path(path, rectangle=None):
def __build_thumb_path(path, rectangle=None, size=SIZE_NORMAL):
"""
Convert the specified path into a corresponding path for the thumbnail
image. We do this by converting the original path into an MD5SUM value
@ -126,14 +134,19 @@ def __build_thumb_path(path, rectangle=None):
if rectangle is not None:
extra = "?" + str(rectangle)
md5_hash = md5(path+extra)
return os.path.join(const.THUMB_DIR, md5_hash.hexdigest()+'.png')
if size == SIZE_LARGE:
base_dir = const.THUMB_LARGE
else:
base_dir = const.THUMB_NORMAL
return os.path.join(base_dir, md5_hash.hexdigest()+'.png')
#-------------------------------------------------------------------------
#
# __create_thumbnail_image
#
#-------------------------------------------------------------------------
def __create_thumbnail_image(src_file, mtype=None, rectangle=None):
def __create_thumbnail_image(src_file, mtype=None, rectangle=None,
size=SIZE_NORMAL):
"""
Generates the thumbnail image for a file. If the mime type is specified,
and is not an 'image', then we attempt to find and run a thumbnailer
@ -147,7 +160,7 @@ def __create_thumbnail_image(src_file, mtype=None, rectangle=None):
:param rectangle: subsection rectangle
:type rectangle: tuple
"""
filename = __build_thumb_path(src_file, rectangle)
filename = __build_thumb_path(src_file, rectangle, size)
if mtype and not mtype.startswith('image/'):
# Not an image, so run the thumbnailer
@ -174,7 +187,11 @@ def __create_thumbnail_image(src_file, mtype=None, rectangle=None):
width = sub_width
height = sub_height
scale = const.THUMBSCALE / (float(max(width, height)))
if size == SIZE_LARGE:
thumbscale = const.THUMBSCALE_LARGE
else:
thumbscale = const.THUMBSCALE
scale = thumbscale / (float(max(width, height)))
scaled_width = int(width * scale)
scaled_height = int(height * scale)
@ -213,7 +230,7 @@ def find_mime_type_pixbuf(mime_type):
# run_thumbnailer
#
#-------------------------------------------------------------------------
def run_thumbnailer(mime_type, src_file, dest_file, size=const.THUMBSCALE):
def run_thumbnailer(mime_type, src_file, dest_file, size=SIZE_NORMAL):
"""
This function attempts to generate a thumbnail image for a non-image.
This includes things such as video and PDF files. This will currently
@ -232,7 +249,6 @@ def run_thumbnailer(mime_type, src_file, dest_file, size=const.THUMBSCALE):
:rtype: bool
:returns: True if the thumbnail was successfully generated
"""
# only try this if GCONF is present, the thumbnailer has not been
# disabled, and if the src_file actually exists
if GCONF and const.USE_THUMBNAILER and os.path.isfile(src_file):
@ -246,8 +262,12 @@ def run_thumbnailer(mime_type, src_file, dest_file, size=const.THUMBSCALE):
# if we found the command and it has been enabled, then spawn
# of the command to build the thumbnail
if cmd and enable:
if size == SIZE_LARGE:
thumbscale = const.THUMBSCALE_LARGE
else:
thumbscale = const.THUMBSCALE
sublist = {
'%s' : "%d" % int(size),
'%s' : "%d" % int(thumbscale),
'%u' : src_file,
'%o' : dest_file,
}
@ -261,7 +281,7 @@ def run_thumbnailer(mime_type, src_file, dest_file, size=const.THUMBSCALE):
# get_thumbnail_image
#
#-------------------------------------------------------------------------
def get_thumbnail_image(src_file, mtype=None, rectangle=None):
def get_thumbnail_image(src_file, mtype=None, rectangle=None, size=SIZE_NORMAL):
"""
Return the thumbnail image (in GTK Pixbuf format) associated with the
source file passed to the function. If no thumbnail could be found,
@ -281,7 +301,7 @@ def get_thumbnail_image(src_file, mtype=None, rectangle=None):
:rtype: gtk.gdk.Pixbuf
"""
try:
filename = get_thumbnail_path(src_file, mtype, rectangle)
filename = get_thumbnail_path(src_file, mtype, rectangle, size)
return gtk.gdk.pixbuf_new_from_file(filename)
except (gobject.GError, OSError):
if mtype:
@ -295,7 +315,7 @@ def get_thumbnail_image(src_file, mtype=None, rectangle=None):
# get_thumbnail_path
#
#-------------------------------------------------------------------------
def get_thumbnail_path(src_file, mtype=None, rectangle=None):
def get_thumbnail_path(src_file, mtype=None, rectangle=None, size=SIZE_NORMAL):
"""
Return the path to the thumbnail image associated with the
source file passed to the function. If the thumbnail does not exist,
@ -310,13 +330,13 @@ def get_thumbnail_path(src_file, mtype=None, rectangle=None):
:returns: thumbnail representing the source file
:rtype: gtk.gdk.Pixbuf
"""
filename = __build_thumb_path(src_file, rectangle)
filename = __build_thumb_path(src_file, rectangle, size)
if not os.path.isfile(src_file):
return os.path.join(const.IMAGE_DIR, "image-missing.png")
else:
if not os.path.isfile(filename):
__create_thumbnail_image(src_file, mtype, rectangle)
__create_thumbnail_image(src_file, mtype, rectangle, size)
elif os.path.getmtime(src_file) > os.path.getmtime(filename):
__create_thumbnail_image(src_file, mtype, rectangle)
__create_thumbnail_image(src_file, mtype, rectangle, size)
return os.path.abspath(filename)

View File

@ -152,10 +152,12 @@ TOOL_OPTIONS = os.path.join(HOME_DIR, "tool_options.xml")
ENV_DIR = os.path.join(HOME_DIR, "env")
TEMP_DIR = os.path.join(HOME_DIR, "temp")
THUMB_DIR = os.path.join(HOME_DIR, "thumb")
THUMB_NORMAL = os.path.join(THUMB_DIR, "normal")
THUMB_LARGE = os.path.join(THUMB_DIR, "large")
USER_PLUGINS = os.path.join(VERSION_DIR, "plugins")
# dirs checked/made for each Gramps session
USER_DIRLIST = (HOME_DIR, VERSION_DIR, ENV_DIR, TEMP_DIR, THUMB_DIR,
USER_PLUGINS)
THUMB_NORMAL, THUMB_LARGE, USER_PLUGINS)
ICON = os.path.join(ROOT_DIR, "images", "gramps.png")
LOGO = os.path.join(ROOT_DIR, "images", "logo.png")
@ -227,6 +229,7 @@ TRANSLATORS = _('TRANSLATORS: Translate this to your '
#
#-------------------------------------------------------------------------
THUMBSCALE = 96.0
THUMBSCALE_LARGE = 180.0
XMLFILE = "data.gramps"
NO_SURNAME = "(%s)" % _("none")
NO_GIVEN = "(%s)" % _("none")

View File

@ -31,6 +31,7 @@ import gtk
# Gramps modules
#
#-------------------------------------------------------------------------
import ThumbNails
from gui.utils import open_file_with_default_application
from gen.ggettext import gettext as _
@ -43,9 +44,8 @@ class Photo(gtk.EventBox):
"""
Displays an image and allows it to be viewed in an external image viewer.
"""
def __init__(self, size=100.0):
def __init__(self):
gtk.EventBox.__init__(self)
self.size = size
self.full_path = None
self.photo = gtk.Image()
self.add(self.photo)
@ -54,14 +54,17 @@ class Photo(gtk.EventBox):
'viewer application.')
self.set_tooltip_text(tip)
def set_image(self, full_path, rectangle=None):
def set_image(self, full_path, mime_type=None, rectangle=None):
"""
Set the image to be displayed.
"""
self.full_path = full_path
if full_path:
pb = self.get_pixbuf(full_path, rectangle, self.size)
self.photo.set_from_pixbuf(pb)
pixbuf = ThumbNails.get_thumbnail_image(full_path,
mime_type,
rectangle,
ThumbNails.SIZE_LARGE)
self.photo.set_from_pixbuf(pixbuf)
self.photo.show()
else:
self.photo.hide()
@ -72,33 +75,3 @@ class Photo(gtk.EventBox):
"""
if event.type == gtk.gdk._2BUTTON_PRESS and event.button == 1:
open_file_with_default_application(self.full_path)
def get_pixbuf(self, full_path, rectangle=None, size=100.0):
"""
Load, scale and display the image from the path.
"""
try:
image = gtk.gdk.pixbuf_new_from_file(full_path)
except:
return None
width = image.get_width()
height = image.get_height()
if rectangle is not None:
upper_x = min(rectangle[0], rectangle[2])/100.
lower_x = max(rectangle[0], rectangle[2])/100.
upper_y = min(rectangle[1], rectangle[3])/100.
lower_y = max(rectangle[1], rectangle[3])/100.
sub_x = int(upper_x * width)
sub_y = int(upper_y * height)
sub_width = int((lower_x - upper_x) * width)
sub_height = int((lower_y - upper_y) * height)
if sub_width > 0 and sub_height > 0:
image = image.subpixbuf(sub_x, sub_y, sub_width, sub_height)
ratio = float(max(image.get_height(), image.get_width()))
scale = float(size)/ratio
x = int(scale*(image.get_width()))
y = int(scale*(image.get_height()))
image = image.scale_simple(x, y, gtk.gdk.INTERP_BILINEAR)
return image

View File

@ -61,8 +61,8 @@ class Gallery(Gramplet):
full_path = Utils.media_path_full(self.dbstate.db, media.get_path())
mime_type = media.get_mime_type()
if mime_type and mime_type.startswith("image"):
photo = Photo(180.0)
photo.set_image(full_path, media_ref.get_rectangle())
photo = Photo()
photo.set_image(full_path, mime_type, media_ref.get_rectangle())
self.image_list.append(photo)
self.top.pack_start(photo, expand=False, fill=False)
self.top.show_all()

View File

@ -20,9 +20,7 @@
#
from gen.plug import Gramplet
from gui.utils import open_file_with_default_application
import ThumbNails
import const
from gui.widgets import Photo
import Utils
import gtk
@ -40,13 +38,8 @@ class MediaPreview(Gramplet):
Build the GUI interface.
"""
self.top = gtk.HBox()
self.thumbnail = gtk.Image()
ebox = gtk.EventBox()
ebox.add(self.thumbnail)
ebox.connect('button-press-event', self.display_image)
ebox.set_tooltip_text(
_('Double click image to view in an external viewer'))
self.top.pack_start(ebox, fill=True, expand=False, padding=5)
self.photo = Photo()
self.top.pack_start(self.photo, fill=True, expand=False, padding=5)
self.top.show_all()
return self.top
@ -68,7 +61,7 @@ class MediaPreview(Gramplet):
self.load_image(media)
self.set_has_data(True)
else:
self.thumbnail.clear()
self.photo.set_image(None)
self.set_has_data(False)
self.top.show()
@ -79,13 +72,4 @@ class MediaPreview(Gramplet):
self.full_path = Utils.media_path_full(self.dbstate.db,
media.get_path())
mime_type = media.get_mime_type()
pixbuf = ThumbNails.get_thumbnail_image(self.full_path, mime_type)
self.thumbnail.set_from_pixbuf(pixbuf)
def display_image(self, widget, event):
"""
Display the image with the default external viewer.
"""
if event.type == gtk.gdk._2BUTTON_PRESS and event.button == 1:
open_file_with_default_application(self.full_path)
self.photo.set_image(self.full_path, mime_type)

View File

@ -45,7 +45,7 @@ class PersonDetails(Gramplet):
"""
self.top = gtk.HBox()
vbox = gtk.VBox()
self.photo = Photo(190.0)
self.photo = Photo()
self.photo.show()
self.name = gtk.Label()
self.name.set_alignment(0, 0)
@ -227,7 +227,8 @@ class PersonDetails(Gramplet):
full_path = Utils.media_path_full(self.dbstate.db, obj.get_path())
mime_type = obj.get_mime_type()
if mime_type and mime_type.startswith("image"):
self.photo.set_image(full_path, media_ref.get_rectangle())
self.photo.set_image(full_path, mime_type,
media_ref.get_rectangle())
else:
self.photo.set_image(None)
else:

View File

@ -42,7 +42,7 @@ class PlaceDetails(Gramplet):
"""
self.top = gtk.HBox()
vbox = gtk.VBox()
self.photo = Photo(190.0)
self.photo = Photo()
self.title = gtk.Label()
self.title.set_alignment(0, 0)
self.title.modify_font(pango.FontDescription('sans bold 12'))
@ -157,7 +157,8 @@ class PlaceDetails(Gramplet):
full_path = Utils.media_path_full(self.dbstate.db, obj.get_path())
mime_type = obj.get_mime_type()
if mime_type and mime_type.startswith("image"):
self.photo.set_image(full_path, media_ref.get_rectangle())
self.photo.set_image(full_path, mime_type,
media_ref.get_rectangle())
else:
self.photo.set_image(None)
else:

View File

@ -113,6 +113,8 @@ class RepositoryDetails(Gramplet):
self.display_url(repo, UrlType(UrlType.EMAIL))
self.display_url(repo, UrlType(UrlType.WEB_HOME))
self.display_url(repo, UrlType(UrlType.WEB_SEARCH))
self.display_url(repo, UrlType(UrlType.WEB_FTP))
def display_address(self, address):
"""