2007-09-10 Don Allingham <don@gramps-project.org>
* src/ThumbNails.py: Added to handle the thumbnailing routines * src/DataViews/_MediaView.py: thumbnail updates * src/DataViews/_PedigreeView.py: thumbnail updates * src/DataViews/_RelationView.py: thumbnail updates * src/Editors/_EditMediaRef.py: thumbnail updates * src/Editors/_EditMedia.py: thumbnail updates * src/DisplayTabs/_GalleryTab.py: thumbnail updates * src/plugins/WebCal.py: thumbnail updates * src/plugins/NarrativeWeb.py: thumbnail updates * src/plugins/GraphViz.py: thumbnail updates * src/plugins/SimpleBookTitle.py: thumbnail updates * src/plugins/FamilyLines.py: thumbnail updates * src/DbManager.py: pylint fixes * src/ImgManip.py: pull out thumbnail routines 2007-09-08 Benny Malengier <benny.malengier@gramps-project.org> * src/DataViews/_RelationView.py : expand/collapse, edit button on/off bug fix svn: r8958
This commit is contained in:
24
ChangeLog
24
ChangeLog
@@ -1,3 +1,19 @@
|
|||||||
|
2007-09-10 Don Allingham <don@gramps-project.org>
|
||||||
|
* src/ThumbNails.py: Added to handle the thumbnailing routines
|
||||||
|
* src/DataViews/_MediaView.py: thumbnail updates
|
||||||
|
* src/DataViews/_PedigreeView.py: thumbnail updates
|
||||||
|
* src/DataViews/_RelationView.py: thumbnail updates
|
||||||
|
* src/Editors/_EditMediaRef.py: thumbnail updates
|
||||||
|
* src/Editors/_EditMedia.py: thumbnail updates
|
||||||
|
* src/DisplayTabs/_GalleryTab.py: thumbnail updates
|
||||||
|
* src/plugins/WebCal.py: thumbnail updates
|
||||||
|
* src/plugins/NarrativeWeb.py: thumbnail updates
|
||||||
|
* src/plugins/GraphViz.py: thumbnail updates
|
||||||
|
* src/plugins/SimpleBookTitle.py: thumbnail updates
|
||||||
|
* src/plugins/FamilyLines.py: thumbnail updates
|
||||||
|
* src/DbManager.py: pylint fixes
|
||||||
|
* src/ImgManip.py: pull out thumbnail routines
|
||||||
|
|
||||||
2007-09-10 Brian Matherly <brian@gramps-project.org>
|
2007-09-10 Brian Matherly <brian@gramps-project.org>
|
||||||
* src/plugins/AncestorChart.py: Make max generations 15.
|
* src/plugins/AncestorChart.py: Make max generations 15.
|
||||||
|
|
||||||
@@ -26,8 +42,8 @@
|
|||||||
* src/DateEdit.py: code cleanup
|
* src/DateEdit.py: code cleanup
|
||||||
* src/DbLoader.py: code cleanup
|
* src/DbLoader.py: code cleanup
|
||||||
|
|
||||||
2007-09-08 Benny Malengier <benny.malengier@gramps-project.org>
|
2007-09-08 Benny Malengier <benny.malengier@gramps-project.org>
|
||||||
* src/DataViews/_RelationView.py : expand/collapse, edit button on/off bug fix
|
* src/DataViews/_RelationView.py : expand/collapse, edit button on/off bug fix
|
||||||
* src/GrampsWidgets.py : Expand widget, changes link labels
|
* src/GrampsWidgets.py : Expand widget, changes link labels
|
||||||
* src/DisplayState.py : history bugs
|
* src/DisplayState.py : history bugs
|
||||||
* src/ViewManager.py : history bugs
|
* src/ViewManager.py : history bugs
|
||||||
@@ -37,7 +53,7 @@
|
|||||||
|
|
||||||
2007-09-07 Don Allingham <don@gramps-project.org>
|
2007-09-07 Don Allingham <don@gramps-project.org>
|
||||||
* various: const.py changes
|
* various: const.py changes
|
||||||
|
|
||||||
2007-09-07 Don Allingham <don@gramps-project.org>
|
2007-09-07 Don Allingham <don@gramps-project.org>
|
||||||
* src/DateHandler/_Date_fr.py: fix indentation errors
|
* src/DateHandler/_Date_fr.py: fix indentation errors
|
||||||
|
|
||||||
@@ -45,7 +61,7 @@
|
|||||||
* src/ansel_utf8.py: pylint
|
* src/ansel_utf8.py: pylint
|
||||||
* src/Date.py: pylint
|
* src/Date.py: pylint
|
||||||
* src/Spell.py: pylint
|
* src/Spell.py: pylint
|
||||||
|
|
||||||
2007-09-07 Don Allingham <don@gramps-project.org>
|
2007-09-07 Don Allingham <don@gramps-project.org>
|
||||||
* src/GrampsDb/_DbBase.py: pylint
|
* src/GrampsDb/_DbBase.py: pylint
|
||||||
* src/GrampsDbUtils/_GedcomStageOne.py: added
|
* src/GrampsDbUtils/_GedcomStageOne.py: added
|
||||||
|
@@ -50,7 +50,7 @@ import gtk
|
|||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
import PageView
|
import PageView
|
||||||
import DisplayModels
|
import DisplayModels
|
||||||
import ImgManip
|
import ThumbNails
|
||||||
import const
|
import const
|
||||||
import Config
|
import Config
|
||||||
import Utils
|
import Utils
|
||||||
@@ -274,7 +274,7 @@ class MediaView(PageView.ListView):
|
|||||||
self.tt.enable()
|
self.tt.enable()
|
||||||
else:
|
else:
|
||||||
obj = self.dbstate.db.get_object_from_handle(handle)
|
obj = self.dbstate.db.get_object_from_handle(handle)
|
||||||
pix = ImgManip.get_thumbnail_image(obj.get_path())
|
pix = ThumbNails.get_thumbnail_image(obj.get_path())
|
||||||
self.image.set_from_pixbuf(pix)
|
self.image.set_from_pixbuf(pix)
|
||||||
self.tt.enable()
|
self.tt.enable()
|
||||||
|
|
||||||
|
@@ -54,7 +54,7 @@ import PageView
|
|||||||
from BasicUtils import name_displayer
|
from BasicUtils import name_displayer
|
||||||
import Utils
|
import Utils
|
||||||
import DateHandler
|
import DateHandler
|
||||||
import ImgManip
|
import ThumbNails
|
||||||
import Errors
|
import Errors
|
||||||
from ReportBase import ReportUtils
|
from ReportBase import ReportUtils
|
||||||
from Editors import EditPerson, EditFamily
|
from Editors import EditPerson, EditFamily
|
||||||
@@ -853,7 +853,7 @@ class PedigreeView(PageView.PersonNavView):
|
|||||||
if obj:
|
if obj:
|
||||||
mtype = obj.get_mime_type()
|
mtype = obj.get_mime_type()
|
||||||
if mtype and mtype[0:5] == "image":
|
if mtype and mtype[0:5] == "image":
|
||||||
image = ImgManip.get_thumbnail_path(obj.get_path())
|
image = ThumbNails.get_thumbnail_path(obj.get_path())
|
||||||
if cairo_available:
|
if cairo_available:
|
||||||
pw = PersonBoxWidget_cairo( self.format_helper, lst[i][0], lst[i][3], positions[i][0][3], image);
|
pw = PersonBoxWidget_cairo( self.format_helper, lst[i][0], lst[i][3], positions[i][0][3], image);
|
||||||
else:
|
else:
|
||||||
|
@@ -50,7 +50,7 @@ import RelLib
|
|||||||
import PageView
|
import PageView
|
||||||
from BasicUtils import name_displayer
|
from BasicUtils import name_displayer
|
||||||
import DateHandler
|
import DateHandler
|
||||||
import ImgManip
|
import ThumbNails
|
||||||
import Config
|
import Config
|
||||||
import GrampsWidgets
|
import GrampsWidgets
|
||||||
import Errors
|
import Errors
|
||||||
@@ -559,7 +559,7 @@ class RelationshipView(PageView.PersonNavView):
|
|||||||
if image_list:
|
if image_list:
|
||||||
mobj = self.dbstate.db.get_object_from_handle(image_list[0].ref)
|
mobj = self.dbstate.db.get_object_from_handle(image_list[0].ref)
|
||||||
if mobj.get_mime_type()[0:5] == "image":
|
if mobj.get_mime_type()[0:5] == "image":
|
||||||
pixbuf = ImgManip.get_thumbnail_image(mobj.get_path())
|
pixbuf = ThumbNails.get_thumbnail_image(mobj.get_path())
|
||||||
image = gtk.Image()
|
image = gtk.Image()
|
||||||
image.set_from_pixbuf(pixbuf)
|
image.set_from_pixbuf(pixbuf)
|
||||||
image.show()
|
image.show()
|
||||||
|
@@ -156,8 +156,8 @@ class DbManager:
|
|||||||
self.selection.connect('changed', self.__selection_changed)
|
self.selection.connect('changed', self.__selection_changed)
|
||||||
self.dblist.connect('button-press-event', self.__button_press)
|
self.dblist.connect('button-press-event', self.__button_press)
|
||||||
self.top.connect('drag_data_received', self.__drag_data_received)
|
self.top.connect('drag_data_received', self.__drag_data_received)
|
||||||
self.top.connect('drag_motion', self.__drag_motion)
|
self.top.connect('drag_motion', drag_motion)
|
||||||
self.top.connect('drag_drop', self.__drop_cb)
|
self.top.connect('drag_drop', drop_cb)
|
||||||
|
|
||||||
if RCS_FOUND:
|
if RCS_FOUND:
|
||||||
self.rcs.connect('clicked', self.__rcs)
|
self.rcs.connect('clicked', self.__rcs)
|
||||||
@@ -364,7 +364,7 @@ class DbManager:
|
|||||||
store.set_value(node, STOCK_COL, "")
|
store.set_value(node, STOCK_COL, "")
|
||||||
store.set_value(node, DATE_COL, last)
|
store.set_value(node, DATE_COL, last)
|
||||||
store.set_value(node, DSORT_COL, tval)
|
store.set_value(node, DSORT_COL, tval)
|
||||||
except:
|
except IOError:
|
||||||
return
|
return
|
||||||
|
|
||||||
def __change_name(self, text, path, new_text):
|
def __change_name(self, text, path, new_text):
|
||||||
@@ -649,14 +649,6 @@ class DbManager:
|
|||||||
start_editing=True)
|
start_editing=True)
|
||||||
return new_path
|
return new_path
|
||||||
|
|
||||||
def __drag_motion(self, wid, context, x, y, time):
|
|
||||||
context.drag_status(gtk.gdk.ACTION_COPY, time)
|
|
||||||
return True
|
|
||||||
|
|
||||||
def __drop_cb(self, wid, context, x, y, time):
|
|
||||||
context.finish(True, False, time)
|
|
||||||
return True
|
|
||||||
|
|
||||||
def __drag_data_received(self, widget, context, xpos, ypos, selection,
|
def __drag_data_received(self, widget, context, xpos, ypos, selection,
|
||||||
info, rtime):
|
info, rtime):
|
||||||
"""
|
"""
|
||||||
@@ -699,6 +691,21 @@ class DbManager:
|
|||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def drag_motion(wid, context, xpos, ypos, time_stamp):
|
||||||
|
"""
|
||||||
|
DND callback that is called on a DND drag motion begin
|
||||||
|
"""
|
||||||
|
context.drag_status(gtk.gdk.ACTION_COPY, time_stamp)
|
||||||
|
return True
|
||||||
|
|
||||||
|
def drop_cb(wid, context, xpos, ypos, time_stamp):
|
||||||
|
"""
|
||||||
|
DND callback that finishes the DND operation
|
||||||
|
"""
|
||||||
|
context.finish(True, False, time_stamp)
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
def find_next_db_name(name_list):
|
def find_next_db_name(name_list):
|
||||||
"""
|
"""
|
||||||
Scan the name list, looking for names that do not yet exist.
|
Scan the name list, looking for names that do not yet exist.
|
||||||
|
@@ -44,7 +44,7 @@ import os
|
|||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
import RelLib
|
import RelLib
|
||||||
import Utils
|
import Utils
|
||||||
import ImgManip
|
import ThumbNails
|
||||||
import Errors
|
import Errors
|
||||||
import Mime
|
import Mime
|
||||||
from DdTargets import DdTargets
|
from DdTargets import DdTargets
|
||||||
@@ -190,8 +190,8 @@ class GalleryTab(ButtonTab):
|
|||||||
for ref in self.media_list:
|
for ref in self.media_list:
|
||||||
handle = ref.get_reference_handle()
|
handle = ref.get_reference_handle()
|
||||||
obj = self.dbstate.db.get_object_from_handle(handle)
|
obj = self.dbstate.db.get_object_from_handle(handle)
|
||||||
pixbuf = ImgManip.get_thumbnail_image(obj.get_path(),
|
pixbuf = ThumbNails.get_thumbnail_image(obj.get_path(),
|
||||||
obj.get_mime_type())
|
obj.get_mime_type())
|
||||||
self.iconmodel.append(row=[pixbuf, obj.get_description(), ref])
|
self.iconmodel.append(row=[pixbuf, obj.get_description(), ref])
|
||||||
self._connect_icon_model()
|
self._connect_icon_model()
|
||||||
self._set_label()
|
self._set_label()
|
||||||
|
@@ -45,7 +45,7 @@ import const
|
|||||||
import Config
|
import Config
|
||||||
import RelLib
|
import RelLib
|
||||||
import Mime
|
import Mime
|
||||||
import ImgManip
|
import ThumbNails
|
||||||
from _EditPrimary import EditPrimary
|
from _EditPrimary import EditPrimary
|
||||||
|
|
||||||
from GrampsWidgets import *
|
from GrampsWidgets import *
|
||||||
@@ -126,7 +126,7 @@ class EditMedia(EditPrimary):
|
|||||||
|
|
||||||
mtype = self.obj.get_mime_type()
|
mtype = self.obj.get_mime_type()
|
||||||
if mtype:
|
if mtype:
|
||||||
pb = ImgManip.get_thumbnail_image(self.obj.get_path(),mtype)
|
pb = ThumbNails.get_thumbnail_image(self.obj.get_path(),mtype)
|
||||||
pixmap.set_from_pixbuf(pb)
|
pixmap.set_from_pixbuf(pb)
|
||||||
ebox.connect('button-press-event', self.button_press_event)
|
ebox.connect('button-press-event', self.button_press_event)
|
||||||
descr = Mime.get_description(mtype)
|
descr = Mime.get_description(mtype)
|
||||||
|
@@ -42,7 +42,7 @@ import gtk
|
|||||||
import const
|
import const
|
||||||
import Config
|
import Config
|
||||||
import Mime
|
import Mime
|
||||||
import ImgManip
|
import ThumbNails
|
||||||
from RelLib import NoteType
|
from RelLib import NoteType
|
||||||
|
|
||||||
from DisplayTabs import \
|
from DisplayTabs import \
|
||||||
@@ -79,7 +79,7 @@ class EditMediaRef(EditReference):
|
|||||||
|
|
||||||
mtype = self.source.get_mime_type()
|
mtype = self.source.get_mime_type()
|
||||||
|
|
||||||
self.pix = ImgManip.get_thumbnail_image(self.source.get_path(),mtype)
|
self.pix = ThumbNails.get_thumbnail_image(self.source.get_path(),mtype)
|
||||||
self.pixmap = self.top.get_widget("pixmap")
|
self.pixmap = self.top.get_widget("pixmap")
|
||||||
ebox = self.top.get_widget('eventbox')
|
ebox = self.top.get_widget('eventbox')
|
||||||
ebox.connect('button-press-event', self.button_press_event)
|
ebox.connect('button-press-event', self.button_press_event)
|
||||||
|
114
src/ImgManip.py
114
src/ImgManip.py
@@ -8,7 +8,7 @@
|
|||||||
# the Free Software Foundation; either version 2 of the License, or
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
# (at your option) any later version.
|
# (at your option) any later version.
|
||||||
#
|
#
|
||||||
# This program is distributed in the hope that it will be useful,
|
# This program is distributed in the hope that it will be useful,
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
# GNU General Public License for more details.
|
# GNU General Public License for more details.
|
||||||
@@ -20,6 +20,11 @@
|
|||||||
|
|
||||||
# $Id$
|
# $Id$
|
||||||
|
|
||||||
|
"""
|
||||||
|
Image manipulation routines.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
#
|
#
|
||||||
# Standard python modules
|
# Standard python modules
|
||||||
@@ -49,10 +54,13 @@ import Utils
|
|||||||
|
|
||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
#
|
#
|
||||||
#
|
# ImgManip
|
||||||
#
|
#
|
||||||
#-------------------------------------------------------------------------
|
#-------------------------------------------------------------------------
|
||||||
class ImgManip:
|
class ImgManip:
|
||||||
|
"""
|
||||||
|
Image manipulation class
|
||||||
|
"""
|
||||||
def __init__(self, source):
|
def __init__(self, source):
|
||||||
self.src = source
|
self.src = source
|
||||||
try:
|
try:
|
||||||
@@ -64,52 +72,50 @@ class ImgManip:
|
|||||||
self.height = 0
|
self.height = 0
|
||||||
|
|
||||||
def size(self):
|
def size(self):
|
||||||
|
"""
|
||||||
|
Returns a tuple consisting of the width, height of the image in pixels.
|
||||||
|
|
||||||
|
@rtype width and height of the image in pixels
|
||||||
|
@return tuple of two integers
|
||||||
|
"""
|
||||||
return (self.width, self.height)
|
return (self.width, self.height)
|
||||||
|
|
||||||
def fmt_thumbnail(self,dest,width,height,cnv):
|
|
||||||
scaled = self.img.scale_simple(width, height, gtk.gdk.INTERP_BILINEAR)
|
|
||||||
scaled.save(dest,cnv)
|
|
||||||
|
|
||||||
def fmt_data(self, cnv):
|
|
||||||
fd, dest = tempfile.mkstemp()
|
|
||||||
self.img.save(dest,cnv)
|
|
||||||
fh = open(dest,mode='rb')
|
|
||||||
data = fh.read()
|
|
||||||
fh.close()
|
|
||||||
try:
|
|
||||||
os.unlink(dest)
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
return data
|
|
||||||
|
|
||||||
def fmt_scale_data(self, x, y, cnv):
|
|
||||||
fd, dest = tempfile.mkstemp()
|
|
||||||
scaled = self.img.scale_simple(int(x), int(y), gtk.gdk.INTERP_BILINEAR)
|
|
||||||
scaled.save(dest,cnv)
|
|
||||||
fh = open(dest,mode='rb')
|
|
||||||
data = fh.read()
|
|
||||||
fh.close()
|
|
||||||
try:
|
|
||||||
os.unlink(dest)
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
return data
|
|
||||||
|
|
||||||
def jpg_thumbnail(self, dest, width, height):
|
def jpg_thumbnail(self, dest, width, height):
|
||||||
self.fmt_thumbnail(dest, width, height, "jpeg")
|
"""
|
||||||
|
@type dest: unicode
|
||||||
def jpg_data(self):
|
@param dest : target filename
|
||||||
return self.fmt_data("jpeg")
|
@type width: int
|
||||||
|
@param width: desired width of the image
|
||||||
|
@type height: int
|
||||||
|
@param height: desired height of the image
|
||||||
|
"""
|
||||||
|
scaled = self.img.scale_simple(width, height, gtk.gdk.INTERP_BILINEAR)
|
||||||
|
scaled.save(dest, 'jpeg')
|
||||||
|
|
||||||
def png_data(self):
|
def png_data(self):
|
||||||
return self.fmt_data("png")
|
fd, dest = tempfile.mkstemp()
|
||||||
|
self.img.save(dest, "png")
|
||||||
|
fh = open(dest, mode='rb')
|
||||||
|
data = fh.read()
|
||||||
|
fh.close()
|
||||||
|
try:
|
||||||
|
os.unlink(dest)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
return data
|
||||||
|
|
||||||
def jpg_scale_data(self, x, y):
|
def jpg_scale_data(self, x, y):
|
||||||
return self.fmt_scale_data(x, y, "jpeg")
|
fd, dest = tempfile.mkstemp()
|
||||||
|
scaled = self.img.scale_simple(int(x), int(y), gtk.gdk.INTERP_BILINEAR)
|
||||||
def png_scale_data(self,x,y):
|
scaled.save(dest, 'jpeg')
|
||||||
return self.fmt_scale_data(x, y, "png")
|
fh = open(dest, mode='rb')
|
||||||
|
data = fh.read()
|
||||||
|
fh.close()
|
||||||
|
try:
|
||||||
|
os.unlink(dest)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
return data
|
||||||
|
|
||||||
def _build_thumb_path(path):
|
def _build_thumb_path(path):
|
||||||
m = md5.md5(path)
|
m = md5.md5(path)
|
||||||
@@ -118,18 +124,18 @@ def _build_thumb_path(path):
|
|||||||
def run_thumbnailer(mtype, frm, to, size=const.THUMBSCALE):
|
def run_thumbnailer(mtype, frm, to, size=const.THUMBSCALE):
|
||||||
if const.USE_THUMBNAILER and os.path.isfile(frm):
|
if const.USE_THUMBNAILER and os.path.isfile(frm):
|
||||||
sublist = {
|
sublist = {
|
||||||
'%s' : "%dx%d" % (int(size),int(size)),
|
'%s' : "%dx%d" % (int(size), int(size)),
|
||||||
'%u' : frm,
|
'%u' : frm,
|
||||||
'%o' : to,
|
'%o' : to,
|
||||||
}
|
}
|
||||||
|
|
||||||
base = '/desktop/gnome/thumbnailers/%s' % mtype.replace('/','@')
|
base = '/desktop/gnome/thumbnailers/%s' % mtype.replace('/', '@')
|
||||||
|
|
||||||
cmd = Config.get_string(base + '/command')
|
cmd = Config.get_string(base + '/command')
|
||||||
enable = Config.get_bool(base + '/enable')
|
enable = Config.get_bool(base + '/enable')
|
||||||
|
|
||||||
if cmd and enable:
|
if cmd and enable:
|
||||||
cmdlist = map(lambda x: sublist.get(x,x),cmd.split())
|
cmdlist = map(lambda x: sublist.get(x, x), cmd.split())
|
||||||
os.spawnvpe(os.P_WAIT, cmdlist[0], cmdlist, os.environ)
|
os.spawnvpe(os.P_WAIT, cmdlist[0], cmdlist, os.environ)
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
@@ -138,19 +144,19 @@ def run_thumbnailer(mtype, frm, to, size=const.THUMBSCALE):
|
|||||||
|
|
||||||
def set_thumbnail_image(path, mtype=None):
|
def set_thumbnail_image(path, mtype=None):
|
||||||
if mtype and not mtype.startswith('image/'):
|
if mtype and not mtype.startswith('image/'):
|
||||||
run_thumbnailer(mtype,path,_build_thumb_path(path))
|
run_thumbnailer(mtype, path, _build_thumb_path(path))
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
pixbuf = gtk.gdk.pixbuf_new_from_file(path)
|
pixbuf = gtk.gdk.pixbuf_new_from_file(path)
|
||||||
w = pixbuf.get_width()
|
w = pixbuf.get_width()
|
||||||
h = pixbuf.get_height()
|
h = pixbuf.get_height()
|
||||||
scale = const.THUMBSCALE / (float(max(w,h)))
|
scale = const.THUMBSCALE / (float(max(w, h)))
|
||||||
|
|
||||||
pw = int(w*scale)
|
pw = int(w*scale)
|
||||||
ph = int(h*scale)
|
ph = int(h*scale)
|
||||||
|
|
||||||
pixbuf = pixbuf.scale_simple(pw,ph,gtk.gdk.INTERP_BILINEAR)
|
pixbuf = pixbuf.scale_simple(pw, ph, gtk.gdk.INTERP_BILINEAR)
|
||||||
pixbuf.save(_build_thumb_path(path),"png")
|
pixbuf.save(_build_thumb_path(path), "png")
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@@ -160,21 +166,21 @@ def get_thumbnail_image(path, mtype=None):
|
|||||||
try:
|
try:
|
||||||
path = Utils.find_file( path)
|
path = Utils.find_file( path)
|
||||||
if not os.path.isfile(filename):
|
if not os.path.isfile(filename):
|
||||||
set_thumbnail_image(path,mtype)
|
set_thumbnail_image(path, mtype)
|
||||||
elif os.path.getmtime(path) > os.path.getmtime(filename):
|
elif os.path.getmtime(path) > os.path.getmtime(filename):
|
||||||
set_thumbnail_image(path,mtype)
|
set_thumbnail_image(path, mtype)
|
||||||
return gtk.gdk.pixbuf_new_from_file(filename)
|
return gtk.gdk.pixbuf_new_from_file(filename)
|
||||||
except (gobject.GError, OSError):
|
except (gobject.GError, OSError):
|
||||||
if mtype:
|
if mtype:
|
||||||
return Mime.find_mime_type_pixbuf(mtype)
|
return Mime.find_mime_type_pixbuf(mtype)
|
||||||
else:
|
else:
|
||||||
return gtk.gdk.pixbuf_new_from_file(os.path.join(
|
return gtk.gdk.pixbuf_new_from_file(os.path.join(
|
||||||
const.IMAGE_DIR,"document.png"))
|
const.IMAGE_DIR, "document.png"))
|
||||||
|
|
||||||
def get_thumbnail_path(path, mtype=None):
|
def get_thumbnail_path(path, mtype=None):
|
||||||
filename = _build_thumb_path(path)
|
filename = _build_thumb_path(path)
|
||||||
if not os.path.isfile(filename):
|
if not os.path.isfile(filename):
|
||||||
set_thumbnail_image(path,mtype)
|
set_thumbnail_image(path, mtype)
|
||||||
return filename
|
return filename
|
||||||
|
|
||||||
def get_thumb_from_obj(obj):
|
def get_thumb_from_obj(obj):
|
||||||
|
271
src/ThumbNails.py
Normal file
271
src/ThumbNails.py
Normal file
@@ -0,0 +1,271 @@
|
|||||||
|
#
|
||||||
|
# Gramps - a GTK+/GNOME based genealogy program
|
||||||
|
#
|
||||||
|
# Copyright (C) 2000-2006 Donald N. Allingham
|
||||||
|
#
|
||||||
|
# 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
|
||||||
|
#
|
||||||
|
|
||||||
|
# $Id: ImgManip.py 8948 2007-09-08 05:54:02Z dallingham $
|
||||||
|
|
||||||
|
"""
|
||||||
|
Handles generation and access to thumbnails used in GRAMPS.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# Standard python modules
|
||||||
|
#
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
import os
|
||||||
|
import md5
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# GTK/Gnome modules
|
||||||
|
#
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
import gtk
|
||||||
|
import gobject
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# gramps modules
|
||||||
|
#
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
import const
|
||||||
|
import Mime
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# gconf - try loading gconf for GNOME based systems. If we find it, we
|
||||||
|
# might be able to generate thumbnails for non-image files.
|
||||||
|
#
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
try:
|
||||||
|
import gconf
|
||||||
|
GCONF = True
|
||||||
|
CLIENT = gconf.client_get_default()
|
||||||
|
except ImportError:
|
||||||
|
GCONF = False
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# __get_gconf_string
|
||||||
|
#
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
def __get_gconf_string(key):
|
||||||
|
"""
|
||||||
|
Attempt to retrieve a value from the GNOME gconf database based of the
|
||||||
|
passed key.
|
||||||
|
|
||||||
|
@param key: GCONF key
|
||||||
|
@type key: unicode
|
||||||
|
@returns: Value associated with the GCONF key
|
||||||
|
@rtype: unicode
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
val = CLIENT.get_string(key)
|
||||||
|
except gobject.GError:
|
||||||
|
val = None
|
||||||
|
return unicode(val)
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# __get_gconf_bool
|
||||||
|
#
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
def __get_gconf_bool(key):
|
||||||
|
"""
|
||||||
|
Attempt to retrieve a value from the GNOME gconf database based of the
|
||||||
|
passed key.
|
||||||
|
|
||||||
|
@param key: GCONF key
|
||||||
|
@type key: unicode
|
||||||
|
@returns: Value associated with the GCONF key
|
||||||
|
@rtype: bool
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
val = CLIENT.get_bool(key)
|
||||||
|
except gobject.GError:
|
||||||
|
val = None
|
||||||
|
return val
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# __build_thumb_path
|
||||||
|
#
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
def __build_thumb_path(path):
|
||||||
|
"""
|
||||||
|
Converts the specified path into a corresponding path for the thumbnail
|
||||||
|
image. We do this by converting the original path into an MD5SUM value
|
||||||
|
(which should be unique), adding the '.png' extension, and prepending
|
||||||
|
with the GRAMPS thumbnail directory.
|
||||||
|
|
||||||
|
@type path: unicode
|
||||||
|
@param path: filename of the source file
|
||||||
|
@rtype: unicode
|
||||||
|
@returns: full path name to the corresponding thumbnail file.
|
||||||
|
"""
|
||||||
|
md5_hash = md5.md5(path)
|
||||||
|
return os.path.join(const.THUMB_DIR, md5_hash.hexdigest()+'.png')
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# __create_thumbnail_image
|
||||||
|
#
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
def __create_thumbnail_image(src_file, mtype=None):
|
||||||
|
"""
|
||||||
|
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
|
||||||
|
utility to create a thumbnail. For images, we simply create a smaller
|
||||||
|
image, scaled to thumbnail size.
|
||||||
|
|
||||||
|
@param src_file: filename of the source file
|
||||||
|
@type src_file: unicode
|
||||||
|
@param mtype: mime type of the specified file (optional)
|
||||||
|
@type mtype: unicode
|
||||||
|
"""
|
||||||
|
filename = __build_thumb_path(src_file)
|
||||||
|
|
||||||
|
if mtype and not mtype.startswith('image/'):
|
||||||
|
# Not an image, so run the thumbnailer
|
||||||
|
run_thumbnailer(mtype, src_file, filename)
|
||||||
|
else:
|
||||||
|
# build a thumbnail by scaling the image using GTK's built in
|
||||||
|
# routines.
|
||||||
|
try:
|
||||||
|
pixbuf = gtk.gdk.pixbuf_new_from_file(src_file)
|
||||||
|
width = pixbuf.get_width()
|
||||||
|
height = pixbuf.get_height()
|
||||||
|
scale = const.THUMBSCALE / (float(max(width, height)))
|
||||||
|
|
||||||
|
scaled_width = int(width * scale)
|
||||||
|
scaled_height = int(height * scale)
|
||||||
|
|
||||||
|
pixbuf = pixbuf.scale_simple(scaled_width, scaled_height,
|
||||||
|
gtk.gdk.INTERP_BILINEAR)
|
||||||
|
pixbuf.save(filename, "png")
|
||||||
|
except:
|
||||||
|
return
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# run_thumbnailer
|
||||||
|
#
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
def run_thumbnailer(mime_type, src_file, dest_file, size=const.THUMBSCALE):
|
||||||
|
"""
|
||||||
|
This function attempts to generate a thumbnail image for a non-image.
|
||||||
|
This includes things such as video and PDF files. This will currently
|
||||||
|
only succeed if the GNOME environment is installed, since at this point,
|
||||||
|
only the GNOME environment has the ability to generate thumbnails.
|
||||||
|
|
||||||
|
@param mime_type: mime type of the source file
|
||||||
|
@type mime_type: unicode
|
||||||
|
@param src_file: filename of the source file
|
||||||
|
@type src_file: unicode
|
||||||
|
@param dest_file: destination file for the thumbnail image
|
||||||
|
@type dest_file: unicode
|
||||||
|
@param size: option parameters specifying the desired size of the
|
||||||
|
thumbnail
|
||||||
|
@type size: int
|
||||||
|
@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):
|
||||||
|
|
||||||
|
# find the command and enable for the associated mime types by
|
||||||
|
# querying the gconf database
|
||||||
|
base = '/desktop/gnome/thumbnailers/%s' % mime_type.replace('/', '@')
|
||||||
|
cmd = __get_gconf_string(base + '/command')
|
||||||
|
enable = __get_gconf_bool(base + '/enable')
|
||||||
|
|
||||||
|
# if we found the command and it has been enabled, then spawn
|
||||||
|
# of the command to build the thumbnail
|
||||||
|
if cmd and enable:
|
||||||
|
sublist = {
|
||||||
|
'%s' : "%d" % int(size),
|
||||||
|
'%u' : src_file,
|
||||||
|
'%o' : dest_file,
|
||||||
|
}
|
||||||
|
cmdlist = [ sublist.get(x, x) for x in cmd.split() ]
|
||||||
|
os.spawnvpe(os.P_WAIT, cmdlist[0], cmdlist, os.environ)
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# get_thumbnail_image
|
||||||
|
#
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
def get_thumbnail_image(src_file, mtype=None):
|
||||||
|
"""
|
||||||
|
Returns the thumbnail image (in GTK Pixbuf format) associated with the
|
||||||
|
source file passed to the function. If no thumbnail could be found,
|
||||||
|
the associated icon for the mime type is returned, or if that cannot be
|
||||||
|
found, a generic document icon is returned.
|
||||||
|
|
||||||
|
The image is not generated everytime, but only if the thumbnail does not
|
||||||
|
exist, or if the source file is newer than the thumbnail.
|
||||||
|
|
||||||
|
@param src_file: Source media file
|
||||||
|
@type src_file: unicode
|
||||||
|
@param mime_type: mime type of the source file
|
||||||
|
@type mime_type: unicode
|
||||||
|
@returns: thumbnail representing the source file
|
||||||
|
@rtype: gtk.gdk.Pixbuf
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
filename = get_thumbnail_path(src_file, mtype)
|
||||||
|
return gtk.gdk.pixbuf_new_from_file(filename)
|
||||||
|
except (gobject.GError, OSError):
|
||||||
|
if mtype:
|
||||||
|
return Mime.find_mime_type_pixbuf(mtype)
|
||||||
|
else:
|
||||||
|
default = os.path.join(const.IMAGE_DIR, "document.png")
|
||||||
|
return gtk.gdk.pixbuf_new_from_file(default)
|
||||||
|
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# get_thumbnail_path
|
||||||
|
#
|
||||||
|
#-------------------------------------------------------------------------
|
||||||
|
def get_thumbnail_path(src_file, mtype=None):
|
||||||
|
"""
|
||||||
|
Returns the path to the thumbnail image associated with the
|
||||||
|
source file passed to the function. If the thumbnail does not exist,
|
||||||
|
or if it is older than the source file, we create a new thumbnail image.
|
||||||
|
|
||||||
|
@param src_file: Source media file
|
||||||
|
@type src_file: unicode
|
||||||
|
@param mime_type: mime type of the source file
|
||||||
|
@type mime_type: unicode
|
||||||
|
@returns: thumbnail representing the source file
|
||||||
|
@rtype: gtk.gdk.Pixbuf
|
||||||
|
"""
|
||||||
|
filename = __build_thumb_path(src_file)
|
||||||
|
if not os.path.isfile(filename):
|
||||||
|
__create_thumbnail_image(src_file, mtype)
|
||||||
|
elif os.path.getmtime(src_file) > os.path.getmtime(filename):
|
||||||
|
__create_thumbnail_image(src_file, mtype)
|
||||||
|
return os.path.abspath(filename)
|
||||||
|
|
@@ -58,7 +58,7 @@ import RelLib
|
|||||||
import Config
|
import Config
|
||||||
import Errors
|
import Errors
|
||||||
import Utils
|
import Utils
|
||||||
import ImgManip
|
import ThumbNails
|
||||||
import DateHandler
|
import DateHandler
|
||||||
import GrampsWidgets
|
import GrampsWidgets
|
||||||
import ManagedWindow
|
import ManagedWindow
|
||||||
@@ -580,7 +580,7 @@ class FamilyLinesReport(Report):
|
|||||||
media = self.db.get_object_from_handle(mediaHandle)
|
media = self.db.get_object_from_handle(mediaHandle)
|
||||||
mediaMimeType = media.get_mime_type()
|
mediaMimeType = media.get_mime_type()
|
||||||
if mediaMimeType[0:5] == "image":
|
if mediaMimeType[0:5] == "image":
|
||||||
imagePath = os.path.abspath(ImgManip.get_thumbnail_path(media.get_path()))
|
imagePath = ThumbNails.get_thumbnail_path(media.get_path())
|
||||||
|
|
||||||
# put the label together and ouput this person
|
# put the label together and ouput this person
|
||||||
label = u""
|
label = u""
|
||||||
|
@@ -71,7 +71,7 @@ from QuestionDialog import ErrorDialog
|
|||||||
import Errors
|
import Errors
|
||||||
import Utils
|
import Utils
|
||||||
import Mime
|
import Mime
|
||||||
import ImgManip
|
import ThumbNails
|
||||||
|
|
||||||
#------------------------------------------------------------------------
|
#------------------------------------------------------------------------
|
||||||
#
|
#
|
||||||
@@ -542,7 +542,7 @@ just use iconv:
|
|||||||
media = self.database.get_object_from_handle(mediaHandle)
|
media = self.database.get_object_from_handle(mediaHandle)
|
||||||
mediaMimeType = media.get_mime_type()
|
mediaMimeType = media.get_mime_type()
|
||||||
if mediaMimeType[0:5] == "image":
|
if mediaMimeType[0:5] == "image":
|
||||||
imagePath = os.path.abspath(ImgManip.get_thumbnail_path(media.get_path()))
|
imagePath = ThumbNails.get_thumbnail_path(media.get_path())
|
||||||
#test if thumbnail actually exists in thumbs (import of data means media files might not be present
|
#test if thumbnail actually exists in thumbs (import of data means media files might not be present
|
||||||
imagePath = Utils.find_file(imagePath)
|
imagePath = Utils.find_file(imagePath)
|
||||||
|
|
||||||
|
@@ -74,7 +74,7 @@ from ReportBase._ReportDialog import ReportDialog
|
|||||||
from ReportBase._CommandLineReport import CommandLineReport
|
from ReportBase._CommandLineReport import CommandLineReport
|
||||||
import Errors
|
import Errors
|
||||||
import Utils
|
import Utils
|
||||||
import ImgManip
|
import ThumbNails
|
||||||
import GrampsLocale
|
import GrampsLocale
|
||||||
from QuestionDialog import ErrorDialog, WarningDialog
|
from QuestionDialog import ErrorDialog, WarningDialog
|
||||||
from BasicUtils import name_displayer as _nd
|
from BasicUtils import name_displayer as _nd
|
||||||
@@ -1087,7 +1087,7 @@ class MediaPage(BasePage):
|
|||||||
|
|
||||||
dirname = tempfile.mkdtemp()
|
dirname = tempfile.mkdtemp()
|
||||||
thmb_path = os.path.join(dirname,"temp.png")
|
thmb_path = os.path.join(dirname,"temp.png")
|
||||||
if ImgManip.run_thumbnailer(mime_type, photo.get_path(), thmb_path, 320):
|
if ThumbNails.run_thumbnailer(mime_type, photo.get_path(), thmb_path, 320):
|
||||||
try:
|
try:
|
||||||
path = "%s/%s.png" % (self.build_path(photo.handle,"preview"),photo.handle)
|
path = "%s/%s.png" % (self.build_path(photo.handle,"preview"),photo.handle)
|
||||||
self.store_file(archive, self.html_dir, thmb_path, path)
|
self.store_file(archive, self.html_dir, thmb_path, path)
|
||||||
@@ -1190,7 +1190,7 @@ class MediaPage(BasePage):
|
|||||||
to_dir = self.build_path(handle,'thumb')
|
to_dir = self.build_path(handle,'thumb')
|
||||||
to_path = os.path.join(to_dir,handle+".png")
|
to_path = os.path.join(to_dir,handle+".png")
|
||||||
if photo.get_mime_type():
|
if photo.get_mime_type():
|
||||||
from_path = ImgManip.get_thumbnail_path(photo.get_path(),photo.get_mime_type())
|
from_path = ThumbNails.get_thumbnail_path(photo.get_path(),photo.get_mime_type())
|
||||||
if not os.path.isfile(from_path):
|
if not os.path.isfile(from_path):
|
||||||
from_path = os.path.join(const.IMAGE_DIR,"document.png")
|
from_path = os.path.join(const.IMAGE_DIR,"document.png")
|
||||||
else:
|
else:
|
||||||
|
@@ -46,7 +46,7 @@ import BaseDoc
|
|||||||
from Selectors import selector_factory
|
from Selectors import selector_factory
|
||||||
SelectObject = selector_factory('MediaObject')
|
SelectObject = selector_factory('MediaObject')
|
||||||
import AddMedia
|
import AddMedia
|
||||||
import ImgManip
|
import ThumbNails
|
||||||
|
|
||||||
#------------------------------------------------------------------------
|
#------------------------------------------------------------------------
|
||||||
#
|
#
|
||||||
@@ -253,8 +253,8 @@ class SimpleBookTitleOptions(ReportOptions):
|
|||||||
return
|
return
|
||||||
self.options_dict['imgid'] = the_object.get_gramps_id()
|
self.options_dict['imgid'] = the_object.get_gramps_id()
|
||||||
self.obj_title.set_text(the_object.get_description())
|
self.obj_title.set_text(the_object.get_description())
|
||||||
icon_image = ImgManip.get_thumbnail_image(the_object.get_path(),
|
icon_image = ThumbNails.get_thumbnail_image(the_object.get_path(),
|
||||||
the_object.get_mime_type())
|
the_object.get_mime_type())
|
||||||
self.preview.set_from_pixbuf(icon_image)
|
self.preview.set_from_pixbuf(icon_image)
|
||||||
self.remove_obj_button.set_sensitive(True)
|
self.remove_obj_button.set_sensitive(True)
|
||||||
self.size.set_sensitive(True)
|
self.size.set_sensitive(True)
|
||||||
|
@@ -78,7 +78,6 @@ from ReportBase import Report, ReportUtils, ReportOptions, \
|
|||||||
from ReportBase._ReportDialog import ReportDialog
|
from ReportBase._ReportDialog import ReportDialog
|
||||||
import Errors
|
import Errors
|
||||||
import Utils
|
import Utils
|
||||||
import ImgManip
|
|
||||||
import GrampsLocale
|
import GrampsLocale
|
||||||
from QuestionDialog import ErrorDialog, WarningDialog
|
from QuestionDialog import ErrorDialog, WarningDialog
|
||||||
from Utils import probably_alive
|
from Utils import probably_alive
|
||||||
|
Reference in New Issue
Block a user