diff --git a/src/ThumbNails.py b/src/ThumbNails.py index d2239d2b6..9dba147ba 100644 --- a/src/ThumbNails.py +++ b/src/ThumbNails.py @@ -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) diff --git a/src/const.py.in b/src/const.py.in index d78c4cdc6..e0b63e444 100644 --- a/src/const.py.in +++ b/src/const.py.in @@ -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") @@ -226,10 +228,11 @@ TRANSLATORS = _('TRANSLATORS: Translate this to your ' # Constants # #------------------------------------------------------------------------- -THUMBSCALE = 96.0 -XMLFILE = "data.gramps" -NO_SURNAME = "(%s)" % _("none") -NO_GIVEN = "(%s)" % _("none") +THUMBSCALE = 96.0 +THUMBSCALE_LARGE = 180.0 +XMLFILE = "data.gramps" +NO_SURNAME = "(%s)" % _("none") +NO_GIVEN = "(%s)" % _("none") #------------------------------------------------------------------------- # diff --git a/src/gui/widgets/photo.py b/src/gui/widgets/photo.py index e583eb44d..b90f33619 100644 --- a/src/gui/widgets/photo.py +++ b/src/gui/widgets/photo.py @@ -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 diff --git a/src/plugins/gramplet/Gallery.py b/src/plugins/gramplet/Gallery.py index df54d27e2..292853577 100644 --- a/src/plugins/gramplet/Gallery.py +++ b/src/plugins/gramplet/Gallery.py @@ -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() diff --git a/src/plugins/gramplet/MediaPreview.py b/src/plugins/gramplet/MediaPreview.py index 64c078c5b..0c36d2923 100644 --- a/src/plugins/gramplet/MediaPreview.py +++ b/src/plugins/gramplet/MediaPreview.py @@ -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) diff --git a/src/plugins/gramplet/PersonDetails.py b/src/plugins/gramplet/PersonDetails.py index f33e12a37..2995f6d14 100644 --- a/src/plugins/gramplet/PersonDetails.py +++ b/src/plugins/gramplet/PersonDetails.py @@ -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: diff --git a/src/plugins/gramplet/PlaceDetails.py b/src/plugins/gramplet/PlaceDetails.py index f6213115a..b51eabdb0 100644 --- a/src/plugins/gramplet/PlaceDetails.py +++ b/src/plugins/gramplet/PlaceDetails.py @@ -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: diff --git a/src/plugins/gramplet/RepositoryDetails.py b/src/plugins/gramplet/RepositoryDetails.py index 3b8cc5b0e..b0685f922 100644 --- a/src/plugins/gramplet/RepositoryDetails.py +++ b/src/plugins/gramplet/RepositoryDetails.py @@ -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): """