Gallery drag/drop functionality
svn: r1169
This commit is contained in:
parent
2f9f1660ee
commit
9b2933bee0
Binary file not shown.
@ -1426,7 +1426,6 @@ def disp_url(url):
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
def disp_attr(attr):
|
||||
detail = Utils.get_detail_flags(attr)
|
||||
return [const.display_pattr(attr.getType()),attr.getValue()]
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
@ -1444,7 +1443,6 @@ def disp_addr(addr):
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
def disp_event(event):
|
||||
attr = Utils.get_detail_flags(event)
|
||||
return [const.display_pevent(event.getName()),event.getDescription(),
|
||||
event.getQuoteDate(),event.getPlaceName()]
|
||||
|
||||
|
@ -62,6 +62,7 @@ from intl import gettext as _
|
||||
|
||||
_IMAGEX = 140
|
||||
_IMAGEY = 150
|
||||
_PAD = 5
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
@ -77,9 +78,12 @@ class ImageSelect:
|
||||
self.path = path;
|
||||
self.db = db
|
||||
self.dataobj = None
|
||||
self.parent = parent
|
||||
self.canvas_list = []
|
||||
|
||||
self.parent = parent
|
||||
self.canvas_list = {}
|
||||
self.item_map = {}
|
||||
self.item_map = {}
|
||||
self.p_map = {}
|
||||
|
||||
def add_thumbnail(self, photo):
|
||||
"should be overrridden"
|
||||
pass
|
||||
@ -189,6 +193,13 @@ class ImageSelect:
|
||||
"""Save the photo in the dataobj object - must be overridden"""
|
||||
pass
|
||||
|
||||
_drag_targets = [
|
||||
('STRING', 0, 0),
|
||||
('text/plain',0,0),
|
||||
('text/uri-list',0,2),
|
||||
('application/x-rootwin-drop',0,1)]
|
||||
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
# Gallery class - This class handles all the logic underlying a
|
||||
@ -200,22 +211,15 @@ class Gallery(ImageSelect):
|
||||
def __init__(self, dataobj, path, icon_list, db, parent):
|
||||
ImageSelect.__init__(self, path, db, parent)
|
||||
|
||||
t = [
|
||||
('STRING', 0, 0),
|
||||
('text/plain',0,0),
|
||||
('text/uri-list',0,2),
|
||||
('application/x-rootwin-drop',0,1)]
|
||||
|
||||
if path:
|
||||
icon_list.drag_dest_set(gtk.DEST_DEFAULT_ALL, t,
|
||||
icon_list.drag_dest_set(gtk.DEST_DEFAULT_ALL, _drag_targets,
|
||||
gtk.gdk.ACTION_COPY | gtk.gdk.ACTION_MOVE)
|
||||
icon_list.connect('event',self.item_event)
|
||||
icon_list.connect("drag_data_received",
|
||||
self.on_photolist_drag_data_received)
|
||||
icon_list.drag_source_set(gtk.gdk.BUTTON1_MASK|gtk.gdk.BUTTON3_MASK,t,
|
||||
gtk.gdk.ACTION_COPY | gtk.gdk.ACTION_MOVE)
|
||||
icon_list.connect("drag_data_get",
|
||||
self.on_photolist_drag_data_get)
|
||||
|
||||
|
||||
# Remember arguments
|
||||
self.path = path;
|
||||
self.dataobj = dataobj;
|
||||
@ -226,24 +230,60 @@ class Gallery(ImageSelect):
|
||||
self.selectedIcon = -1
|
||||
self.x = 0
|
||||
self.y = 0
|
||||
self.remember_x = -1
|
||||
self.remember_y = -1
|
||||
self.button = None
|
||||
self.drag_item = None
|
||||
self.sel = None
|
||||
self.photo = None
|
||||
|
||||
def on_canvas1_event(self,obj,event):
|
||||
"""Handle resize events over the canvas, redrawing if the size changes"""
|
||||
|
||||
def item_event(self, widget, event=None):
|
||||
|
||||
if self.button and event.type == gtk.gdk.MOTION_NOTIFY :
|
||||
if widget.drag_check_threshold(self.remember_x,self.remember_y,event.x,event.y):
|
||||
self.drag_item = widget.get_item_at(self.remember_x,self.remember_y)
|
||||
if self.drag_item:
|
||||
context = widget.drag_begin(_drag_targets,
|
||||
gtk.gdk.ACTION_COPY|gtk.gdk.ACTION_MOVE,
|
||||
self.button, event)
|
||||
return gtk.TRUE
|
||||
photo = widget.get_data('obj')
|
||||
|
||||
if event.type == gtk.gdk.BUTTON_PRESS:
|
||||
if event.button == 1:
|
||||
# Remember starting position.
|
||||
|
||||
item = widget.get_item_at(event.x,event.y)
|
||||
if item:
|
||||
(i,t,b,self.photo) = self.p_map[item]
|
||||
style = self.iconlist.get_style()
|
||||
t.set(fill_color_gdk=style.fg[gtk.STATE_SELECTED])
|
||||
b.set(fill_color_gdk=style.bg[gtk.STATE_SELECTED])
|
||||
if self.sel:
|
||||
(i,t,b,photo) = self.p_map[self.sel]
|
||||
t.set(fill_color_gdk=style.fg[gtk.STATE_NORMAL])
|
||||
b.set(fill_color_gdk=style.bg[gtk.STATE_NORMAL])
|
||||
|
||||
self.sel = item
|
||||
|
||||
self.remember_x = event.x
|
||||
self.remember_y = event.y
|
||||
self.button = event.button
|
||||
return gtk.TRUE
|
||||
|
||||
elif event.button == 3:
|
||||
self.show_popup(photo)
|
||||
item = widget.get_item_at(event.x,event.y)
|
||||
if item:
|
||||
(i,t,b,self.photo) = self.p_map[item]
|
||||
self.show_popup(self.photo)
|
||||
return gtk.TRUE
|
||||
|
||||
elif event.type == gtk.gdk.BUTTON_RELEASE:
|
||||
self.button = 0
|
||||
elif event.type == gtk.gdk._2BUTTON_PRESS and event.button == 1:
|
||||
#Change the item's color.
|
||||
print photo,self.path,self
|
||||
LocalMediaProperties(photo,self.path,self)
|
||||
return gtk.TRUE
|
||||
|
||||
@ -258,13 +298,8 @@ class Gallery(ImageSelect):
|
||||
|
||||
return gtk.TRUE
|
||||
|
||||
elif event.type == gtk.gdk.ENTER_NOTIFY:
|
||||
# Make the outline wide.
|
||||
return gtk.TRUE
|
||||
|
||||
elif event.type == gtk.gdk.LEAVE_NOTIFY:
|
||||
# Make the outline thin.
|
||||
return gtk.TRUE
|
||||
if event.type == gtk.gdk.EXPOSE:
|
||||
self.load_images()
|
||||
|
||||
return gtk.FALSE
|
||||
|
||||
@ -279,58 +314,79 @@ class Gallery(ImageSelect):
|
||||
def add_thumbnail(self, photo):
|
||||
"""Scale the image and add it to the IconList."""
|
||||
object = photo.getReference()
|
||||
name = Utils.thumb_path(self.db.getSavePath(),object)
|
||||
description = object.getDescription()
|
||||
if len(description) > 20:
|
||||
description = "%s..." % description[0:20]
|
||||
|
||||
image = gtk.gdk.pixbuf_new_from_file(name)
|
||||
x = image.get_width()
|
||||
y = image.get_height()
|
||||
|
||||
grp = self.root.add(gnome.canvas.CanvasGroup,x=self.cx,y=self.cy)
|
||||
grp.connect('event',self.item_event)
|
||||
grp.set_data('obj',photo)
|
||||
|
||||
xloc = (_IMAGEX-x)/2
|
||||
yloc = (_IMAGEX-y)/2
|
||||
|
||||
item = grp.add(gnome.canvas.CanvasPixbuf,
|
||||
pixbuf=image,
|
||||
x=xloc,
|
||||
y=yloc)
|
||||
text = grp.add(gnome.canvas.CanvasText,
|
||||
x=_IMAGEX/2,
|
||||
y=_IMAGEX,
|
||||
anchor=gtk.ANCHOR_CENTER,
|
||||
text=description)
|
||||
oid = object.getId()
|
||||
|
||||
self.cx = 10 + _IMAGEX + self.cx
|
||||
if self.cx + 10 + _IMAGEX > self.x:
|
||||
self.cx = 10
|
||||
self.cy = self.cy + 10 + _IMAGEY
|
||||
if self.canvas_list.has_key(oid):
|
||||
(grp,item,text,bg,x,y) = self.canvas_list[oid]
|
||||
if x != self.cx or y != self.cy:
|
||||
grp.move(self.cx-x,self.cy-y)
|
||||
else:
|
||||
name = Utils.thumb_path(self.db.getSavePath(),object)
|
||||
description = object.getDescription()
|
||||
if len(description) > 20:
|
||||
description = "%s..." % description[0:20]
|
||||
|
||||
image = gtk.gdk.pixbuf_new_from_file(name)
|
||||
x = image.get_width()
|
||||
y = image.get_height()
|
||||
|
||||
grp = self.root.add(gnome.canvas.CanvasGroup,x=self.cx,y=self.cy)
|
||||
|
||||
xloc = (_IMAGEX-x)/2
|
||||
yloc = (_IMAGEY-y)/2
|
||||
|
||||
bg = grp.add(gnome.canvas.CanvasRect,
|
||||
x1=0,
|
||||
x2=_IMAGEX,
|
||||
y2=_IMAGEY,
|
||||
y1=_IMAGEY-20)
|
||||
|
||||
item = grp.add(gnome.canvas.CanvasPixbuf,
|
||||
pixbuf=image,
|
||||
x=xloc,
|
||||
y=yloc)
|
||||
|
||||
text = grp.add(gnome.canvas.CanvasText,
|
||||
x=_IMAGEX/2,
|
||||
y=_IMAGEX,
|
||||
anchor=gtk.ANCHOR_CENTER,
|
||||
text=description)
|
||||
|
||||
|
||||
self.item_map[item] = oid
|
||||
self.item_map[text] = oid
|
||||
self.item_map[grp] = oid
|
||||
self.item_map[bg] = oid
|
||||
|
||||
self.p_map[item] = (item,text,bg,photo)
|
||||
self.p_map[text] = (item,text,bg,photo)
|
||||
self.p_map[grp] = (item,text,bg,photo)
|
||||
self.p_map[bg] = (item,text,bg,photo)
|
||||
|
||||
item.show()
|
||||
text.show()
|
||||
self.canvas_list.append(grp)
|
||||
self.canvas_list.append(item)
|
||||
self.canvas_list.append(text)
|
||||
item.show()
|
||||
text.show()
|
||||
bg.show()
|
||||
|
||||
self.canvas_list[oid] = (grp,item,text,bg,self.cx,self.cy)
|
||||
|
||||
if self.cx + _PAD + _IMAGEX > self.x:
|
||||
self.cx = _PAD
|
||||
self.cy = self.cy + _PAD + _IMAGEY
|
||||
else:
|
||||
self.cx = _PAD + self.cx + _IMAGEX
|
||||
|
||||
def load_images(self):
|
||||
"""clears the currentImages list to free up any cached
|
||||
Imlibs. Then add each photo in the place's list of photos to the
|
||||
photolist window."""
|
||||
|
||||
for item in self.canvas_list:
|
||||
item.destroy()
|
||||
|
||||
self.pos = 0
|
||||
self.cx = 10
|
||||
self.cy = 10
|
||||
self.cx = _PAD
|
||||
self.cy = _PAD
|
||||
|
||||
(self.x,self.y) = self.iconlist.get_size()
|
||||
|
||||
self.max = (self.x)/(_IMAGEX+10)
|
||||
self.max = (self.x)/(_IMAGEX+_PAD)
|
||||
|
||||
for photo in self.dataobj.getPhotoList():
|
||||
self.add_thumbnail(photo)
|
||||
@ -345,13 +401,12 @@ class Gallery(ImageSelect):
|
||||
self.selectedIcon = iconNumber
|
||||
|
||||
def get_index(self,obj,x,y):
|
||||
x_offset = x/(_IMAGEX+10)
|
||||
y_offset = y/(_IMAGEY+10)
|
||||
index = (y_offset*self.max)+x_offset
|
||||
x_offset = x/(_IMAGEX+_PAD)
|
||||
y_offset = y/(_IMAGEY+_PAD)
|
||||
index = (y_offset*(1+self.max))+x_offset
|
||||
return min(index,len(self.dataobj.getPhotoList()))
|
||||
|
||||
def on_photolist_drag_data_received(self,w, context, x, y, data, info, time):
|
||||
print "receive",w
|
||||
if data and data.format == 8:
|
||||
icon_index = self.get_index(w,x,y)
|
||||
d = string.strip(string.replace(data.data,'\0',' '))
|
||||
@ -441,20 +496,14 @@ class Gallery(ImageSelect):
|
||||
if GrampsCfg.globalprop:
|
||||
LocalMediaProperties(oref,self.path,self)
|
||||
Utils.modified()
|
||||
#w.drag_finish(context, 1, 0, time)
|
||||
else:
|
||||
pass
|
||||
#w.drag_finish(context, 0, 0, time)
|
||||
|
||||
def on_photolist_drag_data_get(self,w, context, selection_data, info, time):
|
||||
print "drag data get",w
|
||||
if info == 1:
|
||||
return
|
||||
if self.selectedIcon != -1:
|
||||
ref = self.dataobj.getPhotoList()[self.selectedIcon]
|
||||
id = ref.getReference().getId()
|
||||
selection_data.set(selection_data.target, 8, id)
|
||||
|
||||
id = self.item_map[self.drag_item]
|
||||
selection_data.set(selection_data.target, 8, id)
|
||||
self.drag_item = None
|
||||
|
||||
def on_add_photo_clicked(self, obj):
|
||||
"""User wants to add a new photo. Create a dialog to find out
|
||||
which photo they want."""
|
||||
@ -479,7 +528,6 @@ class Gallery(ImageSelect):
|
||||
def show_popup(self, photo):
|
||||
"""Look for right-clicks on a picture and create a popup
|
||||
menu of the available actions."""
|
||||
|
||||
|
||||
menu = gtk.Menu()
|
||||
item = gtk.TearoffMenuItem()
|
||||
|
@ -25,29 +25,7 @@ class ListModel:
|
||||
def __init__(self,tree,dlist):
|
||||
self.tree = tree
|
||||
l = len(dlist)
|
||||
if l == 1:
|
||||
self.model = gtk.ListStore(TYPE_STRING)
|
||||
elif l == 2:
|
||||
self.model = gtk.ListStore(TYPE_STRING, TYPE_STRING)
|
||||
elif l == 3:
|
||||
self.model = gtk.ListStore(TYPE_STRING, TYPE_STRING, TYPE_STRING)
|
||||
elif l == 4:
|
||||
self.model = gtk.ListStore(TYPE_STRING, TYPE_STRING, TYPE_STRING,
|
||||
TYPE_STRING)
|
||||
elif l == 5:
|
||||
self.model = gtk.ListStore(TYPE_STRING, TYPE_STRING, TYPE_STRING,
|
||||
TYPE_STRING, TYPE_STRING)
|
||||
elif l == 6:
|
||||
self.model = gtk.ListStore(TYPE_STRING, TYPE_STRING, TYPE_STRING,
|
||||
TYPE_STRING, TYPE_STRING, TYPE_STRING)
|
||||
elif l == 7:
|
||||
self.model = gtk.ListStore(TYPE_STRING, TYPE_STRING, TYPE_STRING,
|
||||
TYPE_STRING, TYPE_STRING, TYPE_STRING,
|
||||
TYPE_STRING)
|
||||
elif l == 8:
|
||||
self.model = gtk.ListStore(TYPE_STRING, TYPE_STRING, TYPE_STRING,
|
||||
TYPE_STRING, TYPE_STRING, TYPE_STRING,
|
||||
TYPE_STRING, TYPE_STRING)
|
||||
self.model = gtk.ListStore(*[TYPE_STRING]*l)
|
||||
|
||||
self.selection = self.tree.get_selection()
|
||||
self.tree.set_model(self.model)
|
||||
|
@ -121,21 +121,21 @@ class SelectChild:
|
||||
bday = self.person.getBirth().getDateObj()
|
||||
dday = self.person.getDeath().getDateObj()
|
||||
|
||||
slist = []
|
||||
slist = {}
|
||||
for f in self.person.getParentList():
|
||||
if f:
|
||||
if f[0].getFather():
|
||||
slist.append(f[0].getFather())
|
||||
slist[f[0].getFather().getId()] = 1
|
||||
elif f[0].getMother():
|
||||
slist.append(f[0].getMother())
|
||||
slist[f[0].getMother().getId()] = 1
|
||||
for c in f[0].getChildList():
|
||||
slist.append(c)
|
||||
slist[c.getId()] = 1
|
||||
|
||||
person_list = []
|
||||
for key in self.db.getPersonKeys():
|
||||
person = self.db.getPerson(key)
|
||||
if filter:
|
||||
if person in slist or person.getMainParents():
|
||||
if slist.has_key(key) or person.getMainParents():
|
||||
continue
|
||||
|
||||
pdday = person.getDeath().getDateObj()
|
||||
@ -167,10 +167,10 @@ class SelectChild:
|
||||
if pdday.getLowYear() > dday.getHighYear() + 150:
|
||||
continue
|
||||
|
||||
person_list.append(person)
|
||||
person_list.append(person.getId())
|
||||
|
||||
for person in person_list:
|
||||
dinfo = self.db.getPersonDisplay(id)
|
||||
for idval in person_list:
|
||||
dinfo = self.db.getPersonDisplay(idval)
|
||||
rdata = [dinfo[0],dinfo[1],dinfo[3],dinfo[5],dinfo[6]]
|
||||
self.refmodel.add(rdata)
|
||||
|
||||
|
@ -4274,8 +4274,8 @@
|
||||
<widget class="GtkScrolledWindow" id="scrolledwindow22">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="hscrollbar_policy">GTK_POLICY_ALWAYS</property>
|
||||
<property name="vscrollbar_policy">GTK_POLICY_ALWAYS</property>
|
||||
<property name="hscrollbar_policy">GTK_POLICY_NEVER</property>
|
||||
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
|
||||
<property name="shadow_type">GTK_SHADOW_NONE</property>
|
||||
<property name="window_placement">GTK_CORNER_TOP_LEFT</property>
|
||||
|
||||
|
@ -5450,6 +5450,7 @@
|
||||
<property name="type">GTK_WINDOW_TOPLEVEL</property>
|
||||
<property name="window_position">GTK_WIN_POS_NONE</property>
|
||||
<property name="modal">False</property>
|
||||
<property name="default_width">300</property>
|
||||
<property name="resizable">True</property>
|
||||
<property name="destroy_with_parent">False</property>
|
||||
<property name="has_separator">True</property>
|
||||
|
3683
src/mergedata.glade
3683
src/mergedata.glade
File diff suppressed because it is too large
Load Diff
@ -31,10 +31,10 @@ import Utils
|
||||
import string
|
||||
import const
|
||||
import GenericFilter
|
||||
import ListModel
|
||||
from TextDoc import *
|
||||
from OpenSpreadSheet import *
|
||||
import intl
|
||||
_ = intl.gettext
|
||||
from intl import gettext as _
|
||||
|
||||
import gnome.ui
|
||||
import gtk
|
||||
@ -167,11 +167,8 @@ def by_value(first,second):
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
def fix(line):
|
||||
l = string.strip(line)
|
||||
l = string.replace(l,'&','&')
|
||||
l = string.replace(l,'>','>')
|
||||
l = string.replace(l,'<','<')
|
||||
return string.replace(l,'"','"')
|
||||
l = line.strip().replace('&','&').replace(l,'>','>')
|
||||
return l.replace(l,'<','<').replace(l,'"','"')
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
@ -193,7 +190,7 @@ class DisplayChart:
|
||||
})
|
||||
|
||||
self.top = self.topDialog.get_widget("view")
|
||||
self.table = self.topDialog.get_widget("addarea")
|
||||
self.eventlist = self.topDialog.get_widget('treeview')
|
||||
|
||||
self.my_list.sort(sort.by_last_name)
|
||||
|
||||
@ -204,17 +201,19 @@ class DisplayChart:
|
||||
|
||||
def draw_clist_display(self):
|
||||
|
||||
eventlist = gtk.CList(len(self.event_titles),self.event_titles)
|
||||
self.table.add(eventlist)
|
||||
eventlist.show()
|
||||
titles = []
|
||||
index = 0
|
||||
for v in self.event_titles:
|
||||
titles.append((v,150,index))
|
||||
index = index + 1
|
||||
|
||||
self.list = ListModel.ListModel(self.eventlist,titles)
|
||||
for data in self.row_data:
|
||||
self.list.add(data)
|
||||
|
||||
for (top,bottom) in self.row_data:
|
||||
eventlist.append(top)
|
||||
eventlist.append(bottom)
|
||||
|
||||
for index in range(0,len(self.event_titles)):
|
||||
width = min(150,eventlist.optimal_column_width(index))
|
||||
eventlist.set_column_width(index,width)
|
||||
# for index in range(0,len(self.event_titles)):
|
||||
# width = min(150,eventlist.optimal_column_width(index))
|
||||
# self.eventlist.set_column_width(index,width)
|
||||
|
||||
def build_row_data(self):
|
||||
for individual in self.my_list:
|
||||
@ -235,29 +234,26 @@ class DisplayChart:
|
||||
while done == 0:
|
||||
added = 0
|
||||
if first:
|
||||
tlist = [name,birth.getDate(),death.getDate()]
|
||||
blist = ["",birth.getPlaceName(),death.getPlaceName()]
|
||||
tlist = [name,"%s\n%s" % (birth.getDate(),birth.getPlaceName()),
|
||||
"%s\n%s" % (death.getDate(),death.getPlaceName())]
|
||||
else:
|
||||
tlist = ["","",""]
|
||||
blist = ["","",""]
|
||||
for ename in self.event_titles[3:]:
|
||||
if map.has_key(ename) and len(map[ename]) > 0:
|
||||
event = map[ename][0]
|
||||
del map[ename][0]
|
||||
tlist.append(event.getDate())
|
||||
blist.append(event.getPlaceName())
|
||||
tlist.append("%s\n%s" % (event.getDate(), event.getPlaceName()))
|
||||
added = 1
|
||||
else:
|
||||
tlist.append("")
|
||||
blist.append("")
|
||||
|
||||
if first:
|
||||
first = 0
|
||||
self.row_data.append((tlist,blist))
|
||||
self.row_data.append(tlist)
|
||||
elif added == 0:
|
||||
done = 1
|
||||
else:
|
||||
self.row_data.append((tlist,blist))
|
||||
self.row_data.append(tlist)
|
||||
|
||||
def make_event_titles(self):
|
||||
"""Creates the list of unique event types, along with the person's
|
||||
@ -330,6 +326,8 @@ register_tool(
|
||||
runTool,
|
||||
_("Compare individual events"),
|
||||
category=_("Analysis and Exploration"),
|
||||
description=_("Aids in the analysis of data by allowing the development of custom filters that can be applied to the database to find similar events")
|
||||
description=_("Aids in the analysis of data by allowing the "
|
||||
"development of custom filters that can be applied "
|
||||
"to the database to find similar events")
|
||||
)
|
||||
|
||||
|
@ -24,6 +24,7 @@ import RelLib
|
||||
import Utils
|
||||
import soundex
|
||||
import GrampsCfg
|
||||
import ListModel
|
||||
from intl import gettext as _
|
||||
|
||||
import string
|
||||
@ -43,11 +44,16 @@ def is_initial(name):
|
||||
if len(name) > 2:
|
||||
return 0
|
||||
elif len(name) == 2:
|
||||
if name[0] in string.uppercase and name[1] == '.':
|
||||
if name[0] == name[0].upper() and name[1] == '.':
|
||||
return 1
|
||||
else:
|
||||
return name[0] in string.uppercase
|
||||
return name[0] == name[0].upper()
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
#
|
||||
#
|
||||
#
|
||||
#-------------------------------------------------------------------------
|
||||
def ancestors_of(p1,list):
|
||||
if p1 == None or p1 in list:
|
||||
return
|
||||
@ -113,9 +119,11 @@ class Merge:
|
||||
self.show()
|
||||
|
||||
def progress_update(self,val):
|
||||
self.progress.set_value(val)
|
||||
while gtk.events_pending():
|
||||
gtk.mainiteration()
|
||||
pass
|
||||
# self.progress.set_value(val)
|
||||
# while gtk.events_pending():
|
||||
# gtk.mainiteration()
|
||||
|
||||
|
||||
def find_potentials(self,thresh):
|
||||
top = gtk.glade.XML(self.glade_file,"message")
|
||||
@ -131,19 +139,20 @@ class Merge:
|
||||
key = self.gen_key(p1.getPrimaryName().getSurname())
|
||||
if p1.getGender() == RelLib.Person.male:
|
||||
if males.has_key(key):
|
||||
males[key].append(p1)
|
||||
males[key].append(p1.getId())
|
||||
else:
|
||||
males[key] = [p1]
|
||||
males[key] = [p1.getId()]
|
||||
else:
|
||||
if females.has_key(key):
|
||||
females[key].append(p1)
|
||||
females[key].append(p1.getId())
|
||||
else:
|
||||
females[key] = [p1]
|
||||
females[key] = [p1.getId()]
|
||||
|
||||
length = len(self.person_list)
|
||||
|
||||
num = 0
|
||||
for p1 in self.person_list:
|
||||
p1key = p1.getId()
|
||||
if num % 25 == 0:
|
||||
self.progress_update((float(num)/float(length))*100)
|
||||
num = num + 1
|
||||
@ -155,26 +164,27 @@ class Merge:
|
||||
remaining = females[key]
|
||||
|
||||
index = 0
|
||||
for p2 in remaining:
|
||||
for p2key in remaining:
|
||||
index = index + 1
|
||||
if p1 == p2:
|
||||
if p1key == p2key:
|
||||
continue
|
||||
if self.map.has_key(p2):
|
||||
(v,c) = self.map[p2]
|
||||
p2 = self.db.getPerson(p2key)
|
||||
if self.map.has_key(p2key):
|
||||
(v,c) = self.map[p2key]
|
||||
if v == p1:
|
||||
continue
|
||||
|
||||
chance = self.compare_people(p1,p2)
|
||||
if chance >= thresh:
|
||||
if self.map.has_key(p1):
|
||||
val = self.map[p1]
|
||||
if self.map.has_key(p1key):
|
||||
val = self.map[p1key]
|
||||
if val[1] > chance:
|
||||
self.map[p1] = (p2,chance)
|
||||
self.map[p1key] = (p2,chance)
|
||||
else:
|
||||
self.map[p1] = (p2,chance)
|
||||
self.map[p1key] = (p2,chance)
|
||||
|
||||
self.list = self.map.keys()[:]
|
||||
self.list.sort(by_id)
|
||||
self.list = self.map.keys()
|
||||
self.list.sort()
|
||||
self.length = len(self.list)
|
||||
self.topWin.destroy()
|
||||
self.dellist = {}
|
||||
@ -188,6 +198,12 @@ class Merge:
|
||||
"on_do_merge_clicked" : self.on_do_merge_clicked,
|
||||
})
|
||||
self.mlist.connect('button-press-event',self.button_press_event)
|
||||
|
||||
self.list = ListModel.ListModel(self.mlist,
|
||||
[(_('Rating'),75,0),
|
||||
(_('First Person'),200,1),
|
||||
(_('Second Person'),200,2)])
|
||||
|
||||
self.redraw()
|
||||
|
||||
def redraw(self):
|
||||
@ -196,39 +212,41 @@ class Merge:
|
||||
if self.dellist.has_key(p1):
|
||||
continue
|
||||
(p2,c) = self.map[p1]
|
||||
if self.dellist.has_key(p2):
|
||||
p2 = self.dellist[p2]
|
||||
p2key = p2.getId()
|
||||
if self.dellist.has_key(p2key):
|
||||
p2 = self.dellist[p2key]
|
||||
if p1 == p2:
|
||||
continue
|
||||
list.append((c,p1,p2))
|
||||
list.append((c,p1,p2.getId()))
|
||||
list.sort()
|
||||
list.reverse()
|
||||
|
||||
index = 0
|
||||
self.mlist.freeze()
|
||||
self.mlist.clear()
|
||||
self.match_map = {}
|
||||
self.list.clear()
|
||||
for (c,p1,p2) in list:
|
||||
c = "%5.2f" % c
|
||||
self.mlist.append([c, name_of(p1), name_of(p2)])
|
||||
self.mlist.set_row_data(index,(p1,p2))
|
||||
pn1 = self.db.getPerson(p1)
|
||||
pn2 = self.db.getPerson(p2)
|
||||
self.list.add([c, name_of(pn1), name_of(pn2)])
|
||||
self.match_map[index] = (p1,p2)
|
||||
index = index + 1
|
||||
self.mlist.thaw()
|
||||
|
||||
def button_press_event(self,obj,event):
|
||||
if event.button != 1 or event.type != GDK._2BUTTON_PRESS:
|
||||
if event.button != 1 or event.type != gtk.gdk._2BUTTON_PRESS:
|
||||
return
|
||||
if len(self.mlist.selection) <= 0:
|
||||
return
|
||||
row = self.mlist.selection[0]
|
||||
(p1,p2) = self.mlist.get_row_data(row)
|
||||
MergeData.MergePeople(self.db,p1,p2,self.on_update)
|
||||
self.on_do_merge_clicked(obj)
|
||||
|
||||
def on_do_merge_clicked(self,obj):
|
||||
if len(self.mlist.selection) != 1:
|
||||
store,iter = self.list.selection.get_selected()
|
||||
if not iter:
|
||||
return
|
||||
row = self.mlist.selection[0]
|
||||
(p1,p2) = self.mlist.get_row_data(row)
|
||||
MergeData.MergePeople(self.db,p1,p2,self.on_update)
|
||||
|
||||
row = self.list.model.get_path(iter)
|
||||
(p1,p2) = self.match_map[row[0]]
|
||||
pn1 = self.db.getPerson(p1)
|
||||
pn2 = self.db.getPerson(p2)
|
||||
MergeData.MergePeople(self.db,pn1,pn2,self.on_update)
|
||||
|
||||
def on_update(self,p1,p2):
|
||||
self.dellist[p2] = p1
|
||||
@ -389,7 +407,7 @@ class Merge:
|
||||
|
||||
name1 = p1.getPrimaryName()
|
||||
name2 = p2.getPrimaryName()
|
||||
|
||||
|
||||
chance = self.name_match(name1,name2)
|
||||
if chance == -1 :
|
||||
return -1
|
||||
@ -524,6 +542,7 @@ register_tool(
|
||||
runTool,
|
||||
_("Find possible duplicate people"),
|
||||
category=_("Database Processing"),
|
||||
description=_("Searches the entire database, looking for individual entries that may represent the same person.")
|
||||
description=_("Searches the entire database, looking for "
|
||||
"individual entries that may represent the same person.")
|
||||
)
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user