diff --git a/gramps/gui/widgets/fanchart.py b/gramps/gui/widgets/fanchart.py
index 58db5ed24..a0c5545f8 100644
--- a/gramps/gui/widgets/fanchart.py
+++ b/gramps/gui/widgets/fanchart.py
@@ -34,16 +34,15 @@
# Python modules
#
#-------------------------------------------------------------------------
+import math
+import colorsys
+import pickle
+from html import escape
+import cairo
from gi.repository import Pango
from gi.repository import Gdk
from gi.repository import Gtk
from gi.repository import PangoCairo
-import cairo
-import math
-import colorsys
-import sys
-import pickle
-from html import escape
#-------------------------------------------------------------------------
#
@@ -55,14 +54,10 @@ from gramps.gen.display.name import displayer as name_displayer
from gramps.gen.errors import WindowActiveError
from gramps.gen.lib import ChildRef, Family, Name, Person, Surname
from gramps.gen.lib.date import Today
-from ..editors import EditPerson, EditFamily
-from .reorderfam import Reorder
-from ..utils import color_graph_box, hex_to_rgb, is_right_click
-from ..ddtargets import DdTargets
from gramps.gen.utils.alive import probably_alive
from gramps.gen.utils.libformatting import FormattingHelper
-from gramps.gen.utils.db import (find_children, find_parents, find_witnessed_people,
- get_age, get_timeperiod, preset_name)
+from gramps.gen.utils.db import (find_children, find_parents, get_timeperiod,
+ find_witnessed_people, get_age, preset_name)
from gramps.gen.constfunc import is_quartz
from gramps.gen.const import GRAMPS_LOCALE as glocale
from gramps.gen.const import (
@@ -88,13 +83,16 @@ from gramps.gen.const import (
FORM_QUADRANT,
COLLAPSED,
NORMAL,
- EXPANDED,
- TYPE_BOX_NORMAL,
- TYPE_BOX_FAMILY)
-_ = glocale.translation.gettext
+ EXPANDED)
+from .reorderfam import Reorder
+from ..utils import color_graph_box, hex_to_rgb, is_right_click
+from ..ddtargets import DdTargets
+from ..editors import EditPerson, EditFamily
from ..utilscairo import warpPath
from gramps.gen.utils.symbols import Symbols
+_ = glocale.translation.gettext
+
# following are used in name_displayer format def
# (must not conflict with standard defs)
TWO_LINE_FORMAT_1 = 100
@@ -121,7 +119,21 @@ class FanChartBaseWidget(Gtk.DrawingArea):
self.textcolor = (0, 0, 0)
self.dbstate = dbstate
self.uistate = uistate
+ self.form = FORM_CIRCLE
+ self.generations = 8
+ self.childring = 0
+ self.childrenroot = []
+ self.angle = {}
+ self.grad_start = '#0000FF'
+ self.grad_end = '#FF0000'
+ self.background = BACKGROUND_GRAD_GEN
+ self.filter = None
+ self.alpha_filter = 0.5
self.translating = False
+ self.showid = False
+ self.flipupsidedownname = True
+ self.dupcolor = None
+ self.twolinename = False
self.surface = None
self.goto = None
self.on_popup = callback_popup
@@ -148,9 +160,8 @@ class FanChartBaseWidget(Gtk.DrawingArea):
Gdk.EventMask.KEY_PRESS_MASK)
# Enable drag
- self.drag_source_set(Gdk.ModifierType.BUTTON1_MASK,
- [],
- Gdk.DragAction.COPY)
+ self.drag_source_set(Gdk.ModifierType.BUTTON1_MASK, [],
+ Gdk.DragAction.COPY)
tglist = Gtk.TargetList.new([])
tglist.add(DdTargets.PERSON_LINK.atom_drag_type,
DdTargets.PERSON_LINK.target_flags,
@@ -162,22 +173,32 @@ class FanChartBaseWidget(Gtk.DrawingArea):
self.connect("drag_begin", self.on_drag_begin)
self.connect("drag_end", self.on_drag_end)
# Enable drop
- self.drag_dest_set(Gtk.DestDefaults.MOTION |
- Gtk.DestDefaults.DROP,
- [DdTargets.PERSON_LINK.target()],
- Gdk.DragAction.COPY)
+ self.drag_dest_set(Gtk.DestDefaults.MOTION | Gtk.DestDefaults.DROP,
+ [DdTargets.PERSON_LINK.target()],
+ Gdk.DragAction.COPY)
self.connect('drag_data_received', self.on_drag_data_received)
self.uistate.connect('font-changed', self.reload_symbols)
self._mouse_click = False
self.rotate_value = 90 # degrees, initially, 1st gen male on right half
- self.center_delta_xy = [0, 0] # translation of the center of the fan wrt canonical center
+ self.center_delta_xy = [0, 0] # translation of the center of the
+ # fan wrt canonical center
self.center_xy = [0, 0] # coord of the center of the fan
self.mouse_x = 0
self.mouse_y = 0
#(re)compute everything
self.reset()
self.set_size_request(120, 120)
+ self.maxperiod = 0
+ self.minperiod = 0
+ self.cstart_hsv = None
+ self.cend_hsv = None
+ self.colors = None
+ self.maincolor = None
+ self.gradval = None
+ self.gradcol = None
+ self.in_drag = False
+ self._mouse_click_cell_address = None
self.symbols = Symbols()
self.reload_symbols()
@@ -251,22 +272,28 @@ class FanChartBaseWidget(Gtk.DrawingArea):
"""
raise NotImplementedError
- def get_radiusinout_for_generation(self,generation):
+ def get_radiusinout_for_gen(self, generation):
+ """
+ Get the in and out radius for descendant generation
+ """
raise NotImplementedError
- def on_draw(self, widget, cr, scale=1.):
+ def on_draw(self, widget, ctx, scale=1.):
"""
callback to draw the fanchart
"""
+ dummy_scale = scale
+ dummy_widget = widget
if self.surface:
- cr.set_source_surface(self.surface, 0, 0)
- cr.paint()
+ ctx.set_source_surface(self.surface, 0, 0)
+ ctx.paint()
- def prt_draw(self, widget, cr, scale=1.0):
+ def prt_draw(self, widget, ctx, scale=1.0):
"""
method to allow direct drawing to cairo context for printing
"""
- self.draw(cr=cr, scale=scale)
+ dummy_widget = widget
+ self.draw(ctx=ctx, scale=scale)
def people_generator(self):
"""
@@ -295,6 +322,9 @@ class FanChartBaseWidget(Gtk.DrawingArea):
userdata.append(period)
def set_userdata_age(self, person, userdata):
+ """
+ set the userdata as used by age
+ """
agecol = (1, 1, 1) # white
if person:
age = get_age(self.dbstate.db, person)
@@ -307,9 +337,12 @@ class FanChartBaseWidget(Gtk.DrawingArea):
#now determine fraction for gradient
agefrac = age / MAX_AGE
agecol = colorsys.hsv_to_rgb(
- (1-agefrac) * self.cstart_hsv[0] + agefrac * self.cend_hsv[0],
- (1-agefrac) * self.cstart_hsv[1] + agefrac * self.cend_hsv[1],
- (1-agefrac) * self.cstart_hsv[2] + agefrac * self.cend_hsv[2],
+ ((1-agefrac) * self.cstart_hsv[0] +
+ agefrac * self.cend_hsv[0]),
+ ((1-agefrac) * self.cstart_hsv[1] +
+ agefrac * self.cend_hsv[1]),
+ ((1-agefrac) * self.cstart_hsv[2] +
+ agefrac * self.cend_hsv[2]),
)
userdata.append((agecol[0]*255, agecol[1]*255, agecol[2]*255))
@@ -321,24 +354,26 @@ class FanChartBaseWidget(Gtk.DrawingArea):
cstart = hex_to_rgb(self.grad_start)
cend = hex_to_rgb(self.grad_end)
self.cstart_hsv = colorsys.rgb_to_hsv(cstart[0]/255, cstart[1]/255,
- cstart[2]/255)
+ cstart[2]/255)
self.cend_hsv = colorsys.rgb_to_hsv(cend[0]/255, cend[1]/255,
- cend[2]/255)
+ cend[2]/255)
if self.background in [BACKGROUND_GENDER, BACKGROUND_SINGLE_COLOR]:
# nothing to precompute
self.colors = None
self.maincolor = cstart
elif self.background == BACKGROUND_GRAD_GEN:
#compute the colors, -1, 0, ..., maxgen
- divs = [x/(maxgen-1) for x in range(maxgen)] if maxgen>1 else [0]
+ divs = [x/(maxgen-1) for x in range(maxgen)] if maxgen > 1 else [0]
rgb_colors = [colorsys.hsv_to_rgb(
- (1-x) * self.cstart_hsv[0] + x * self.cend_hsv[0],
- (1-x) * self.cstart_hsv[1] + x * self.cend_hsv[1],
- (1-x) * self.cstart_hsv[2] + x * self.cend_hsv[2],
- ) for x in divs]
- self.colors = [(255*r, 255*g, 255*b) for r, g, b in rgb_colors]
+ (1-x) * self.cstart_hsv[0] + x * self.cend_hsv[0],
+ (1-x) * self.cstart_hsv[1] + x * self.cend_hsv[1],
+ (1-x) * self.cstart_hsv[2] + x * self.cend_hsv[2],
+ ) for x in divs]
+ self.colors = [(255 * red, 255 * green, 255 * blue)
+ for red, green, blue in rgb_colors]
elif self.background == BACKGROUND_GRAD_PERIOD:
- # we fill in in the data structure what the period is, None if not found
+ # we fill in in the data structure what the period is,
+ # None if not found
self.colors = None
self.minperiod = 1e10
self.maxperiod = -1e10
@@ -349,7 +384,8 @@ class FanChartBaseWidget(Gtk.DrawingArea):
gen_inner = self.innerpeople_generator()
for child, userdata in gen_inner:
self.set_userdata_timeperiod(child, userdata)
- #now create gradient data, 5 values from min to max rounded to nearest 50
+ # now create gradient data, 5 values from min to max rounded
+ # to nearest 50
if self.maxperiod < self.minperiod:
self.maxperiod = self.minperiod = Today().get_year()
rper = self.maxperiod // 50
@@ -359,18 +395,20 @@ class FanChartBaseWidget(Gtk.DrawingArea):
periodrange = self.maxperiod - self.minperiod
steps = 2 * GRADIENTSCALE - 1
divs = [x/(steps-1) for x in range(steps)]
- self.gradval = ['%d' % int(self.minperiod + x * periodrange) for x in divs]
+ self.gradval = ['%d' % int(self.minperiod + x *
+ periodrange) for x in divs]
for i in range(len(self.gradval)):
if i % 2 == 1:
self.gradval[i] = ''
self.gradcol = [colorsys.hsv_to_rgb(
- (1-div) * self.cstart_hsv[0] + div * self.cend_hsv[0],
- (1-div) * self.cstart_hsv[1] + div * self.cend_hsv[1],
- (1-div) * self.cstart_hsv[2] + div * self.cend_hsv[2],
- ) for div in divs]
+ (1-div) * self.cstart_hsv[0] + div * self.cend_hsv[0],
+ (1-div) * self.cstart_hsv[1] + div * self.cend_hsv[1],
+ (1-div) * self.cstart_hsv[2] + div * self.cend_hsv[2],
+ ) for div in divs]
elif self.background == BACKGROUND_GRAD_AGE:
- # we fill in in the data structure what the color age is, white if no age
+ # we fill in in the data structure what the color age is,
+ # white if no age
self.colors = None
gen_people = self.people_generator()
for person, userdata in gen_people:
@@ -388,10 +426,10 @@ class FanChartBaseWidget(Gtk.DrawingArea):
if i % 2 == 1:
self.gradval[i] = ''
self.gradcol = [colorsys.hsv_to_rgb(
- (1-div) * self.cstart_hsv[0] + div * self.cend_hsv[0],
- (1-div) * self.cstart_hsv[1] + div * self.cend_hsv[1],
- (1-div) * self.cstart_hsv[2] + div * self.cend_hsv[2],
- ) for div in divs]
+ (1-div) * self.cstart_hsv[0] + div * self.cend_hsv[0],
+ (1-div) * self.cstart_hsv[1] + div * self.cend_hsv[1],
+ (1-div) * self.cstart_hsv[2] + div * self.cend_hsv[2],
+ ) for div in divs]
else:
# known colors per generation, set or compute them
self.colors = GENCOLOR[self.background]
@@ -402,8 +440,9 @@ class FanChartBaseWidget(Gtk.DrawingArea):
which has gender gender, and is in ring generation
"""
if generation == 0 and self.background in [BACKGROUND_GENDER,
- BACKGROUND_GRAD_GEN, BACKGROUND_SCHEME1,
- BACKGROUND_SCHEME2]:
+ BACKGROUND_GRAD_GEN,
+ BACKGROUND_SCHEME1,
+ BACKGROUND_SCHEME2]:
# white for center person:
color = (255, 255, 255)
elif self.background == BACKGROUND_GENDER:
@@ -411,7 +450,7 @@ class FanChartBaseWidget(Gtk.DrawingArea):
alive = probably_alive(person, self.dbstate.db)
except RuntimeError:
alive = False
- backgr, border = color_graph_box(alive, person.gender)
+ backgr, dummy_border = color_graph_box(alive, person.gender)
color = hex_to_rgb(backgr)
elif self.background == BACKGROUND_SINGLE_COLOR:
color = self.maincolor
@@ -428,10 +467,13 @@ class FanChartBaseWidget(Gtk.DrawingArea):
else:
periodfrac = 0.5
periodcol = colorsys.hsv_to_rgb(
- (1-periodfrac) * self.cstart_hsv[0] + periodfrac * self.cend_hsv[0],
- (1-periodfrac) * self.cstart_hsv[1] + periodfrac * self.cend_hsv[1],
- (1-periodfrac) * self.cstart_hsv[2] + periodfrac * self.cend_hsv[2],
- )
+ ((1-periodfrac) * self.cstart_hsv[0] +
+ periodfrac * self.cend_hsv[0]),
+ ((1-periodfrac) * self.cstart_hsv[1] +
+ periodfrac * self.cend_hsv[1]),
+ ((1-periodfrac) * self.cstart_hsv[2] +
+ periodfrac * self.cend_hsv[2]),
+ )
color = (periodcol[0]*255, periodcol[1]*255, periodcol[2]*255)
else:
if self.background == BACKGROUND_GRAD_GEN and generation < 0:
@@ -440,7 +482,8 @@ class FanChartBaseWidget(Gtk.DrawingArea):
if person.gender == Person.MALE:
color = [x*.9 for x in color]
# now we set transparency data
- if self.filter and not self.filter.match(person.handle, self.dbstate.db):
+ if self.filter and not self.filter.match(person.handle,
+ self.dbstate.db):
if self.background == BACKGROUND_SINGLE_COLOR:
alpha = 0. # no color shown
else:
@@ -450,65 +493,70 @@ class FanChartBaseWidget(Gtk.DrawingArea):
return color[0], color[1], color[2], alpha
- def fontcolor(self, r, g, b, a):
+ def fontcolor(self, red, green, blue, alpha):
"""
return the font color based on the r, g, b of the background
"""
- if a == 0:
+ if alpha == 0:
return self.textcolor
try:
- return self.cache_fontcolor[(r, g, b)]
+ return self.cache_fontcolor[(red, green, blue)]
except KeyError:
- hls = colorsys.rgb_to_hls(r/255, g/255, b/255)
+ hls = colorsys.rgb_to_hls(red / 255, green / 255, blue / 255)
# we use the lightness value to determine white or black font
if hls[1] > 0.4:
- self.cache_fontcolor[(r, g, b)] = (0, 0, 0)
+ self.cache_fontcolor[(red, green, blue)] = (0, 0, 0)
else:
- self.cache_fontcolor[(r, g, b)] = (1, 1, 1)
- return self.cache_fontcolor[(r, g, b)]
+ self.cache_fontcolor[(red, green, blue)] = (1, 1, 1)
+ return self.cache_fontcolor[(red, green, blue)]
- def fontbold(self, a):
+ def fontbold(self, alpha):
"""
The font should be bold if no transparency and font is set.
In that case, True is returned
"""
- if a >= 1. and self.filter:
+ if alpha >= 1. and self.filter:
return True
return False
- def draw_radbox(self, cr, radiusin, radiusout, start_rad, stop_rad, color,
+ def draw_radbox(self, ctx, radiusin, radiusout, start_rad, stop_rad, color,
thick=False):
"""
Procedure to draw a person box in the outter ring position
"""
- cr.move_to(radiusout * math.cos(start_rad), radiusout * math.sin(start_rad))
- cr.arc(0, 0, radiusout, start_rad, stop_rad)
- cr.line_to(radiusin * math.cos(stop_rad), radiusin * math.sin(stop_rad))
- cr.arc_negative(0, 0, radiusin, stop_rad, start_rad)
- cr.close_path()
- ##path = cr.copy_path() # not working correct
- cr.set_source_rgba(color[0], color[1], color[2], color[3])
- cr.fill()
+ ctx.move_to(radiusout * math.cos(start_rad),
+ radiusout * math.sin(start_rad))
+ ctx.arc(0, 0, radiusout, start_rad, stop_rad)
+ ctx.line_to(radiusin * math.cos(stop_rad),
+ radiusin * math.sin(stop_rad))
+ ctx.arc_negative(0, 0, radiusin, stop_rad, start_rad)
+ ctx.close_path()
+ ##path = ctx.copy_path() # not working correct
+ ctx.set_source_rgba(color[0], color[1], color[2], color[3])
+ ctx.fill()
#and again for the border
- cr.move_to(radiusout * math.cos(start_rad), radiusout * math.sin(start_rad))
- cr.arc(0, 0, radiusout, start_rad, stop_rad)
+ ctx.move_to(radiusout * math.cos(start_rad),
+ radiusout * math.sin(start_rad))
+ ctx.arc(0, 0, radiusout, start_rad, stop_rad)
if (start_rad - stop_rad) % (2 * math.pi) > 1e-5:
- radial_motion_type = cr.line_to
+ radial_motion_type = ctx.line_to
else:
- radial_motion_type = cr.move_to
- radial_motion_type(radiusin * math.cos(stop_rad), radiusin * math.sin(stop_rad))
- cr.arc_negative(0, 0, radiusin, stop_rad, start_rad)
- radial_motion_type(radiusout * math.cos(start_rad), radiusout * math.sin(start_rad))
- ##cr.append_path(path) # not working correct
- cr.set_source_rgb(0, 0, 0) # black
+ radial_motion_type = ctx.move_to
+ radial_motion_type(radiusin * math.cos(stop_rad),
+ radiusin * math.sin(stop_rad))
+ ctx.arc_negative(0, 0, radiusin, stop_rad, start_rad)
+ radial_motion_type(radiusout * math.cos(start_rad),
+ radiusout * math.sin(start_rad))
+ ##ctx.append_path(path) # not working correct
+ ctx.set_source_rgb(0, 0, 0) # black
if thick:
- cr.set_line_width(3)
+ ctx.set_line_width(3)
else:
- cr.set_line_width(1)
- cr.stroke()
- cr.set_line_width(1)
+ ctx.set_line_width(1)
+ ctx.stroke()
+ ctx.set_line_width(1)
- def draw_innerring(self, cr, person, userdata, start, inc):
+ def draw_innerring(self, ctx, person, userdata, start, inc):
"""
Procedure to draw a person in the inner ring position
"""
@@ -520,65 +568,69 @@ class FanChartBaseWidget(Gtk.DrawingArea):
# add child to angle storage
self.angle[-2].append([thetamin, thetamax, None])
#draw child now
- cr.move_to(rmin*math.cos(thetamin), rmin*math.sin(thetamin))
- cr.arc(0, 0, rmin, thetamin, thetamax)
- cr.line_to(rmax*math.cos(thetamax), rmax*math.sin(thetamax))
- cr.arc_negative(0, 0, rmax, thetamax, thetamin)
- cr.close_path()
- ##path = cr.copy_path() # not working correct
- cr.set_source_rgb(0, 0, 0) # black
- cr.set_line_width(1)
- cr.stroke()
+ ctx.move_to(rmin*math.cos(thetamin), rmin*math.sin(thetamin))
+ ctx.arc(0, 0, rmin, thetamin, thetamax)
+ ctx.line_to(rmax*math.cos(thetamax), rmax*math.sin(thetamax))
+ ctx.arc_negative(0, 0, rmax, thetamax, thetamin)
+ ctx.close_path()
+ ##path = ctx.copy_path() # not working correct
+ ctx.set_source_rgb(0, 0, 0) # black
+ ctx.set_line_width(1)
+ ctx.stroke()
#now again to fill
if person:
- r, g, b, a = self.background_box(person, -1, userdata)
+ red, green, blue, alpha = self.background_box(person, -1, userdata)
else:
- r=255; g=255; b=255; a=1
- cr.move_to(rmin*math.cos(thetamin), rmin*math.sin(thetamin))
- cr.arc(0, 0, rmin, thetamin, thetamax)
- cr.line_to(rmax*math.cos(thetamax), rmax*math.sin(thetamax))
- cr.arc_negative(0, 0, rmax, thetamax, thetamin)
- cr.close_path()
- ##cr.append_path(path) # not working correct
- cr.set_source_rgba(r/255., g/255., b/255., a)
- cr.fill()
+ red = green = blue = 255
+ alpha = 1
+ ctx.move_to(rmin*math.cos(thetamin), rmin*math.sin(thetamin))
+ ctx.arc(0, 0, rmin, thetamin, thetamax)
+ ctx.line_to(rmax*math.cos(thetamax), rmax*math.sin(thetamax))
+ ctx.arc_negative(0, 0, rmax, thetamax, thetamin)
+ ctx.close_path()
+ ##ctx.append_path(path) # not working correct
+ ctx.set_source_rgba(red/255., green/255., blue/255., alpha)
+ ctx.fill()
- def draw_person(self, cr, person, radiusin, radiusout, start_rad, stop_rad,
- generation, dup, userdata, thick=False, has_moregen_indicator = False,
- is_central_person=False):
+ def draw_person(self, ctx, person, radiusin, radiusout, start_rad, stop_rad,
+ generation, dup, userdata, thick=False,
+ has_moregen_indicator=False, is_central_person=False):
"""
Display the piece of pie for a given person. start_rad and stop_rad
are in radians.
"""
- cr.save()
+ ctx.save()
# If we need an indicator of more generations:
if has_moregen_indicator:
# draw an indicator
- color=(1.0, 1.0, 1.0, 1.0) # white
- self.draw_radbox(cr, radiusout, radiusout + BORDER_EDGE_WIDTH, start_rad, stop_rad, color, thick=False)
+ color = (1.0, 1.0, 1.0, 1.0) # white
+ self.draw_radbox(ctx, radiusout, radiusout + BORDER_EDGE_WIDTH,
+ start_rad, stop_rad, color, thick=False)
# get the color of the background
if not person:
# if called on None, let's make a transparent box
- r, g, b, a = (255, 255, 255, 0)
+ red, green, blue, alpha = (255, 255, 255, 0)
elif dup:
- r, g, b = self.dupcolor #duplicate color
- a = 1.0
+ red, green, blue = self.dupcolor #duplicate color
+ alpha = 1.0
else:
- r, g, b, a = self.background_box(person, generation, userdata)
- color=(r/255., g/255., b/255., a)
+ red, green, blue, alpha = self.background_box(person, generation,
+ userdata)
+ color = (red/255., green/255., blue/255., alpha)
# now draw the person
if not is_central_person:
- self.draw_radbox(cr, radiusin, radiusout, start_rad, stop_rad, color, thick)
+ self.draw_radbox(ctx, radiusin, radiusout, start_rad, stop_rad,
+ color, thick)
else:
#special box for centrer pers
- cr.arc(0, 0, radiusout, 0, 2 * math.pi)
- if self.childring and len(self.childrenroot)>0:
- cr.arc_negative(0, 0, radiusin, 2 * math.pi, 0)
- cr.close_path()
- cr.set_source_rgba(*color)
- cr.fill()
+ ctx.arc(0, 0, radiusout, 0, 2 * math.pi)
+ if self.childring and self.childrenroot:
+ ctx.arc_negative(0, 0, radiusin, 2 * math.pi, 0)
+ ctx.close_path()
+ ctx.set_source_rgba(*color)
+ ctx.fill()
if self.last_x is None or self.last_y is None:
#we are not in a move, so draw text
@@ -586,56 +638,98 @@ class FanChartBaseWidget(Gtk.DrawingArea):
if self.radialtext: ## and generation >= 6:
space_arc_text = (radiusin+radiusout)/2 * (stop_rad-start_rad)
# is there more space to print it radial ?
- radial= (space_arc_text < (radiusout-radiusin) * 1.1)
- self.draw_person_text(cr, person, radiusin, radiusout, start_rad, stop_rad,
- radial, self.fontcolor(r, g, b, a), self.fontbold(a), can_flip=not is_central_person)
- cr.restore()
+ radial = (space_arc_text < (radiusout-radiusin) * 1.1)
+ self.draw_person_text(ctx, person, radiusin, radiusout,
+ start_rad, stop_rad, radial,
+ self.fontcolor(red, green, blue, alpha),
+ self.fontbold(alpha),
+ can_flip=not is_central_person)
+ ctx.restore()
- def draw_person_text(self, cr, person, radiusin, radiusout, start, stop,
- radial=False, fontcolor=(0, 0, 0), bold=False, can_flip = True):
- if not person: return
+ def draw_person_text(self, ctx, person, radiusin, radiusout, start, stop,
+ radial=False, fontcolor=(0, 0, 0), bold=False,
+ can_flip=True):
+ """
+ Draw the piece of pie for a given person.
+ """
+ if not person:
+ return
draw_radial = radial and self.radialtext
try:
alive = probably_alive(person, self.dbstate.db)
except RuntimeError:
alive = False
if not self.twolinename:
- name=name_displayer.display(person)
+ name = name_displayer.display(person)
+ if self.showid:
+ name += " (" + person.gramps_id + ")"
if self.uistate.symbols and not alive:
name = self.dth + ' ' + name
- self.draw_text(cr, name, radiusin, radiusout, start, stop, draw_radial,
- fontcolor, bold)
+ self.draw_text(ctx, name, radiusin, radiusout, start, stop,
+ draw_radial, fontcolor, bold)
else:
- text=name_displayer.display(person)
- text_line1=name_displayer.display_format(person, TWO_LINE_FORMAT_1)
- text_line2=name_displayer.display_format(person, TWO_LINE_FORMAT_2)
+ #text=name_displayer.display(person)
+ if self.showid:
+ text_line1 = "(" + person.gramps_id + ") "
+ else:
+ text_line1 = ""
+ text_line1 += name_displayer.display_format(person,
+ TWO_LINE_FORMAT_1)
+ text_line2 = name_displayer.display_format(person,
+ TWO_LINE_FORMAT_2)
if draw_radial:
- split_frac_line1=0.5
- flipped = can_flip and ((math.degrees((start+stop)/2.0) + self.rotate_value - 90) % 360 < 179 and self.flipupsidedownname)
+ split_frac_line1 = 0.5
+ flipped = can_flip and ((math.degrees((start+stop)/2.0) +
+ self.rotate_value - 90) % 360 < 179
+ and self.flipupsidedownname)
if flipped:
- middle=(start*split_frac_line1+stop*(1.0-split_frac_line1))
- (a11,a12,a21,a22)=(middle,stop,start,middle)
+ middle = (start * split_frac_line1 +
+ stop * (1.0 - split_frac_line1))
+ (a11, a12, a21, a22) = (middle, stop, start, middle)
else:
- middle=(start*(1.0-split_frac_line1)+stop*split_frac_line1)
- (a11,a12,a21,a22)=(start,middle,middle,stop)
- written_textwidth=self.draw_text(cr, text_line1, radiusin, radiusout, a11, a12, draw_radial, fontcolor, bold=1, flipped=flipped)
+ middle = (start * (1.0 - split_frac_line1) +
+ stop * split_frac_line1)
+ (a11, a12, a21, a22) = (start, middle, middle, stop)
+ written_textwidth = self.draw_text(ctx, text_line1, radiusin,
+ radiusout, a11, a12,
+ draw_radial, fontcolor,
+ bold=1, flipped=flipped)
if written_textwidth == 0 and text_line1 != "":
#Not enought space for 2 line, fallback to 1 line
- written_textwidth=self.draw_text(cr, text_line1, radiusin, radiusout, start, stop, draw_radial, fontcolor, bold=1, flipped=flipped)
- self.draw_text(cr, text_line2, radiusin+written_textwidth+PAD_TEXT, radiusout, start, stop, draw_radial, fontcolor, bold, flipped)
+ written_textwidth = self.draw_text(ctx, text_line1,
+ radiusin, radiusout,
+ start, stop, draw_radial,
+ fontcolor, bold=1,
+ flipped=flipped)
+ self.draw_text(ctx, text_line2,
+ radiusin+written_textwidth+PAD_TEXT,
+ radiusout, start, stop, draw_radial,
+ fontcolor, bold, flipped)
else:
- self.draw_text(cr, text_line2, radiusin, radiusout, a21, a22, draw_radial, fontcolor, bold, flipped)
+ self.draw_text(ctx, text_line2, radiusin, radiusout, a21,
+ a22, draw_radial, fontcolor, bold, flipped)
else:
- middle=(radiusin*.5+radiusout*.5)
- flipped = can_flip and ((math.degrees((start+stop)/2.0) + self.rotate_value) % 360 < 179 and self.flipupsidedownname)
+ middle = (radiusin * .5 + radiusout * .5)
+ flipped = can_flip and ((math.degrees((start+stop)/2.0) +
+ self.rotate_value) % 360 < 179
+ and self.flipupsidedownname)
if flipped:
- self.draw_text(cr, text_line2, middle, radiusout, start, stop, draw_radial, fontcolor, bold=0, flipped=flipped)
- self.draw_text(cr, text_line1, radiusin, middle, start, stop, draw_radial, fontcolor, bold=1, flipped=flipped)
+ self.draw_text(ctx, text_line2, middle, radiusout,
+ start, stop, draw_radial, fontcolor,
+ bold=0, flipped=flipped)
+ self.draw_text(ctx, text_line1, radiusin, middle,
+ start, stop, draw_radial, fontcolor,
+ bold=1, flipped=flipped)
else:
- self.draw_text(cr, text_line1, middle, radiusout, start, stop, draw_radial, fontcolor, bold=1, flipped=flipped)
- self.draw_text(cr, text_line2, radiusin, middle, start, stop, draw_radial, fontcolor, bold=0, flipped=flipped)
+ self.draw_text(ctx, text_line1, middle, radiusout,
+ start, stop, draw_radial, fontcolor,
+ bold=1, flipped=flipped)
+ self.draw_text(ctx, text_line2, radiusin, middle,
+ start, stop, draw_radial, fontcolor,
+ bold=0, flipped=flipped)
- def wrap_truncate_layout(self, layout, font, width_pixels, height_pixels, tryrescale=True):
+ def wrap_truncate_layout(self, layout, font, width_pixels, height_pixels,
+ tryrescale=True):
"""
Uses the layout to wrap and truncate its text to given width
Returns: (w,h) as returned by layout.get_pixel_size()
@@ -650,27 +744,30 @@ class FanChartBaseWidget(Gtk.DrawingArea):
layout.set_text(layout.get_text(), layout.get_line(0).length)
#2. we check if height is ok
- w, h = layout.get_pixel_size()
- if h > height_pixels:
+ dummy_width, height = layout.get_pixel_size()
+ if height > height_pixels:
if tryrescale:
#try to reduce the height
- fontsize = max(height_pixels / h * font.get_size() /1.1, font.get_size()/2.0)
+ fontsize = max(height_pixels / height * font.get_size() /1.1,
+ font.get_size()/2.0)
font.set_size(fontsize)
- layout.set_text(all_text_backup, len(all_text_backup.encode('utf-8'))) # reducing the height allows for more characters
+ # reducing the height allows for more characters
+ layout.set_text(all_text_backup,
+ len(all_text_backup.encode('utf-8')))
layout.set_font_description(font)
if layout.get_line_count() > 1:
- layout.set_text(layout.get_text(), layout.get_line(0).length)
- w, h = layout.get_pixel_size()
+ layout.set_text(layout.get_text(),
+ layout.get_line(0).length)
+ dummy_width, height = layout.get_pixel_size()
# we check again if height is ok
- if h > height_pixels:
+ if height > height_pixels:
#we could not fix it, no text
- layout.set_text("",0)
+ layout.set_text("", 0)
layout.context_changed()
return layout.get_pixel_size()
- def draw_text(self, cr, text, radiusin, radiusout, start_rad, stop_rad,
- radial=False,
- fontcolor=(0, 0, 0), bold=False, flipped = False):
+ def draw_text(self, ctx, text, radiusin, radiusout, start_rad, stop_rad,
+ radial=False, fontcolor=(0, 0, 0), bold=False, flipped=False):
"""
Display text at a particular radius, between start_rad and stop_rad
radians.
@@ -680,15 +777,21 @@ class FanChartBaseWidget(Gtk.DrawingArea):
font.set_size(fontsize * Pango.SCALE)
if bold:
font.set_weight(Pango.Weight.BOLD)
- cr.save()
- cr.set_source_rgb(*fontcolor)
+ ctx.save()
+ ctx.set_source_rgb(*fontcolor)
if radial and self.radialtext:
- self.draw_radial_text(cr, text, radiusin, radiusout, start_rad, stop_rad, font, flipped)
+ self.draw_radial_text(ctx, text, radiusin, radiusout,
+ start_rad, stop_rad, font, flipped)
else:
- self.draw_arc_text(cr, text, radiusin, radiusout, start_rad, stop_rad, font, flipped)
- cr.restore()
+ self.draw_arc_text(ctx, text, radiusin, radiusout,
+ start_rad, stop_rad, font, flipped)
+ ctx.restore()
- def draw_radial_text(self, cr, text, radiusin, radiusout, start_rad, stop_rad, font, flipped):
+ def draw_radial_text(self, ctx, text, radiusin, radiusout,
+ start_rad, stop_rad, font, flipped):
+ """
+ Draw the text in the available portion.
+ """
layout = self.create_pango_layout(text)
if is_quartz():
PangoCairo.context_set_resolution(layout.get_context(), 72)
@@ -700,22 +803,26 @@ class FanChartBaseWidget(Gtk.DrawingArea):
avail_height = (stop_rad - start_rad) * radiusin - 2.0 * PAD_TEXT
avail_width = radiusout - radiusin - 2.0 * PAD_TEXT
- w, h = self.wrap_truncate_layout(layout, font, avail_width, avail_height, tryrescale=True)
+ dummy_width, height = self.wrap_truncate_layout(layout, font,
+ avail_width,
+ avail_height,
+ tryrescale=True)
# 2. now draw this text
# offset for cairo-font system is 90
if flipped:
- angle = (start_rad + stop_rad)/2 + (h / radiusin / 2) + math.pi
+ angle = (start_rad + stop_rad)/2 + (height / radiusin / 2) + math.pi
start_pos = -radiusout + PAD_TEXT
else:
- angle = (start_rad + stop_rad)/2 - (h / radiusin / 2)
+ angle = (start_rad + stop_rad)/2 - (height / radiusin / 2)
start_pos = radiusin + PAD_TEXT
- cr.rotate(angle)
+ ctx.rotate(angle)
layout.context_changed()
- cr.move_to(start_pos, 0)
- PangoCairo.show_layout(cr, layout)
+ ctx.move_to(start_pos, 0)
+ PangoCairo.show_layout(ctx, layout)
- def draw_arc_text(self, cr, text, radiusin, radiusout, start_rad, stop_rad, font, bottom_is_outside):
+ def draw_arc_text(self, ctx, text, radiusin, radiusout,
+ start_rad, stop_rad, font, bottom_is_outside):
"""
Display text at a particular radius, between start and stop
degrees, setting it up along the arc, center-justified.
@@ -729,31 +836,36 @@ class FanChartBaseWidget(Gtk.DrawingArea):
layout.set_wrap(Pango.WrapMode.WORD_CHAR)
# get height of text:
- textheight=layout.get_size()[1]/Pango.SCALE
- radius_text=(radiusin+radiusout)/2.0
+ textheight = layout.get_size()[1] / Pango.SCALE
+ radius_text = (radiusin + radiusout) / 2.0
# 1. compute available text space
avail_height = radiusout - radiusin - 2.0 * PAD_TEXT
avail_width = (stop_rad - start_rad) * radius_text - 2.0 * PAD_TEXT
- w, h = self.wrap_truncate_layout(layout, font, avail_width, avail_height, tryrescale=True)
+ width, dummy_height = self.wrap_truncate_layout(layout, font,
+ avail_width,
+ avail_height,
+ tryrescale=True)
# 2. Compute text position start angle
mid_rad = (stop_rad + start_rad)/2
- pos_rad = mid_rad - (w/2/radius_text)
- end_rad = pos_rad + (w/radius_text)
+ pos_rad = mid_rad - (width/2/radius_text)
+ end_rad = pos_rad + (width/radius_text)
# 3. Use the layout to provide us the metrics of the text box
- cr.new_path()
- PangoCairo.layout_path(cr, layout)
+ ctx.new_path()
+ PangoCairo.layout_path(ctx, layout)
# 4. The moment of truth: map the text box onto the sector, and render!
- warpPath(cr, \
- self.create_map_rect_to_sector(radius_text, pos_rad, end_rad, textheight, bottom_is_outside ))
- cr.fill()
+ warpPath(ctx, \
+ self.create_map_rect_to_sector(radius_text, pos_rad, end_rad,
+ textheight, bottom_is_outside))
+ ctx.fill()
@staticmethod
- def create_map_rect_to_sector(radius, start_rad, stop_rad, textheight, bottom_is_outside = False):
+ def create_map_rect_to_sector(radius, start_rad, stop_rad, textheight,
+ bottom_is_outside=False):
"""
Create a 2D-transform, mapping a rectangle onto a circle sector.
@@ -761,48 +873,57 @@ class FanChartBaseWidget(Gtk.DrawingArea):
:param start_rad: start radial angle of the sector, in radians
:param stop_rad: stop radial angle of the sector, in radians
:param textheight height of the text
- :param bottom_is_outside flag defining if we write with the bottom toward outside
+ :param bottom_is_outside flag defining if we write with the
+ bottom toward outside
:returns: a lambda (x,y)|->(xNew,yNew) to feed to warpPath.
"""
if bottom_is_outside:
- def phi(x):
- return -x/radius + stop_rad
- def rho(y):
- return radius + (y - textheight/2.0)
+ def phi(posx):
+ """ x in outside case """
+ return -posx / radius + stop_rad
+ def rho(posy):
+ """ y in outside case """
+ return radius + (posy - textheight / 2.0)
else:
- def phi(x):
- return x/radius + start_rad
- def rho(y):
- return radius - ( y - textheight/2.0)
- return lambda x, y: \
- (rho(y) * math.cos(phi(x)), rho(y) * math.sin(phi(x)))
+ def phi(posx):
+ """ x in inside case """
+ return posx / radius + start_rad
+ def rho(posy):
+ """ y in inside case """
+ return radius - (posy - textheight / 2.0)
+ return lambda posx, posy: (rho(posy) * math.cos(phi(posx)),
+ rho(posy) * math.sin(phi(posx)))
- def draw_gradient_legend(self, cr, halfdist):
+ def draw_gradient_legend(self, ctx, halfdist):
+ """
+ Draw the gradient legend
+ """
+ dummy_halfdist = halfdist
gradwidth = 10
gradheight = 10
starth = 15
startw = 5
- cr.save()
+ ctx.save()
- cr.translate(-self.center_xy[0], -self.center_xy[1])
+ ctx.translate(-self.center_xy[0], -self.center_xy[1])
font = Pango.FontDescription("")
fontsize = self.fontsize
font.set_size(fontsize * Pango.SCALE)
for color, text in zip(self.gradcol, self.gradval):
- cr.move_to(startw, starth)
- cr.rectangle(startw, starth, gradwidth, gradheight)
- cr.set_source_rgb(color[0], color[1], color[2])
- cr.fill()
+ ctx.move_to(startw, starth)
+ ctx.rectangle(startw, starth, gradwidth, gradheight)
+ ctx.set_source_rgb(color[0], color[1], color[2])
+ ctx.fill()
layout = self.create_pango_layout(text)
if is_quartz():
PangoCairo.context_set_resolution(layout.get_context(), 72)
layout.set_font_description(font)
- cr.move_to(startw+gradwidth+4, starth)
- cr.set_source_rgb(0, 0, 0) #black
- PangoCairo.show_layout(cr, layout)
+ ctx.move_to(startw+gradwidth+4, starth)
+ ctx.set_source_rgb(0, 0, 0) #black
+ PangoCairo.show_layout(ctx, layout)
starth = starth+gradheight
- cr.restore()
+ ctx.restore()
def cursor_on_tranlation_dot(self, curx, cury):
"""
@@ -813,27 +934,33 @@ class FanChartBaseWidget(Gtk.DrawingArea):
radius = math.sqrt((fanxy[0]) ** 2 + (fanxy[1]) ** 2)
return radius < TRANSLATE_PX
- def cursor_to_polar(self, curx, cury, get_raw_rads = False):
- # compute angle, radius in unrotated fan
+ def cursor_to_polar(self, curx, cury, get_raw_rads=False):
+ """
+ Compute angle, radius in unrotated fan
+ """
fanxy = curx - self.center_xy[0], cury - self.center_xy[1]
radius = math.sqrt((fanxy[0]) ** 2 + (fanxy[1]) ** 2)
#angle before rotation:
#children are in cairo angle (clockwise) from pi to 3 pi
#rads however is clock 0 to 2 pi
- raw_rads = math.atan2( fanxy[1], fanxy[0]) % (2 * math.pi)
- rads = (raw_rads - math.radians(self.rotate_value) ) % (2 * math.pi)
+ raw_rads = math.atan2(fanxy[1], fanxy[0]) % (2 * math.pi)
+ rads = (raw_rads - math.radians(self.rotate_value)) % (2 * math.pi)
if get_raw_rads:
return radius, rads, raw_rads
else:
return radius, rads
def radian_in_bounds(self, start_rad, rads, stop_rad):
- assert(start_rad <= stop_rad)
- # we compare (rads - start_rad) % (2.0 * math.pi) and (stop_rad - start_rad)
- slice = stop_rad - start_rad
+ """
+ We compare (rads - start_rad) % (2.0 * math.pi) and
+ (stop_rad - start_rad)
+ """
+ assert start_rad <= stop_rad
+ portion = stop_rad - start_rad
dist_rads_to_start_rads = (rads - start_rad) % (2.0 * math.pi)
- #print start_rad, rads, stop_rad, ". (rads-start), slice :", dist_rads_to_start_rads, slice
- return dist_rads_to_start_rads < slice
+ # print(start_rad, rads, stop_rad, ". (rads-start), portion :",
+ # dist_rads_to_start_rads, portion)
+ return dist_rads_to_start_rads < portion
def cell_address_under_cursor(self, curx, cury):
"""
@@ -864,18 +991,21 @@ class FanChartBaseWidget(Gtk.DrawingArea):
if person:
for family_handle in person.get_family_handle_list():
family = self.dbstate.db.get_family_from_handle(family_handle)
- if family and len(family.get_child_ref_list()) > 0:
+ if family and family.get_child_ref_list():
return True
return False
def on_key_press(self, widget, eventkey):
"""grab key press
"""
+ dummy_widget = widget
if self.mouse_x and self.mouse_y:
- cell_address = self.cell_address_under_cursor(self.mouse_x, self.mouse_y)
+ cell_address = self.cell_address_under_cursor(self.mouse_x,
+ self.mouse_y)
if cell_address is None:
return False
- person, family = self.person_at(cell_address), self.family_at(cell_address)
+ person, family = (self.person_at(cell_address),
+ self.family_at(cell_address))
if person and (Gdk.keyval_name(eventkey.keyval) == 'e'):
# we edit the person
self.edit_person_cb(None, person.handle)
@@ -888,6 +1018,10 @@ class FanChartBaseWidget(Gtk.DrawingArea):
return False
def on_mouse_down(self, widget, event):
+ """
+ What to do if we release a mouse button
+ """
+ dummy_widget = widget
self.translating = False # keep track of up/down/left/right movement
if event.button == 1:
@@ -918,7 +1052,8 @@ class FanChartBaseWidget(Gtk.DrawingArea):
#right click on person, context menu
# Do things based on state, event.get_state(), or button, event.button
if is_right_click(event):
- person, family = self.person_at(cell_address), self.family_at(cell_address)
+ person, family = (self.person_at(cell_address),
+ self.family_at(cell_address))
fhandle = None
if family:
fhandle = family.handle
@@ -929,6 +1064,10 @@ class FanChartBaseWidget(Gtk.DrawingArea):
return False
def on_mouse_move(self, widget, event):
+ """
+ What to do if we move the mouse
+ """
+ dummy_widget = widget
self._mouse_click = False
if self.last_x is None or self.last_y is None:
# while mouse is moving, we must update the tooltip based on person
@@ -943,13 +1082,16 @@ class FanChartBaseWidget(Gtk.DrawingArea):
#translate or rotate should happen
if self.translating:
- canonical_center = self.center_xy_from_delta([0,0])
- self.center_delta_xy = canonical_center[0]-event.x,canonical_center[1]-event.y
+ canonical_center = self.center_xy_from_delta([0, 0])
+ self.center_delta_xy = (canonical_center[0] - event.x,
+ canonical_center[1] - event.y)
self.center_xy = self.center_xy_from_delta()
else:
# get the angles of the two points from the center:
- start_angle = math.atan2(event.y - self.center_xy[1], event.x - self.center_xy[0])
- end_angle = math.atan2(self.last_y - self.center_xy[1], self.last_x - self.center_xy[0])
+ start_angle = math.atan2(event.y - self.center_xy[1],
+ event.x - self.center_xy[0])
+ end_angle = math.atan2(self.last_y - self.center_xy[1],
+ self.last_x - self.center_xy[0])
# now look at change in angle:
diff_angle = (end_angle - start_angle) % (math.pi * 2.0)
self.rotate_value -= math.degrees(diff_angle)
@@ -959,15 +1101,22 @@ class FanChartBaseWidget(Gtk.DrawingArea):
return True
def center_xy_from_delta(self, delta=None):
+ """
+ return the x and y position for the center of the canvas
+ """
alloc = self.get_allocation()
- x, y, w, h = alloc.x, alloc.y, alloc.width, alloc.height
- if delta is None: delta = self.center_delta_xy
+ (dummy_x, dummy_y,
+ width, height) = alloc.x, alloc.y, alloc.width, alloc.height
+ if delta is None:
+ delta = self.center_delta_xy
if self.form == FORM_CIRCLE:
- canvas_xy = w/2 - delta[0], h/2 - delta[1]
+ canvas_xy = width / 2 - delta[0], height / 2 - delta[1]
elif self.form == FORM_HALFCIRCLE:
- canvas_xy = w/2 - delta[0], h - self.CENTER - PAD_PX - delta[1]
+ canvas_xy = (width / 2 - delta[0],
+ height - self.CENTER - PAD_PX - delta[1])
elif self.form == FORM_QUADRANT:
- canvas_xy = self.CENTER + PAD_PX - delta[0], h - self.CENTER - PAD_PX - delta[1]
+ canvas_xy = (self.CENTER + PAD_PX - delta[0],
+ height - self.CENTER - PAD_PX - delta[1])
return canvas_xy
def do_mouse_click(self):
@@ -977,6 +1126,11 @@ class FanChartBaseWidget(Gtk.DrawingArea):
pass
def on_mouse_up(self, widget, event):
+ """
+ What to do if we move the mouse
+ """
+ dummy_widget = widget
+ dummy_event = event
if self._mouse_click:
self.do_mouse_click()
return True
@@ -996,11 +1150,15 @@ class FanChartBaseWidget(Gtk.DrawingArea):
def on_drag_begin(self, widget, data):
"""Set up some inital conditions for drag. Set up icon."""
+ dummy_widget = widget
+ dummy_data = data
self.in_drag = True
self.drag_source_set_icon_name('gramps-person')
def on_drag_end(self, widget, data):
"""Set up some inital conditions for drag. Set up icon."""
+ dummy_widget = widget
+ dummy_data = data
self.in_drag = False
def on_drag_data_get(self, widget, context, sel_data, info, time):
@@ -1008,6 +1166,8 @@ class FanChartBaseWidget(Gtk.DrawingArea):
Returned parameters after drag.
Specified for 'person-link', for others return text info about person.
"""
+ dummy_widget = widget
+ dummy_time = time
tgs = [x.name() for x in context.list_targets()]
person = self.person_at(self._mouse_click_cell_address)
if person:
@@ -1016,22 +1176,32 @@ class FanChartBaseWidget(Gtk.DrawingArea):
id(self), person.get_handle(), 0)
sel_data.set(sel_data.get_target(), 8, pickle.dumps(data))
elif ('TEXT' in tgs or 'text/plain' in tgs) and info == 0:
- sel_data.set_text(self.format_helper.format_person(person, 11), -1)
+ sel_data.set_text(self.format_helper.format_person(person,
+ 11), -1)
- def on_drag_data_received(self, widget, context, x, y, sel_data, info, time):
+ def on_drag_data_received(self, widget, context, pos_x, pos_y,
+ sel_data, info, time):
"""
Handle the standard gtk interface for drag_data_received.
If the selection data is defined, extract the value from sel_data.data
"""
- radius, rads = self.cursor_to_polar(x, y)
+ dummy_context = context
+ dummy_widget = widget
+ dummy_info = info
+ dummy_time = time
+ radius, dummy_rads = self.cursor_to_polar(pos_x, pos_y)
if radius < self.CENTER:
if sel_data and sel_data.get_data():
- (drag_type, idval, handle, val) = pickle.loads(sel_data.get_data())
+ (dummy_drag_type, dummy_idval, handle,
+ dummy_val) = pickle.loads(sel_data.get_data())
self.goto(self, handle)
def edit_person_cb(self, obj, person_handle):
+ """
+ Edit a person
+ """
person = self.dbstate.db.get_person_from_handle(person_handle)
if person:
try:
@@ -1042,6 +1212,9 @@ class FanChartBaseWidget(Gtk.DrawingArea):
return False
def edit_fam_cb(self, obj, family_handle):
+ """
+ Edit a family
+ """
fam = self.dbstate.db.get_family_from_handle(family_handle)
if fam:
try:
@@ -1067,13 +1240,19 @@ class FanChartWidget(FanChartBaseWidget):
Fan Chart Widget. Handles visualization of data in self.data.
See main() of FanChartGramplet for example of model format.
"""
- self.set_values(None, 9, BACKGROUND_GRAD_GEN, True, True, True, True, 'Sans', '#0000FF',
- '#FF0000', None, 0.5, FORM_CIRCLE)
+ self.angle = {}
+ self.childrenroot = []
+ self.rootangle_rad = []
+ self.menu = None
+ self.data = {}
+ self.set_values(None, 9, BACKGROUND_GRAD_GEN, True, True, True, True,
+ 'Sans', '#0000FF', '#FF0000', None, 0.5, FORM_CIRCLE,
+ False)
FanChartBaseWidget.__init__(self, dbstate, uistate, callback_popup)
def set_values(self, root_person_handle, maxgen, background, childring,
- flipupsidedownname, twolinename, radialtext, fontdescr,
- grad_start, grad_end, filter, alpha_filter, form):
+ flipupsidedownname, twolinename, radialtext, fontdescr,
+ grad_start, grad_end, filtr, alpha_filter, form, showid):
"""
Reset the values to be used:
@@ -1083,15 +1262,17 @@ class FanChartWidget(FanChartBaseWidget):
:type background: int
:param childring: to show the center ring with children or not
:param twolinename: uses two lines for the display of person's name
- :param flipupsidedownname: flip name on the left of the fanchart for the display of person's name
+ :param flipupsidedownname: flip name on the left of the fanchart
+ for the display of person's name
:param radialtext: try to use radial text or not
:param fontdescr: string describing the font to use
:param grad_start: colors to use for background procedure
:param grad_end: colors to use for background procedure
- :param filter: the person filter to apply to the people in the chart
+ :param filtr: the person filter to apply to the people in the chart
:param alpha: the alpha transparency value (0-1) to apply to filtered
out data
:param form: the ``FORM_`` constant for the fanchart
+ :param showid: to show the gramps_id or not
"""
self.rootpersonh = root_person_handle
self.generations = maxgen
@@ -1103,9 +1284,10 @@ class FanChartWidget(FanChartBaseWidget):
self.fontdescr = fontdescr
self.grad_start = grad_start
self.grad_end = grad_end
- self.filter = filter
+ self.filter = filtr
self.alpha_filter = alpha_filter
self.form = form
+ self.showid = showid
def set_generations(self):
"""
@@ -1126,13 +1308,17 @@ class FanChartWidget(FanChartBaseWidget):
self.data[i] = [(None,) * 4] * 2 ** i
self.angle[i] = []
angle = self.rootangle_rad[0]
- slice = 1/ (2 ** i) * (self.rootangle_rad[1] - self.rootangle_rad[0])
- for count in range(len(self.data[i])):
+ portion = 1/ (2 ** i) * (self.rootangle_rad[1] -
+ self.rootangle_rad[0])
+ for dummy_count in range(len(self.data[i])):
# start, stop, state
- self.angle[i].append([angle, angle + slice, NORMAL])
- angle += slice
+ self.angle[i].append([angle, angle + portion, NORMAL])
+ angle += portion
def _fill_data_structures(self):
+ """
+ Initialise the data structures
+ """
self.set_generations()
if not self.rootpersonh:
return
@@ -1155,9 +1341,10 @@ class FanChartWidget(FanChartBaseWidget):
for current in range(1, self.generations):
parent = 0
# person, parents, children
- for (p, q, c, d) in self.data[current - 1]:
+ for (pers, dummy_q, dummy_c, dummy_d) in self.data[current - 1]:
# Get father's and mother's details:
- for person in [self._get_parent(p, True), self._get_parent(p, False)]:
+ for person in [self._get_parent(pers, True),
+ self._get_parent(pers, False)]:
if current == self.generations - 1:
parents = self._have_parents(person)
else:
@@ -1174,9 +1361,9 @@ class FanChartWidget(FanChartBaseWidget):
TODO: is there no util function for this
"""
if person:
- m = self._get_parent(person, False)
- f = self._get_parent(person, True)
- return not m is f is None
+ mother = self._get_parent(person, False)
+ father = self._get_parent(person, True)
+ return not mother is father is None
return False
def _get_parent(self, person, father):
@@ -1194,7 +1381,8 @@ class FanChartWidget(FanChartBaseWidget):
else:
person_handle = Family.get_mother_handle(family)
if person_handle:
- return self.dbstate.db.get_person_from_handle(person_handle)
+ fct = self.dbstate.db.get_person_from_handle
+ return fct(person_handle)
return None
def gen_pixels(self):
@@ -1204,10 +1392,14 @@ class FanChartWidget(FanChartBaseWidget):
return PIXELS_PER_GENERATION
def nrgen(self):
+ """
+ return the generation if we have a person to draw
+ """
#compute the number of generations present
for generation in range(self.generations - 1, 0, -1):
- for p in range(len(self.data[generation])):
- (person, parents, child, userdata) = self.data[generation][p]
+ for idx in range(len(self.data[generation])):
+ (person, dummy_parents, dummy_child,
+ dummy_userdata) = self.data[generation][idx]
if person:
return generation
return 1
@@ -1216,22 +1408,24 @@ class FanChartWidget(FanChartBaseWidget):
"""
Compute the half radius of the circle
"""
- return PIXELS_PER_GENERATION * self.nrgen() + self.CENTER + BORDER_EDGE_WIDTH
+ return (PIXELS_PER_GENERATION * self.nrgen() +
+ self.CENTER + BORDER_EDGE_WIDTH)
- def get_radiusinout_for_generation(self,generation):
- outerradius=generation * PIXELS_PER_GENERATION + self.CENTER
- innerradius=(generation-1) * PIXELS_PER_GENERATION + self.CENTER
- if generation==0:
- innerradius= CHILDRING_WIDTH + TRANSLATE_PX
- return (innerradius,outerradius)
+ def get_radiusinout_for_gen(self, generation):
+ outerradius = generation * PIXELS_PER_GENERATION + self.CENTER
+ innerradius = (generation - 1) * PIXELS_PER_GENERATION + self.CENTER
+ if generation == 0:
+ innerradius = CHILDRING_WIDTH + TRANSLATE_PX
+ return (innerradius, outerradius)
def people_generator(self):
"""
a generator over all people outside of the core person
"""
for generation in range(self.generations):
- for p in range(len(self.data[generation])):
- (person, parents, child, userdata) = self.data[generation][p]
+ for idx in range(len(self.data[generation])):
+ (person, dummy_parents, dummy_child,
+ userdata) = self.data[generation][idx]
yield (person, userdata)
def innerpeople_generator(self):
@@ -1239,21 +1433,21 @@ class FanChartWidget(FanChartBaseWidget):
a generator over all people inside of the core person
"""
for childdata in self.childrenroot:
- (person, parents, child, userdata) = childdata
+ (person, dummy_parents, dummy_child, userdata) = childdata
yield (person, userdata)
- def draw(self, cr=None, scale=1.0):
+ def draw(self, ctx=None, scale=1.0):
"""
The main method to do the drawing.
- If cr is given, we assume we draw draw raw on the cairo context cr
- To draw in GTK3 and use the allocation, set cr=None.
+ If ctx is given, we assume we draw draw raw on the cairo context ctx
+ To draw in GTK3 and use the allocation, set ctx=None.
Note: when drawing for display, to counter a Gtk issue with scrolling
or resizing the drawing window, we draw on a surface, then copy to the
drawing context when the Gtk 'draw' signal arrives.
"""
# first do size request of what we will need
halfdist = self.halfdist()
- if not cr: # Display
+ if not ctx: # Display
if self.form == FORM_CIRCLE:
size_w = size_h = 2 * halfdist
elif self.form == FORM_HALFCIRCLE:
@@ -1269,57 +1463,68 @@ class FanChartWidget(FanChartBaseWidget):
size_h = self.get_allocated_height()
self.surface = cairo.ImageSurface(cairo.FORMAT_ARGB32,
size_w, size_h)
- cr = cairo.Context(self.surface)
+ ctx = cairo.Context(self.surface)
self.center_xy = self.center_xy_from_delta()
- cr.translate(*self.center_xy)
+ ctx.translate(*self.center_xy)
else: # printing
if self.form == FORM_QUADRANT:
self.center_xy = self.CENTER + PIXELS_PER_GENERATION, halfdist
else:
self.center_xy = halfdist + PIXELS_PER_GENERATION, halfdist
- cr.scale(scale, scale)
- cr.translate(*self.center_xy)
+ ctx.scale(scale, scale)
+ ctx.translate(*self.center_xy)
- cr.save()
- cr.rotate(math.radians(self.rotate_value))
+ ctx.save()
+ ctx.rotate(math.radians(self.rotate_value))
for generation in range(self.generations - 1, 0, -1):
- for p in range(len(self.data[generation])):
- (person, parents, child, userdata) = self.data[generation][p]
+ for idx in range(len(self.data[generation])):
+ (person, parents, child, userdata) = self.data[generation][idx]
if person:
- start, stop, state = self.angle[generation][p]
+ start, stop, state = self.angle[generation][idx]
if state in [NORMAL, EXPANDED]:
- radiusin,radiusout = self.get_radiusinout_for_generation(generation)
+ (radiusin,
+ radiusout) = self.get_radiusinout_for_gen(generation)
dup = False
- self.draw_person(cr, person, radiusin, radiusout, start, stop,
- generation, dup, userdata, thick=(state == EXPANDED),
- has_moregen_indicator = (generation == self.generations - 1 and parents) )
- cr.restore()
+ indicator = (generation == self.generations - 1
+ and parents)
+ self.draw_person(ctx, person, radiusin, radiusout,
+ start, stop, generation, dup, userdata,
+ thick=(state == EXPANDED),
+ has_moregen_indicator=indicator)
+ ctx.restore()
# Draw center person:
(person, parents, child, userdata) = self.data[0][0]
if person:
- radiusin, radiusout = self.get_radiusinout_for_generation(0)
- if not child: radiusin = TRANSLATE_PX
- self.draw_person(cr, person, radiusin, radiusout, math.pi/2, math.pi/2 + 2*math.pi,
- 0, False, userdata, thick = False, has_moregen_indicator = False, is_central_person = True)
+ radiusin, radiusout = self.get_radiusinout_for_gen(0)
+ if not child:
+ radiusin = TRANSLATE_PX
+ self.draw_person(ctx, person, radiusin, radiusout,
+ math.pi/2, math.pi/2 + 2*math.pi,
+ 0, False, userdata, thick=False,
+ has_moregen_indicator=False,
+ is_central_person=True)
#draw center disk to move chart
- cr.set_source_rgb(0, 0, 0) # black
- cr.move_to(TRANSLATE_PX, 0)
- cr.arc(0, 0, TRANSLATE_PX, 0, 2 * math.pi)
+ ctx.set_source_rgb(0, 0, 0) # black
+ ctx.move_to(TRANSLATE_PX, 0)
+ ctx.arc(0, 0, TRANSLATE_PX, 0, 2 * math.pi)
if child: # has at least one child
- cr.fill()
+ ctx.fill()
else:
- cr.stroke()
+ ctx.stroke()
if child and self.childring:
- self.draw_childring(cr)
+ self.draw_childring(ctx)
if self.background in [BACKGROUND_GRAD_AGE, BACKGROUND_GRAD_PERIOD]:
- self.draw_gradient_legend(cr, halfdist)
+ self.draw_gradient_legend(ctx, halfdist)
- def draw_childring(self, cr):
- cr.move_to(TRANSLATE_PX + CHILDRING_WIDTH, 0)
- cr.set_source_rgb(0, 0, 0) # black
- cr.set_line_width(1)
- cr.arc(0, 0, TRANSLATE_PX + CHILDRING_WIDTH, 0, 2 * math.pi)
- cr.stroke()
+ def draw_childring(self, ctx):
+ """
+ Draw the ring for the children
+ """
+ ctx.move_to(TRANSLATE_PX + CHILDRING_WIDTH, 0)
+ ctx.set_source_rgb(0, 0, 0) # black
+ ctx.set_line_width(1)
+ ctx.arc(0, 0, TRANSLATE_PX + CHILDRING_WIDTH, 0, 2 * math.pi)
+ ctx.stroke()
nrchild = len(self.childrenroot)
#Y axis is downward. positve angles are hence clockwise
startangle = math.pi
@@ -1328,40 +1533,54 @@ class FanChartWidget(FanChartBaseWidget):
else:
angleinc = 2 * math.pi / nrchild
for childdata in self.childrenroot:
- (person, parents, child, userdata) = childdata
- self.draw_innerring(cr, person, userdata, startangle, angleinc)
+ (person, dummy_parents, dummy_child, userdata) = childdata
+ self.draw_innerring(ctx, person, userdata, startangle, angleinc)
startangle += angleinc
def expand_parents(self, generation, selected, current):
- if generation >= self.generations: return
+ """
+ Expand the parents
+ """
+ if generation >= self.generations:
+ return
selected = 2 * selected
start, stop, state = self.angle[generation][selected]
if state in [NORMAL, EXPANDED]:
- slice = (stop - start) * 2.0
- self.angle[generation][selected] = [current, current+slice, state]
+ portion = (stop - start) * 2.0
+ self.angle[generation][selected] = [current, current + portion,
+ state]
self.expand_parents(generation + 1, selected, current)
- current += slice
+ current += portion
start, stop, state = self.angle[generation][selected+1]
if state in [NORMAL, EXPANDED]:
- slice = (stop - start) * 2.0
- self.angle[generation][selected+1] = [current,current+slice,
+ portion = (stop - start) * 2.0
+ self.angle[generation][selected+1] = [current, current + portion,
state]
- self.expand_parents(generation + 1, selected+1, current)
+ self.expand_parents(generation + 1, selected + 1, current)
- def show_parents(self, generation, selected, angle, slice):
- if generation >= self.generations: return
+ def show_parents(self, generation, selected, angle, portion):
+ """
+ Show the parents
+ """
+ if generation >= self.generations:
+ return
selected *= 2
self.angle[generation][selected][0] = angle
- self.angle[generation][selected][1] = angle + slice
+ self.angle[generation][selected][1] = angle + portion
self.angle[generation][selected][2] = NORMAL
- self.show_parents(generation+1, selected, angle, slice/2.0)
- self.angle[generation][selected+1][0] = angle + slice
- self.angle[generation][selected+1][1] = angle + slice + slice
+ self.show_parents(generation + 1, selected, angle, portion / 2.0)
+ self.angle[generation][selected+1][0] = angle + portion
+ self.angle[generation][selected+1][1] = angle + portion + portion
self.angle[generation][selected+1][2] = NORMAL
- self.show_parents(generation+1, selected + 1, angle + slice, slice/2.0)
+ self.show_parents(generation + 1, selected + 1, angle + portion,
+ portion / 2.0)
def hide_parents(self, generation, selected, angle):
- if generation >= self.generations: return
+ """
+ Hide the parents
+ """
+ if generation >= self.generations:
+ return
selected = 2 * selected
self.angle[generation][selected][0] = angle
self.angle[generation][selected][1] = angle
@@ -1373,23 +1592,30 @@ class FanChartWidget(FanChartBaseWidget):
self.hide_parents(generation + 1, selected+1, angle)
def shrink_parents(self, generation, selected, current):
- if generation >= self.generations: return
+ """
+ Shrink the parents
+ """
+ if generation >= self.generations:
+ return
selected = 2 * selected
start, stop, state = self.angle[generation][selected]
if state in [NORMAL, EXPANDED]:
- slice = (stop - start) / 2.0
- self.angle[generation][selected] = [current, current + slice,
+ portion = (stop - start) / 2.0
+ self.angle[generation][selected] = [current, current + portion,
state]
self.shrink_parents(generation + 1, selected, current)
- current += slice
+ current += portion
start, stop, state = self.angle[generation][selected+1]
if state in [NORMAL, EXPANDED]:
- slice = (stop - start) / 2.0
- self.angle[generation][selected+1] = [current, current+slice,
+ portion = (stop - start) / 2.0
+ self.angle[generation][selected+1] = [current, current+portion,
state]
self.shrink_parents(generation + 1, selected+1, current)
def toggle_cell_state(self, cell_address):
+ """
+ Toggle the cell (expanded/shrinked)
+ """
generation, selected = cell_address
if generation < 1:
return
@@ -1400,7 +1626,7 @@ class FanChartWidget(FanChartBaseWidget):
stop = gstop + (gstop - gstart)
self.angle[generation][selected] = [gstart, stop, EXPANDED]
self.expand_parents(generation + 1, selected, gstart)
- start, stop, state = self.angle[generation][selected+1]
+ start, stop, dummy_state = self.angle[generation][selected+1]
self.angle[generation][selected+1] = [stop, stop, COLLAPSED]
self.hide_parents(generation+1, selected+1, stop)
else:
@@ -1408,30 +1634,30 @@ class FanChartWidget(FanChartBaseWidget):
start = gstart - (gstop - gstart)
self.angle[generation][selected] = [start, gstop, EXPANDED]
self.expand_parents(generation + 1, selected, start)
- start, stop, state = self.angle[generation][selected-1]
+ start, stop, dummy_state = self.angle[generation][selected-1]
self.angle[generation][selected-1] = [start, start, COLLAPSED]
self.hide_parents(generation+1, selected-1, start)
elif gstate == EXPANDED: # let's shrink
if selected % 2 == 0:
# shrink from right
- slice = (gstop - gstart)/2.0
- stop = gstop - slice
+ portion = (gstop - gstart)/2.0
+ stop = gstop - portion
self.angle[generation][selected] = [gstart, stop, NORMAL]
self.shrink_parents(generation+1, selected, gstart)
self.angle[generation][selected+1][0] = stop # start
- self.angle[generation][selected+1][1] = stop + slice # stop
+ self.angle[generation][selected+1][1] = stop + portion # stop
self.angle[generation][selected+1][2] = NORMAL
- self.show_parents(generation+1, selected+1, stop, slice/2.0)
+ self.show_parents(generation+1, selected+1, stop, portion/2.0)
else:
# shrink from left
- slice = (gstop - gstart)/2.0
- start = gstop - slice
+ portion = (gstop - gstart)/2.0
+ start = gstop - portion
self.angle[generation][selected] = [start, gstop, NORMAL]
self.shrink_parents(generation+1, selected, start)
- start, stop, state = self.angle[generation][selected-1]
- self.angle[generation][selected-1] = [start, start+slice,
+ start, stop, dummy_state = self.angle[generation][selected-1]
+ self.angle[generation][selected-1] = [start, start+portion,
NORMAL]
- self.show_parents(generation+1, selected-1, start, slice/2.0)
+ self.show_parents(generation+1, selected-1, start, portion/2.0)
def cell_address_under_cursor(self, curx, cury):
"""
@@ -1439,33 +1665,34 @@ class FanChartWidget(FanChartBaseWidget):
position x and y.
None if outside of diagram
"""
- radius, rads, raw_rads = self.cursor_to_polar(curx, cury, get_raw_rads=True)
+ radius, rads, raw_rads = self.cursor_to_polar(curx, cury,
+ get_raw_rads=True)
# find out the generation
if radius < TRANSLATE_PX:
return None
elif (self.childring and self.angle[-2] and
- radius < TRANSLATE_PX + CHILDRING_WIDTH):
+ radius < TRANSLATE_PX + CHILDRING_WIDTH):
generation = -2 # indication of one of the children
elif radius < self.CENTER:
generation = 0
else:
generation = None
for gen in range(self.generations):
- radiusin,radiusout = self.get_radiusinout_for_generation(gen)
+ radiusin, radiusout = self.get_radiusinout_for_gen(gen)
if radiusin <= radius <= radiusout:
generation = gen
break
# find what person at this angle:
selected = None
- if not (generation is None) and 0 <= generation:
+ if not (generation is None) and generation > 0:
selected = self.personpos_at_angle(generation, rads)
elif generation == -2:
- for p in range(len(self.angle[generation])):
- start, stop, state = self.angle[generation][p]
+ for idx in range(len(self.angle[generation])):
+ start, stop, dummy_state = self.angle[generation][idx]
if self.radian_in_bounds(start, raw_rads, stop):
- selected = p
+ selected = idx
break
if (generation is None or selected is None):
return None
@@ -1478,12 +1705,13 @@ class FanChartWidget(FanChartBaseWidget):
if generation == 0:
return 0
selected = None
- for p in range(len(self.angle[generation])):
- if self.data[generation][p][0]: # there is a person there
- start, stop, state = self.angle[generation][p]
- if state == COLLAPSED: continue
+ for idx in range(len(self.angle[generation])):
+ if self.data[generation][idx][0]: # there is a person there
+ start, stop, state = self.angle[generation][idx]
+ if state == COLLAPSED:
+ continue
if self.radian_in_bounds(start, rads, stop):
- selected = p
+ selected = idx
break
return selected
@@ -1520,9 +1748,22 @@ class FanChartGrampsGUI:
"""
Common part of GUI that shows Fan Chart, needs to know what to do if
one moves via Fan Ch def set_fan(self, fan):art to a new person
- on_childmenu_changed: in popup, function called on moving to a new person
+ on_childmenu_changed: in popup, function called on moving
+ to a new person
"""
self.fan = None
+ self.menu = None
+ self.twolinename = False
+ self.radialtext = None
+ self.maxgen = 8
+ self.childring = 0
+ self.showid = False
+ self.grad_start = '#0000FF'
+ self.grad_end = '#FF0000'
+ self.form = FORM_CIRCLE
+ self.alpha_filter = 0.5
+ self.filter = None
+ self.background = BACKGROUND_GRAD_GEN
self.on_childmenu_changed = on_childmenu_changed
self.format_helper = FormattingHelper(self.dbstate, self.uistate)
self.uistate.connect('font-changed', self.reload_symbols)
@@ -1545,9 +1786,10 @@ class FanChartGrampsGUI:
"""
root_person_handle = self.get_active('Person')
self.fan.set_values(root_person_handle, self.maxgen, self.background,
- self.childring, self.flipupsidedownname, self.twolinename, self.radialtext, self.fonttype,
- self.grad_start, self.grad_end,
- self.generic_filter, self.alpha_filter, self.form)
+ self.childring, self.flipupsidedownname,
+ self.twolinename, self.radialtext, self.fonttype,
+ self.grad_start, self.grad_end, self.generic_filter,
+ self.alpha_filter, self.form, self.showid)
self.fan.reset()
self.fan.draw()
self.fan.queue_draw()
@@ -1557,6 +1799,7 @@ class FanChartGrampsGUI:
Builds the full menu (including Siblings, Spouses, Children,
and Parents) with navigation.
"""
+ dummy_obj = obj
#store menu for GTK3 to avoid it being destroyed before showing
self.menu = Gtk.Menu()
menu = self.menu
@@ -1649,8 +1892,8 @@ class FanChartGrampsGUI:
pfam_list = person.get_parent_family_handle_list()
siblings = []
step_siblings = []
- for f in pfam_list:
- fam = self.dbstate.db.get_family_from_handle(f)
+ for fhdle in pfam_list:
+ fam = self.dbstate.db.get_family_from_handle(fhdle)
sib_list = fam.get_child_ref_list()
for sib_ref in sib_list:
sib_id = sib_ref.ref
@@ -1667,8 +1910,10 @@ class FanChartGrampsGUI:
if fam_id not in pfam_list]
for step_fam in other_families:
fam_stepsiblings = [sib_ref.ref
- for sib_ref in step_fam.get_child_ref_list()
- if not (sib_ref.ref == person.get_handle())]
+ for sib_ref in
+ step_fam.get_child_ref_list()
+ if not sib_ref.ref ==
+ person.get_handle()]
if fam_stepsiblings:
step_siblings.append(fam_stepsiblings)
@@ -1683,17 +1928,20 @@ class FanChartGrampsGUI:
sib = self.dbstate.db.get_person_from_handle(sib_id)
if not sib:
continue
- if find_children(self.dbstate.db,sib):
- label = Gtk.Label(label='%s' % escape(name_displayer.display(sib)))
+ if find_children(self.dbstate.db, sib):
+ thelabel = escape(name_displayer.display(sib))
+ label = Gtk.Label(label='%s' % thelabel)
else:
- label = Gtk.Label(label=escape(name_displayer.display(sib)))
+ thelabel = escape(name_displayer.display(sib))
+ label = Gtk.Label(label=thelabel)
sib_item = Gtk.MenuItem()
label.set_use_markup(True)
label.show()
- label.set_alignment(0,0)
+ label.set_alignment(0, 0)
sib_item.add(label)
linked_persons.append(sib_id)
- sib_item.connect("activate", self.on_childmenu_changed, sib_id)
+ sib_item.connect("activate", self.on_childmenu_changed,
+ sib_id)
sib_item.show()
sib_menu.append(sib_item)
if sibs.index(sib_group) < len(sibs)-1:
@@ -1720,8 +1968,9 @@ class FanChartGrampsGUI:
child_menu = item.get_submenu()
child_menu.set_reserve_toggle_size(False)
- if find_children(self.dbstate.db,child):
- label = Gtk.Label(label='%s' % escape(name_displayer.display(child)))
+ if find_children(self.dbstate.db, child):
+ thelabel = escape(name_displayer.display(child))
+ label = Gtk.Label(label='%s' % thelabel)
else:
label = Gtk.Label(label=escape(name_displayer.display(child)))
@@ -1731,7 +1980,8 @@ class FanChartGrampsGUI:
label.set_halign(Gtk.Align.START)
child_item.add(label)
linked_persons.append(child_handle)
- child_item.connect("activate", self.on_childmenu_changed, child_handle)
+ child_item.connect("activate", self.on_childmenu_changed,
+ child_handle)
child_item.show()
child_menu.append(child_item)
@@ -1746,7 +1996,7 @@ class FanChartGrampsGUI:
par_menu = item.get_submenu()
par_menu.set_reserve_toggle_size(False)
no_parents = 1
- par_list = find_parents(self.dbstate.db,person)
+ par_list = find_parents(self.dbstate.db, person)
for par_id in par_list:
if not par_id:
continue
@@ -1757,8 +2007,9 @@ class FanChartGrampsGUI:
if no_parents:
no_parents = 0
- if find_parents(self.dbstate.db,par):
- label = Gtk.Label(label='%s' % escape(name_displayer.display(par)))
+ if find_parents(self.dbstate.db, par):
+ thelabel = escape(name_displayer.display(par))
+ label = Gtk.Label(label='%s' % thelabel)
else:
label = Gtk.Label(label=escape(name_displayer.display(par)))
@@ -1785,7 +2036,7 @@ class FanChartGrampsGUI:
# Go over parents and build their menu
item = Gtk.MenuItem(label=_("Related"))
no_related = 1
- for p_id in find_witnessed_people(self.dbstate.db,person):
+ for p_id in find_witnessed_people(self.dbstate.db, person):
#if p_id in linked_persons:
# continue # skip already listed family members
@@ -1833,7 +2084,7 @@ class FanChartGrampsGUI:
add_partner_item = Gtk.MenuItem()
add_partner_item.set_label(_("Add partner to person"))
add_partner_item.connect("activate", self.add_partner_to_pers_cb,
- person_handle)
+ person_handle)
add_partner_item.show()
add_menu.append(add_partner_item)
@@ -1849,6 +2100,9 @@ class FanChartGrampsGUI:
return 1
def edit_person_cb(self, obj, person_handle):
+ """
+ Edit a person
+ """
person = self.dbstate.db.get_person_from_handle(person_handle)
if person:
try:
@@ -1859,6 +2113,9 @@ class FanChartGrampsGUI:
return False
def edit_fam_cb(self, obj, family_handle):
+ """
+ Edit a family
+ """
fam = self.dbstate.db.get_family_from_handle(family_handle)
if fam:
try:
@@ -1869,6 +2126,9 @@ class FanChartGrampsGUI:
return False
def reord_fam_cb(self, obj, person_handle):
+ """
+ reorder a family
+ """
try:
Reorder(self.dbstate, self.uistate, [], person_handle)
except WindowActiveError:
@@ -1889,6 +2149,9 @@ class FanChartGrampsGUI:
pass
def add_child_to_fam_cb(self, obj, family_handle):
+ """
+ Add a child to a family
+ """
callback = lambda x: self.callback_add_child(x, family_handle)
person = Person()
name = Name()
@@ -1897,7 +2160,7 @@ class FanChartGrampsGUI:
name.set_primary_surname(0)
family = self.dbstate.db.get_family_from_handle(family_handle)
father = self.dbstate.db.get_person_from_handle(
- family.get_father_handle())
+ family.get_father_handle())
if father:
preset_name(father, name)
person.set_primary_name(name)
@@ -1908,6 +2171,9 @@ class FanChartGrampsGUI:
pass
def callback_add_child(self, person, family_handle):
+ """
+ Add a child
+ """
ref = ChildRef()
ref.ref = person.get_handle()
family = self.dbstate.db.get_family_from_handle(family_handle)
@@ -1942,6 +2208,10 @@ class FanChartGrampsGUI:
pass
def on_add_parents(self, obj, person_handle):
+ """
+ Add a family
+ """
+ dummy_obj = obj
family = Family()
childref = ChildRef()
childref.set_reference_handle(person_handle)
@@ -1951,12 +2221,15 @@ class FanChartGrampsGUI:
except WindowActiveError:
return
- def copy_person_to_clipboard_cb(self, obj,person_handle):
- """Renders the person data into some lines of text and puts that into the clipboard"""
+ def copy_person_to_clipboard_cb(self, obj, person_handle):
+ """
+ Renders the person data into some lines of text and puts that
+ into the clipboard
+ """
person = self.dbstate.db.get_person_from_handle(person_handle)
if person:
- cb = Gtk.Clipboard.get_for_display(Gdk.Display.get_default(),
- Gdk.SELECTION_CLIPBOARD)
- cb.set_text( self.format_helper.format_person(person,11), -1)
+ cbx = Gtk.Clipboard.get_for_display(Gdk.Display.get_default(),
+ Gdk.SELECTION_CLIPBOARD)
+ cbx.set_text(self.format_helper.format_person(person, 11), -1)
return True
return False
diff --git a/gramps/gui/widgets/fanchart2way.py b/gramps/gui/widgets/fanchart2way.py
index 38e790d2d..28aca7436 100644
--- a/gramps/gui/widgets/fanchart2way.py
+++ b/gramps/gui/widgets/fanchart2way.py
@@ -34,35 +34,25 @@
# Python modules
#
#-------------------------------------------------------------------------
-from gi.repository import Pango
-from gi.repository import GObject
-from gi.repository import Gdk
-from gi.repository import Gtk
-from gi.repository import PangoCairo
-import cairo
import math
-import colorsys
-import sys
-import pickle
-from html import escape
+import cairo
#-------------------------------------------------------------------------
#
# Gramps modules
#
#-------------------------------------------------------------------------
-from gramps.gen.display.name import displayer as name_displayer
-from gramps.gen.errors import WindowActiveError
-from ..editors import EditPerson, EditFamily
from ..utils import hex_to_rgb
-from ..ddtargets import DdTargets
-from gramps.gen.utils.alive import probably_alive
-from gramps.gen.utils.libformatting import FormattingHelper
-from gramps.gen.utils.db import (find_children, find_parents, find_witnessed_people,
- get_age, get_timeperiod)
-from gramps.gen.plug.report.utils import find_spouse
-from .fanchart import *
-from .fanchartdesc import *
+from .fanchart import (FanChartWidget, PIXELS_PER_GENERATION, BORDER_EDGE_WIDTH)
+from .fanchartdesc import (FanChartBaseWidget,
+ FanChartDescWidget,
+ FanChartGrampsGUI,
+ NORMAL, EXPANDED, COLLAPSED,
+ TRANSLATE_PX, CHILDRING_WIDTH,
+ BACKGROUND_GRAD_GEN,
+ BACKGROUND_GRAD_AGE,
+ BACKGROUND_GRAD_PERIOD,
+ FORM_CIRCLE, TYPE_BOX_NORMAL, TYPE_BOX_FAMILY)
#-------------------------------------------------------------------------
#
@@ -70,12 +60,14 @@ from .fanchartdesc import *
#
#-------------------------------------------------------------------------
-PIXELS_PER_GENPERSON_RATIO = 0.55 # ratio of generation radius for person (rest for partner)
+PIXELS_PER_GENPERSON_RATIO = 0.55 # ratio of generation radius for person
+ # (rest for partner)
PIXELS_PER_GEN_SMALL = 80
PIXELS_PER_GEN_LARGE = 160
N_GEN_SMALL = 4
PIXELS_PER_GENFAMILY = 25 # size of radius for family
-PIXELS_PER_RECLAIM = 4 # size of the radius of pixels taken from family to reclaim space
+PIXELS_PER_RECLAIM = 4 # size of the radius of pixels taken from family
+ # to reclaim space
PIXELS_PARTNER_GAP = 0 # Padding between someone and his partner
PIXELS_CHILDREN_GAP = 5 # Padding between generations
PARENTRING_WIDTH = 12 # width of the parent ring inside the person
@@ -103,8 +95,14 @@ class FanChart2WayWidget(FanChartWidget, FanChartDescWidget):
Fan Chart Widget. Handles visualization of data in self.data.
See main() of FanChartGramplet for example of model format.
"""
- self.set_values(None, 6, 5, True, True, BACKGROUND_GRAD_GEN, True, 'Sans', '#0000FF',
- '#FF0000', None, 0.5, ANGLE_WEIGHT, '#888a85')
+ self.gen2people = {}
+ self.gen2fam = {}
+ self.rootangle_rad_desc = [math.radians(275), math.radians(275 + 170)]
+ self.rootangle_rad_asc = [math.radians(90), math.radians(270)]
+ self.data = {}
+ self.set_values(None, 6, 5, True, True, BACKGROUND_GRAD_GEN, True,
+ 'Sans', '#0000FF', '#FF0000', None, 0.5, ANGLE_WEIGHT,
+ '#888a85', False)
FanChartBaseWidget.__init__(self, dbstate, uistate, callback_popup)
def reset(self):
@@ -118,30 +116,35 @@ class FanChart2WayWidget(FanChartWidget, FanChartDescWidget):
self._fill_data_structures()
# prepare the colors for the boxes
- self.prepare_background_box(self.generations_asc + self.generations_desc - 1)
+ self.prepare_background_box(self.generations_asc +
+ self.generations_desc - 1)
- def set_values(self, root_person_handle, maxgen_asc, maxgen_desc, flipupsidedownname, twolinename, background,
- background_gradient, fontdescr, grad_start, grad_end,
- filter, alpha_filter, angle_algo, dupcolor):
+ def set_values(self, root_person_handle, maxgen_asc, maxgen_desc,
+ flipupsidedownname, twolinename, background,
+ background_gradient, fontdescr, grad_start, grad_end,
+ filtr, alpha_filter, angle_algo, dupcolor, showid):
"""
Reset the values to be used:
:param root_person_handle: person to show
:param maxgen_asc: maximum of ascendant generations to show
:param maxgen_desc: maximum of descendant generations to show
- :param flipupsidedownname: flip name on the left of the fanchart for the display of person's name
+ :param flipupsidedownname: flip name on the left of the fanchart
+ for the display of person's name
:param background: config setting of which background procedure to use
:type background: int
- :param background_gradient: option to add an overall gradient for distinguishing Asc/Desc
+ :param background_gradient: option to add an overall gradient
+ for distinguishing Asc/Desc
:param fontdescr: string describing the font to use
:param grad_start: colors to use for background procedure
:param grad_end: colors to use for background procedure
- :param filter: the person filter to apply to the people in the chart
+ :param filtr: the person filter to apply to the people in the chart
:param alpha_filter: the alpha transparency value (0-1) to apply to
filtered out data
:param angle_algo: alorithm to use to calculate the sizes of the boxes
:param dupcolor: color to use for people or families that occur a second
or more time
+ :param showid: option to show the gramps id or not
"""
self.rootpersonh = root_person_handle
self.generations_asc = maxgen_asc
@@ -151,7 +154,7 @@ class FanChart2WayWidget(FanChartWidget, FanChartDescWidget):
self.fontdescr = fontdescr
self.grad_start = grad_start
self.grad_end = grad_end
- self.filter = filter
+ self.filter = filtr
self.form = FORM_CIRCLE
self.alpha_filter = alpha_filter
self.anglealgo = angle_algo
@@ -159,6 +162,7 @@ class FanChart2WayWidget(FanChartWidget, FanChartDescWidget):
self.childring = False
self.flipupsidedownname = flipupsidedownname
self.twolinename = twolinename
+ self.showid = showid
def set_generations(self):
"""
@@ -172,12 +176,14 @@ class FanChart2WayWidget(FanChartWidget, FanChartDescWidget):
self.handle2fam = {}
self.gen2people = {}
self.gen2fam = {}
- self.gen2people[0] = [(None, False, 0, 2 * math.pi, 0, 0, [], NORMAL)] # no center person
+ # no center person
+ self.gen2people[0] = [(None, False, 0, 2 * math.pi, 0, 0, [], NORMAL)]
self.gen2fam[0] = [] # no families
for i in range(1, self.generations_desc):
self.gen2fam[i] = []
self.gen2people[i] = []
- self.gen2people[self.generations_desc] = [] # indication of more children
+ # indication of more children
+ self.gen2people[self.generations_desc] = []
# Ascendance part
self.angle = {}
@@ -187,13 +193,17 @@ class FanChart2WayWidget(FanChartWidget, FanChartDescWidget):
self.data[i] = [(None,) * 4] * 2 ** i
self.angle[i] = []
angle = self.rootangle_rad_asc[0]
- slice = 1 / (2 ** i) * (self.rootangle_rad_asc[1] - self.rootangle_rad_asc[0])
- for count in range(len(self.data[i])):
+ portion = 1 / (2 ** i) * (self.rootangle_rad_asc[1] -
+ self.rootangle_rad_asc[0])
+ for dummy_count in range(len(self.data[i])):
# start, stop, state
- self.angle[i].append([angle, angle + slice, NORMAL])
- angle += slice
+ self.angle[i].append([angle, angle + portion, NORMAL])
+ angle += portion
def _fill_data_structures(self):
+ """
+ Initialize the data structures
+ """
self.set_generations()
if not self.rootpersonh:
return
@@ -221,9 +231,10 @@ class FanChart2WayWidget(FanChartWidget, FanChartDescWidget):
for current in range(1, self.generations_asc):
parent = 0
# name, person, parents, children
- for (p, q, c, d) in self.data[current - 1]:
+ for (pers, dummy_q, dummy_c, dummy_d) in self.data[current - 1]:
# Get father's and mother's details:
- for person in [self._get_parent(p, True), self._get_parent(p, False)]:
+ for person in [self._get_parent(pers, True),
+ self._get_parent(pers, False)]:
if current == self.generations_asc - 1:
parents = self._have_parents(person)
else:
@@ -235,17 +246,22 @@ class FanChart2WayWidget(FanChartWidget, FanChartDescWidget):
parent += 1
def nrgen_desc(self):
- # compute the number of generations present
+ """
+ compute the number of generations present
+ """
for gen in range(self.generations_desc - 1, 0, -1):
- if len(self.gen2people[gen]) > 0:
+ if self.gen2people[gen]:
return gen + 1
return 1
def nrgen_asc(self):
- # compute the number of generations present
+ """
+ compute the number of generations present
+ """
for generation in range(self.generations_asc - 1, 0, -1):
- for p in range(len(self.data[generation])):
- (person, parents, child, userdata) = self.data[generation][p]
+ for idx in range(len(self.data[generation])):
+ (person, dummy_parents, dummy_child,
+ dummy_userdata) = self.data[generation][idx]
if person:
return generation
return 1
@@ -254,59 +270,73 @@ class FanChart2WayWidget(FanChartWidget, FanChartDescWidget):
"""
Compute the current half radius of the ascendant circle
"""
- radiusin, radius_asc = self.get_radiusinout_for_generation_asc(generation)
+ (dummy_radiusin,
+ radius_asc) = self.get_radiusinout_for_gen_asc(generation)
return radius_asc + BORDER_EDGE_WIDTH
- def maxradius_desc(self,generation):
+ def maxradius_desc(self, generation):
"""
Compute the current radius of the descendant circle
"""
- radiusin_pers, radiusout_pers, radiusin_partner, radius_desc = self.get_radiusinout_for_generation_pair(generation-1)
+ (dummy_radiusin_pers, dummy_radiusout_pers, dummy_radiusin_partner,
+ radius_desc) = self.get_radiusinout_for_gen_pair(generation-1)
return radius_desc + BORDER_EDGE_WIDTH
def halfdist(self):
"""
Compute the current max half radius of the circle
"""
- return max(self.maxradius_desc(self.nrgen_desc()), self.maxradius_asc(self.nrgen_asc()))
+ return max(self.maxradius_desc(self.nrgen_desc()),
+ self.maxradius_asc(self.nrgen_asc()))
- def get_radiusinout_for_generation_desc(self, generation):
+ def get_radiusinout_for_gen_desc(self, generation):
"""
- Get the in and out radius for descendant generation (starting with center pers = 0)
+ Get the in and out radius for descendant generation
+ (starting with center pers = 0)
"""
- radius_first_gen = self.CENTER - (1 - PIXELS_PER_GENPERSON_RATIO) * PIXELS_PER_GEN_SMALL
+ radius_first_gen = (self.CENTER -
+ (1 - PIXELS_PER_GENPERSON_RATIO) *
+ PIXELS_PER_GEN_SMALL)
if generation < N_GEN_SMALL:
radius_start = PIXELS_PER_GEN_SMALL * generation + radius_first_gen
return (radius_start, radius_start + PIXELS_PER_GEN_SMALL)
else:
- radius_start = PIXELS_PER_GEN_SMALL * N_GEN_SMALL + PIXELS_PER_GEN_LARGE \
- * (generation - N_GEN_SMALL) + radius_first_gen
+ radius_start = (PIXELS_PER_GEN_SMALL * N_GEN_SMALL +
+ PIXELS_PER_GEN_LARGE * (generation - N_GEN_SMALL) +
+ radius_first_gen)
return (radius_start, radius_start + PIXELS_PER_GEN_LARGE)
- def get_radiusinout_for_generation_asc(self, generation):
+ def get_radiusinout_for_gen_asc(self, generation):
"""
- Get the in and out radius for ascendant generation (starting with center pers = 0)
+ Get the in and out radius for ascendant generation
+ (starting with center pers = 0)
"""
- radiusin, radius_first_gen = self.get_radiusinout_for_generation_desc(0)
+ dummy_radiusin, radius_first_gen = self.get_radiusinout_for_gen_desc(0)
outerradius = generation * PIXELS_PER_GENERATION + radius_first_gen
- innerradius = (generation - 1) * PIXELS_PER_GENERATION + radius_first_gen
+ innerradius = ((generation - 1) * PIXELS_PER_GENERATION +
+ radius_first_gen)
if generation == 0:
innerradius = CHILDRING_WIDTH + TRANSLATE_PX
return (innerradius, outerradius)
- def get_radiusinout_for_generation_pair(self, generation):
+ def get_radiusinout_for_gen_pair(self, generation):
"""
- Get the in and out radius for descendant generation pair (starting with center pers = 0)
- :return: (radiusin_pers, radiusout_pers, radiusin_partner, radiusout_partner)
+ Get the in and out radius for descendant generation pair
+ (starting with center pers = 0)
+ :return: (radiusin_pers, radiusout_pers,
+ radiusin_partner, radiusout_partner)
"""
- radiusin, radiusout = self.get_radiusinout_for_generation_desc(generation)
- radius_spread = radiusout - radiusin - PIXELS_CHILDREN_GAP - PIXELS_PARTNER_GAP
+ radiusin, radiusout = self.get_radiusinout_for_gen_desc(generation)
+ radius_spread = (radiusout - radiusin -
+ PIXELS_CHILDREN_GAP - PIXELS_PARTNER_GAP)
radiusin_pers = radiusin + PIXELS_CHILDREN_GAP
- radiusout_pers = radiusin_pers + PIXELS_PER_GENPERSON_RATIO * radius_spread
+ radiusout_pers = (radiusin_pers +
+ PIXELS_PER_GENPERSON_RATIO * radius_spread)
radiusin_partner = radiusout_pers + PIXELS_PARTNER_GAP
radiusout_partner = radiusout
- return (radiusin_pers, radiusout_pers, radiusin_partner, radiusout_partner)
+ return (radiusin_pers, radiusout_pers,
+ radiusin_partner, radiusout_partner)
def people_generator(self):
"""
@@ -319,8 +349,9 @@ class FanChart2WayWidget(FanChartWidget, FanChartDescWidget):
for data in self.gen2fam[generation]:
yield (data[7], data[6])
for generation in range(self.generations_asc):
- for p in range(len(self.data[generation])):
- (person, parents, child, userdata) = self.data[generation][p]
+ for idx in range(len(self.data[generation])):
+ (person, dummy_parents, dummy_child,
+ userdata) = self.data[generation][idx]
yield (person, userdata)
def innerpeople_generator(self):
@@ -330,47 +361,57 @@ class FanChart2WayWidget(FanChartWidget, FanChartDescWidget):
if False:
yield
- def draw_background(self, cr):
- cr.save()
+ def draw_background(self, ctx):
+ """
+ Draw the background
+ """
+ ctx.save()
- cr.rotate(math.radians(self.rotate_value))
- delta = (self.rootangle_rad_asc[0] - self.rootangle_rad_desc[1]) / 2.0 % math.pi
+ ctx.rotate(math.radians(self.rotate_value))
+ delta = (self.rootangle_rad_asc[0] -
+ self.rootangle_rad_desc[1]) / 2.0 % math.pi
- cr.move_to(0, 0)
+ ctx.move_to(0, 0)
radius_gradient_asc = 1.5 * self.maxradius_asc(self.generations_asc)
- gradient_asc = cairo.RadialGradient(0, 0, self.CENTER, 0, 0, radius_gradient_asc)
+ gradient_asc = cairo.RadialGradient(0, 0, self.CENTER,
+ 0, 0, radius_gradient_asc)
color = hex_to_rgb(self.grad_end)
- gradient_asc.add_color_stop_rgba(0.0, color[0]/255, color[1]/255, color[2]/255, 0.5)
+ gradient_asc.add_color_stop_rgba(0.0, color[0] / 255, color[1] / 255,
+ color[2] / 255, 0.5)
gradient_asc.add_color_stop_rgba(1.0, 1, 1, 1, 0.0)
- start_rad, stop_rad = self.rootangle_rad_asc[0] - delta, self.rootangle_rad_asc[1] + delta
- cr.set_source(gradient_asc)
- cr.arc(0, 0, radius_gradient_asc, start_rad, stop_rad)
- cr.fill()
+ start_rad, stop_rad = (self.rootangle_rad_asc[0] - delta,
+ self.rootangle_rad_asc[1] + delta)
+ ctx.set_source(gradient_asc)
+ ctx.arc(0, 0, radius_gradient_asc, start_rad, stop_rad)
+ ctx.fill()
- cr.move_to(0, 0)
+ ctx.move_to(0, 0)
radius_gradient_desc = 1.5 * self.maxradius_desc(self.generations_desc)
- gradient_desc = cairo.RadialGradient(0, 0, self.CENTER, 0, 0, radius_gradient_desc)
+ gradient_desc = cairo.RadialGradient(0, 0, self.CENTER,
+ 0, 0, radius_gradient_desc)
color = hex_to_rgb(self.grad_start)
- gradient_desc.add_color_stop_rgba(0.0, color[0]/255, color[1]/255, color[2]/255, 0.5)
+ gradient_desc.add_color_stop_rgba(0.0, color[0] / 255, color[1] / 255,
+ color[2] / 255, 0.5)
gradient_desc.add_color_stop_rgba(1.0, 1, 1, 1, 0.0)
- start_rad, stop_rad = self.rootangle_rad_desc[0] - delta, self.rootangle_rad_desc[1] + delta
- cr.set_source(gradient_desc)
- cr.arc(0, 0, radius_gradient_desc, start_rad, stop_rad)
- cr.fill()
- cr.restore()
+ start_rad, stop_rad = (self.rootangle_rad_desc[0] - delta,
+ self.rootangle_rad_desc[1] + delta)
+ ctx.set_source(gradient_desc)
+ ctx.arc(0, 0, radius_gradient_desc, start_rad, stop_rad)
+ ctx.fill()
+ ctx.restore()
- def draw(self, cr=None, scale=1.0):
+ def draw(self, ctx=None, scale=1.0):
"""
The main method to do the drawing.
- If cr is given, we assume we draw draw raw on the cairo context cr
- To draw in GTK3 and use the allocation, set cr=None.
+ If ctx is given, we assume we draw draw raw on the cairo context ctx
+ To draw in GTK3 and use the allocation, set ctx=None.
Note: when drawing for display, to counter a Gtk issue with scrolling
or resizing the drawing window, we draw on a surface, then copy to the
drawing context when the Gtk 'draw' signal arrives.
"""
# first do size request of what we will need
halfdist = self.halfdist()
- if not cr: # Display
+ if not ctx: # Display
size_w = size_h = 2 * halfdist
size_w_a = self.get_allocated_width()
@@ -380,81 +421,101 @@ class FanChart2WayWidget(FanChartWidget, FanChartDescWidget):
size_h = self.get_allocated_height()
self.surface = cairo.ImageSurface(cairo.FORMAT_ARGB32,
size_w, size_h)
- cr = cairo.Context(self.surface)
+ ctx = cairo.Context(self.surface)
self.center_xy = self.center_xy_from_delta()
- cr.translate(*self.center_xy)
+ ctx.translate(*self.center_xy)
else: # printing
self.center_xy = halfdist, halfdist
- cr.scale(scale, scale)
- cr.translate(halfdist, halfdist)
+ ctx.scale(scale, scale)
+ ctx.translate(halfdist, halfdist)
- cr.save()
+ ctx.save()
# Draw background
if self.background_gradient:
- self.draw_background(cr)
+ self.draw_background(ctx)
# Draw center person:
- (person, dup, start, slice, parentfampos, nrfam, userdata, status) \
- = self.gen2people[0][0]
+ (person, dup, start, portion, dummy_parentfampos, dummy_nrfam,
+ userdata, status) = self.gen2people[0][0]
if not person:
return
gen_remapped = self.generations_desc - 1 # remapped generation
- if gen_remapped == 0: gen_remapped = (self.generations_desc + self.generations_asc - 1) # remapped generation
+ if gen_remapped == 0:
+ # remapped generation
+ gen_remapped = (self.generations_desc + self.generations_asc - 1)
radiusin_pers, radiusout_pers, radiusin_partner, radiusout_partner = \
- self.get_radiusinout_for_generation_pair(0)
+ self.get_radiusinout_for_gen_pair(0)
radiusin = TRANSLATE_PX
radiusout = radiusout_pers
- self.draw_person(cr, person, radiusin, radiusout, math.pi / 2, math.pi / 2 + 2 * math.pi,
- gen_remapped, False, userdata, is_central_person=True)
+ self.draw_person(ctx, person, radiusin, radiusout,
+ math.pi / 2, math.pi / 2 + 2 * math.pi, gen_remapped,
+ False, userdata, is_central_person=True)
# draw center to move chart
- cr.set_source_rgb(0, 0, 0) # black
- cr.move_to(TRANSLATE_PX, 0)
- cr.arc(0, 0, TRANSLATE_PX, 0, 2 * math.pi)
- cr.fill()
+ ctx.set_source_rgb(0, 0, 0) # black
+ ctx.move_to(TRANSLATE_PX, 0)
+ ctx.arc(0, 0, TRANSLATE_PX, 0, 2 * math.pi)
+ ctx.fill()
- cr.rotate(math.radians(self.rotate_value))
+ ctx.rotate(math.radians(self.rotate_value))
# Ascendance
for generation in range(self.generations_asc - 1, 0, -1):
- for p in range(len(self.data[generation])):
- (person, parents, child, userdata) = self.data[generation][p]
+ for idx in range(len(self.data[generation])):
+ (person, parents, dummy_child,
+ userdata) = self.data[generation][idx]
if person:
- start, stop, state = self.angle[generation][p]
+ start, stop, state = self.angle[generation][idx]
if state in [NORMAL, EXPANDED]:
- radiusin, radiusout = self.get_radiusinout_for_generation_asc(generation)
+ fct = self.get_radiusinout_for_gen_asc
+ radiusin, radiusout = fct(generation)
dup = False
- gen_remapped = generation + self.generations_desc - 1 # remapped generation
- self.draw_person(cr, person, radiusin, radiusout, start, stop,
- gen_remapped, dup, userdata, thick=(state == EXPANDED),
- has_moregen_indicator=(generation == self.generations_asc - 1 and parents))
+ # remapped generation
+ gen_remapped = generation + self.generations_desc - 1
+ indicator = (generation == self.generations_asc - 1
+ and parents)
+ self.draw_person(ctx, person, radiusin, radiusout,
+ start, stop, gen_remapped, dup,
+ userdata, thick=(state == EXPANDED),
+ has_moregen_indicator=indicator)
# Descendance
for gen in range(self.generations_desc):
- radiusin_pers, radiusout_pers, radiusin_partner, radiusout_partner = \
- self.get_radiusinout_for_generation_pair(gen)
+ (radiusin_pers, radiusout_pers, radiusin_partner,
+ radiusout_partner) = self.get_radiusinout_for_gen_pair(gen)
gen_remapped = (self.generations_desc - gen - 1)
- if gen_remapped == 0: gen_remapped = (self.generations_desc + self.generations_asc - 1) # remapped generation
+ if gen_remapped == 0:
+ # remapped generation
+ gen_remapped = (self.generations_desc +
+ self.generations_asc - 1)
if gen > 0:
for pdata in self.gen2people[gen]:
# person, duplicate or not, start angle, slice size,
# parent pos in fam, nrfam, userdata, status
- pers, dup, start, slice, pospar, nrfam, userdata, status = pdata
+ (pers, dup, start, portion, dummy_pospar, dummy_nrfam,
+ userdata, status) = pdata
if status != COLLAPSED:
- self.draw_person(cr, pers, radiusin_pers, radiusout_pers,
- start, start + slice, gen_remapped, dup, userdata,
+ self.draw_person(ctx, pers, radiusin_pers,
+ radiusout_pers,
+ start, start + portion,
+ gen_remapped, dup, userdata,
thick=status != NORMAL)
#if gen < self.generations_desc - 1:
for famdata in self.gen2fam[gen]:
# family, duplicate or not, start angle, slice size,
# spouse pos in gen, nrchildren, userdata, status
- fam, dup, start, slice, posfam, nrchild, userdata, partner, status = famdata
+ (fam, dup, start, portion, dummy_posfam, dummy_nrchild,
+ userdata, partner, status) = famdata
if status != COLLAPSED:
more_pers_flag = (gen == self.generations_desc - 1
- and len(fam.get_child_ref_list()) > 0)
- self.draw_person(cr, partner, radiusin_partner, radiusout_partner, start, start + slice,
- gen_remapped, dup, userdata, thick=(status != NORMAL), has_moregen_indicator=more_pers_flag)
- cr.restore()
+ and fam.get_child_ref_list())
+ self.draw_person(ctx, partner,
+ radiusin_partner, radiusout_partner,
+ start, start + portion,
+ gen_remapped, dup, userdata,
+ thick=(status != NORMAL),
+ has_moregen_indicator=more_pers_flag)
+ ctx.restore()
if self.background in [BACKGROUND_GRAD_AGE, BACKGROUND_GRAD_PERIOD]:
- self.draw_gradient_legend(cr, halfdist)
+ self.draw_gradient_legend(ctx, halfdist)
def cell_address_under_cursor(self, curx, cury):
"""
@@ -462,19 +523,23 @@ class FanChart2WayWidget(FanChartWidget, FanChartDescWidget):
position x and y.
None if outside of diagram
"""
- radius, rads, raw_rads = self.cursor_to_polar(curx, cury, get_raw_rads=True)
+ radius, rads, dummy_raw_rads = self.cursor_to_polar(curx, cury,
+ get_raw_rads=True)
if radius < TRANSLATE_PX:
return None
- radius_parents = self.get_radiusinout_for_generation_asc(0)[1]
- if (radius < radius_parents) or \
- (self.radian_in_bounds(self.rootangle_rad_desc[0], rads, self.rootangle_rad_desc[1])):
+ radius_parents = self.get_radiusinout_for_gen_asc(0)[1]
+ if ((radius < radius_parents) or
+ self.radian_in_bounds(self.rootangle_rad_desc[0], rads,
+ self.rootangle_rad_desc[1])):
cell_address = self.cell_address_under_cursor_desc(rads, radius)
if cell_address is not None:
return (TYPE_DESCENDANCE,) + cell_address
- elif self.radian_in_bounds(self.rootangle_rad_asc[0], rads, self.rootangle_rad_asc[1]):
+ elif self.radian_in_bounds(self.rootangle_rad_asc[0], rads,
+ self.rootangle_rad_asc[1]):
cell_address = self.cell_address_under_cursor_asc(rads, radius)
- if cell_address and cell_address[0]==0: return None # There is a gap before first parents
+ if cell_address and cell_address[0] == 0:
+ return None # There is a gap before first parents
if cell_address is not None:
return (TYPE_ASCENDANCE,) + cell_address
@@ -488,8 +553,8 @@ class FanChart2WayWidget(FanChartWidget, FanChartDescWidget):
"""
generation, selected, btype = None, None, TYPE_BOX_NORMAL
for gen in range(self.generations_desc):
- radiusin_pers, radiusout_pers, radiusin_partner, radiusout_partner \
- = self.get_radiusinout_for_generation_pair(gen)
+ (radiusin_pers, radiusout_pers, radiusin_partner,
+ radiusout_partner) = self.get_radiusinout_for_gen_pair(gen)
if radiusin_pers <= radius <= radiusout_pers:
generation, btype = gen, TYPE_BOX_NORMAL
break
@@ -497,8 +562,9 @@ class FanChart2WayWidget(FanChartWidget, FanChartDescWidget):
generation, btype = gen, TYPE_BOX_FAMILY
break
# find what person is in this position:
- if not (generation is None) and 0 <= generation:
- selected = FanChartDescWidget.personpos_at_angle(self, generation, rads, btype)
+ if not (generation is None) and generation > 0:
+ selected = FanChartDescWidget.personpos_at_angle(self, generation,
+ rads, btype)
if (generation is None or selected is None):
return None
@@ -514,13 +580,13 @@ class FanChart2WayWidget(FanChartWidget, FanChartDescWidget):
generation, selected = None, None
for gen in range(self.generations_asc):
- radiusin, radiusout = self.get_radiusinout_for_generation_asc(gen)
+ radiusin, radiusout = self.get_radiusinout_for_gen_asc(gen)
if radiusin <= radius <= radiusout:
generation = gen
break
# find what person is in this position:
- if not (generation is None) and 0 <= generation:
+ if not (generation is None) and generation > 0:
selected = FanChartWidget.personpos_at_angle(self, generation, rads)
if (generation is None or selected is None):
return None
@@ -556,35 +622,40 @@ class FanChart2WayWidget(FanChartWidget, FanChartDescWidget):
self.queue_draw()
def expand_parents(self, generation, selected, current):
- if generation >= self.generations_asc: return
+ if generation >= self.generations_asc:
+ return
selected = 2 * selected
start, stop, state = self.angle[generation][selected]
if state in [NORMAL, EXPANDED]:
- slice = (stop - start) * 2.0
- self.angle[generation][selected] = [current, current + slice, state]
+ portion = (stop - start) * 2.0
+ self.angle[generation][selected] = [current, current + portion,
+ state]
self.expand_parents(generation + 1, selected, current)
- current += slice
+ current += portion
start, stop, state = self.angle[generation][selected + 1]
if state in [NORMAL, EXPANDED]:
- slice = (stop - start) * 2.0
- self.angle[generation][selected + 1] = [current, current + slice,
- state]
+ portion = (stop - start) * 2.0
+ self.angle[generation][selected + 1] = [current, current + portion,
+ state]
self.expand_parents(generation + 1, selected + 1, current)
- def show_parents(self, generation, selected, angle, slice):
- if generation >= self.generations_asc: return
+ def show_parents(self, generation, selected, angle, portion):
+ if generation >= self.generations_asc:
+ return
selected *= 2
self.angle[generation][selected][0] = angle
- self.angle[generation][selected][1] = angle + slice
+ self.angle[generation][selected][1] = angle + portion
self.angle[generation][selected][2] = NORMAL
- self.show_parents(generation + 1, selected, angle, slice / 2.0)
- self.angle[generation][selected + 1][0] = angle + slice
- self.angle[generation][selected + 1][1] = angle + slice + slice
+ self.show_parents(generation + 1, selected, angle, portion / 2.0)
+ self.angle[generation][selected + 1][0] = angle + portion
+ self.angle[generation][selected + 1][1] = angle + portion + portion
self.angle[generation][selected + 1][2] = NORMAL
- self.show_parents(generation + 1, selected + 1, angle + slice, slice / 2.0)
+ self.show_parents(generation + 1, selected + 1,
+ angle + portion, portion / 2.0)
def hide_parents(self, generation, selected, angle):
- if generation >= self.generations_asc: return
+ if generation >= self.generations_asc:
+ return
selected = 2 * selected
self.angle[generation][selected][0] = angle
self.angle[generation][selected][1] = angle
@@ -596,20 +667,21 @@ class FanChart2WayWidget(FanChartWidget, FanChartDescWidget):
self.hide_parents(generation + 1, selected + 1, angle)
def shrink_parents(self, generation, selected, current):
- if generation >= self.generations_asc: return
+ if generation >= self.generations_asc:
+ return
selected = 2 * selected
start, stop, state = self.angle[generation][selected]
if state in [NORMAL, EXPANDED]:
- slice = (stop - start) / 2.0
- self.angle[generation][selected] = [current, current + slice,
+ portion = (stop - start) / 2.0
+ self.angle[generation][selected] = [current, current + portion,
state]
self.shrink_parents(generation + 1, selected, current)
- current += slice
+ current += portion
start, stop, state = self.angle[generation][selected + 1]
if state in [NORMAL, EXPANDED]:
- slice = (stop - start) / 2.0
- self.angle[generation][selected + 1] = [current, current + slice,
- state]
+ portion = (stop - start) / 2.0
+ self.angle[generation][selected + 1] = [current, current + portion,
+ state]
self.shrink_parents(generation + 1, selected + 1, current)
def toggle_cell_state(self, cell_address):
@@ -630,10 +702,13 @@ class FanChart2WayGrampsGUI(FanChartGrampsGUI):
data.
"""
root_person_handle = self.get_active('Person')
- self.fan.set_values(root_person_handle, self.generations_asc, self.generations_desc, self.flipupsidedownname, self.twolinename, self.background,
- self.background_gradient, self.fonttype, self.grad_start, self.grad_end,
- self.generic_filter, self.alpha_filter,
- self.angle_algo, self.dupcolor)
+ self.fan.set_values(root_person_handle, self.generations_asc,
+ self.generations_desc, self.flipupsidedownname,
+ self.twolinename, self.background,
+ self.background_gradient, self.fonttype,
+ self.grad_start, self.grad_end, self.generic_filter,
+ self.alpha_filter, self.angle_algo, self.dupcolor,
+ self.showid)
self.fan.reset()
self.fan.draw()
self.fan.queue_draw()
diff --git a/gramps/gui/widgets/fanchartdesc.py b/gramps/gui/widgets/fanchartdesc.py
index 81ddbe355..1988d0ba8 100644
--- a/gramps/gui/widgets/fanchartdesc.py
+++ b/gramps/gui/widgets/fanchartdesc.py
@@ -33,50 +33,40 @@
# Python modules
#
#-------------------------------------------------------------------------
-from gi.repository import Pango
-from gi.repository import GObject
-from gi.repository import Gdk
-from gi.repository import Gtk
-from gi.repository import PangoCairo
-import cairo
import math
-import colorsys
-import pickle
-from html import escape
+import cairo
#-------------------------------------------------------------------------
#
# Gramps modules
#
#-------------------------------------------------------------------------
-from gramps.gen.display.name import displayer as name_displayer
-from gramps.gen.errors import WindowActiveError
-from ..editors import EditPerson, EditFamily
-from ..utils import hex_to_rgb
-from ..ddtargets import DdTargets
-from gramps.gen.utils.alive import probably_alive
-from gramps.gen.utils.libformatting import FormattingHelper
-from gramps.gen.utils.db import (find_children, find_parents, find_witnessed_people,
- get_age, get_timeperiod)
from gramps.gen.plug.report.utils import find_spouse
-from .fanchart import *
+from ..utils import hex_to_rgb
+from .fanchart import (FanChartBaseWidget, FanChartGrampsGUI,
+ PAD_PX, TRANSLATE_PX,
+ FORM_CIRCLE, FORM_HALFCIRCLE, FORM_QUADRANT,
+ NORMAL, EXPANDED, COLLAPSED,
+ BACKGROUND_GRAD_GEN, BACKGROUND_GRAD_AGE,
+ BACKGROUND_GRAD_PERIOD, CHILDRING_WIDTH)
#-------------------------------------------------------------------------
#
# Constants
#
#-------------------------------------------------------------------------
-pi = math.pi
-PIXELS_PER_GENPERSON_RATIO = 0.55 # ratio of generation radius for person (rest for partner)
+PIXELS_PER_GENPERSON_RATIO = 0.55 # ratio of generation radius for person
+ # (rest for partner)
PIXELS_PER_GEN_SMALL = 80
PIXELS_PER_GEN_LARGE = 160
N_GEN_SMALL = 4
PIXELS_PER_GENFAMILY = 25 # size of radius for family
-PIXELS_PER_RECLAIM = 4 # size of the radius of pixels taken from family to reclaim space
+PIXELS_PER_RECLAIM = 4 # size of the radius of pixels taken from family
+ # to reclaim space
PIXELS_PARTNER_GAP = 0 # Padding between someone and his partner
PIXELS_CHILDREN_GAP = 5 # Padding between generations
-PARENTRING_WIDTH = 12 # width of the parent ring inside the person
+PARENTRING_WIDTH = 12 # width of the parent ring inside the person
ANGLE_CHEQUI = 0 #Algorithm with homogeneous children distribution
ANGLE_WEIGHT = 1 #Algorithm for angle computation based on nr of descendants
@@ -94,38 +84,49 @@ class FanChartDescWidget(FanChartBaseWidget):
"""
Interactive Fan Chart Widget.
"""
- CENTER = 60 # we require a larger center as CENTER includes the 1st partner
+ CENTER = 60 # we require a larger center as CENTER includes the 1st partner
def __init__(self, dbstate, uistate, callback_popup=None):
"""
Fan Chart Widget. Handles visualization of data in self.data.
See main() of FanChartGramplet for example of model format.
"""
- self.set_values(None, 9, True, True, BACKGROUND_GRAD_GEN, 'Sans', '#0000FF',
- '#FF0000', None, 0.5, FORM_CIRCLE, ANGLE_WEIGHT, '#888a85')
+ self.gen2people = {}
+ self.gen2fam = {}
+ self.rootangle_rad = []
+ self.handle2desc = {}
+ self.famhandle2desc = {}
+ self.handle2fam = {}
+ self.innerring = []
+ self.angle = {}
+ self.set_values(None, 9, True, True, BACKGROUND_GRAD_GEN, 'Sans',
+ '#0000FF', '#FF0000', None, 0.5,
+ FORM_CIRCLE, ANGLE_WEIGHT, '#888a85', False)
FanChartBaseWidget.__init__(self, dbstate, uistate, callback_popup)
- def set_values(self, root_person_handle, maxgen, flipupsidedownname, twolinename, background,
- fontdescr, grad_start, grad_end,
- filter, alpha_filter, form, angle_algo, dupcolor):
+ def set_values(self, root_person_handle, maxgen, flipupsidedownname,
+ twolinename, background, fontdescr, grad_start, grad_end,
+ filtr, alpha_filter, form, angle_algo, dupcolor, showid):
"""
Reset the values to be used:
:param root_person_handle: person to show
:param maxgen: maximum generations to show
- :param flipupsidedownname: flip name on the left of the fanchart for the display of person's name
+ :param flipupsidedownname: flip name on the left of the fanchart
+ for the display of person's name
:param background: config setting of which background procedure to use
:type background: int
:param fontdescr: string describing the font to use
:param grad_start: colors to use for background procedure
:param grad_end: colors to use for background procedure
- :param filter: the person filter to apply to the people in the chart
+ :param filtr: the person filter to apply to the people in the chart
:param alpha_filter: the alpha transparency value (0-1) to apply to
filtered out data
:param form: the ``FORM_`` constant for the fanchart
:param angle_algo: alorithm to use to calculate the sizes of the boxes
:param dupcolor: color to use for people or families that occur a second
or more time
+ :param showid: to show the gramps_id or not
"""
self.rootpersonh = root_person_handle
self.generations = maxgen
@@ -133,7 +134,7 @@ class FanChartDescWidget(FanChartBaseWidget):
self.fontdescr = fontdescr
self.grad_start = grad_start
self.grad_end = grad_end
- self.filter = filter
+ self.filter = filtr
self.alpha_filter = alpha_filter
self.form = form
self.anglealgo = angle_algo
@@ -141,6 +142,7 @@ class FanChartDescWidget(FanChartBaseWidget):
self.childring = False
self.flipupsidedownname = flipupsidedownname
self.twolinename = twolinename
+ self.showid = showid
def set_generations(self):
"""
@@ -160,7 +162,8 @@ class FanChartDescWidget(FanChartBaseWidget):
self.gen2people = {}
self.gen2fam = {}
self.innerring = []
- self.gen2people[0] = [(None, False, 0, 2*pi, 0, 0, [], NORMAL)] #no center person
+ self.gen2people[0] = [(None, False, 0, 2*math.pi, 0, 0,
+ [], NORMAL)] #no center person
self.gen2fam[0] = [] #no families
self.angle = {}
self.angle[-2] = []
@@ -180,7 +183,7 @@ class FanChartDescWidget(FanChartBaseWidget):
# person, duplicate or not, start angle, slice size,
# text, parent pos in fam, nrfam, userdata, status
- self.gen2people[0] = [[person, False, 0, 2*pi, 0, 0, [], NORMAL]]
+ self.gen2people[0] = [[person, False, 0, 2*math.pi, 0, 0, [], NORMAL]]
self.handle2desc[self.rootpersonh] = 0
# fill in data for the parents
self.innerring = []
@@ -191,7 +194,8 @@ class FanChartDescWidget(FanChartBaseWidget):
family = self.dbstate.db.get_family_from_handle(family_handle)
if not family:
continue
- for hparent in [family.get_father_handle(), family.get_mother_handle()]:
+ for hparent in [family.get_father_handle(),
+ family.get_mother_handle()]:
if hparent and hparent not in handleparents:
parent = self.dbstate.db.get_person_from_handle(hparent)
if parent:
@@ -224,26 +228,31 @@ class FanChartDescWidget(FanChartBaseWidget):
fam_duplicate = family_handle in self.famhandle2desc
# family, duplicate or not, start angle, slice size,
# spouse pos in gen, nrchildren, userdata, parnter, status
- self.gen2fam[gen].append([family, fam_duplicate, 0, 0, pos, 0, [], spouse, NORMAL])
+ self.gen2fam[gen].append([family, fam_duplicate, 0, 0,
+ pos, 0, [], spouse, NORMAL])
posfam = len(self.gen2fam[gen]) - 1
if not fam_duplicate and gen < maxgen-1:
nrchild = len(family.get_child_ref_list())
self.gen2fam[gen][posfam][5] = nrchild
for child_ref in family.get_child_ref_list():
- child = self.dbstate.db.get_person_from_handle(child_ref.ref)
+ chld = self.dbstate.db.get_person_from_handle(child_ref.ref)
child_dup = child_ref.ref in self.handle2desc
if not child_dup:
- self.handle2desc[child_ref.ref] = 0 # mark this child as processed
+ # mark this child as processed
+ self.handle2desc[child_ref.ref] = 0
# person, duplicate or not, start angle, slice size,
# parent pos in fam, nrfam, userdata, status
- self.gen2people[gen+1].append([child, child_dup, 0, 0, posfam, 0, [], NORMAL])
+ self.gen2people[gen+1].append([chld, child_dup, 0, 0,
+ posfam, 0, [], NORMAL])
totdescfam += 1 #add this person as descendant
- pospers = len(self.gen2people[gen+1]) - 1
+ pospers = len(self.gen2people[gen + 1]) - 1
if not child_dup:
- nrdesc = self._rec_fill_data(gen+1, child, pospers, maxgen)
+ nrdesc = self._rec_fill_data(gen + 1, chld,
+ pospers, maxgen)
self.handle2desc[child_ref.ref] += nrdesc
- totdescfam += nrdesc # add children of him as descendants
+ # add children of him as descendants
+ totdescfam += nrdesc
if not fam_duplicate:
self.famhandle2desc[family_handle] = totdescfam
totdesc += totdescfam
@@ -255,13 +264,13 @@ class FanChartDescWidget(FanChartBaseWidget):
"""
#first we compute the size of the slice.
#set angles root person
- start, slice = start_rad, stop_rad - start_rad
+ start, portion = start_rad, stop_rad - start_rad
nr_gen = len(self.gen2people)-1
# Fill in central person angles
gen = 0
data = self.gen2people[gen][0]
data[2] = start
- data[3] = slice
+ data[3] = portion
for gen in range(0, nr_gen):
prevpartnerdatahandle = None
offset = 0
@@ -281,40 +290,42 @@ class FanChartDescWidget(FanChartBaseWidget):
#partner of a new person: reset the offset
offset = 0
prevpartnerdatahandle = persondata[0].handle
- slice = personslice/(nrdescperson+nrfam)*(nrdescfam+1)
+ portion = personslice/(nrdescperson+nrfam)*(nrdescfam+1)
if data_fam[8] == COLLAPSED:
- slice = 0
+ portion = 0
elif data_fam[8] == EXPANDED:
- slice = personslice
+ portion = personslice
data_fam[2] = personstart + offset
- data_fam[3] = slice
- offset += slice
+ data_fam[3] = portion
+ offset += portion
## if nrdescperson == 0:
## #no offspring, draw as large as fraction of
## #nr families
## nrfam = persondata[6]
-## slice = personslice/nrfam
+## portion = personslice/nrfam
## data_fam[2] = personstart + offset
-## data_fam[3] = slice
-## offset += slice
+## data_fam[3] = portion
+## offset += portion
## elif nrdescfam == 0:
## #no offspring this family, but there is another
## #family. We draw this as a weight of 1
## nrfam = persondata[6]
-## slice = personslice/(nrdescperson + nrfam - 1)*(nrdescfam+1)
+## portion = (personslice/(nrdescperson + nrfam - 1) *
+## (nrdescfam + 1))
## data_fam[2] = personstart + offset
-## data_fam[3] = slice
-## offset += slice
+## data_fam[3] = portion
+## offset += portion
## else:
## #this family has offspring. We give it space for it's
## #weight in offspring
## nrfam = persondata[6]
-## slice = personslice/(nrdescperson + nrfam - 1)*(nrdescfam+1)
+## portion = (personslice/(nrdescperson + nrfam - 1) *
+## (nrdescfam + 1))
## data_fam[2] = personstart + offset
-## data_fam[3] = slice
-## offset += slice
+## data_fam[3] = portion
+## offset += portion
prevfamdatahandle = None
offset = 0
@@ -333,27 +344,30 @@ class FanChartDescWidget(FanChartBaseWidget):
#now we divide this slice to the weight of children,
#adding one for every child
if self.anglealgo == ANGLE_CHEQUI:
- slice = famslice / nrchild
+ portion = famslice / nrchild
elif self.anglealgo == ANGLE_WEIGHT:
- slice = famslice/(nrdescfam) * (nrdesc + 1)
+ portion = famslice/(nrdescfam) * (nrdesc + 1)
else:
- raise NotImplementedError('Unknown angle algorithm %d' % self.anglealgo)
+ raise NotImplementedError('Unknown angle algorithm %d' %
+ self.anglealgo)
if prevfamdatahandle != parentfamdata[0].handle:
#reset the offset
offset = 0
prevfamdatahandle = parentfamdata[0].handle
if persondata[7] == COLLAPSED:
- slice = 0
+ portion = 0
elif persondata[7] == EXPANDED:
- slice = famslice
+ portion = famslice
persondata[2] = famstart + offset
- persondata[3] = slice
- offset += slice
+ persondata[3] = portion
+ offset += portion
def nrgen(self):
- #compute the number of generations present
+ """
+ compute the number of generations present
+ """
for gen in range(self.generations - 1, 0, -1):
- if len(self.gen2people[gen]) > 0:
+ if self.gen2people[gen]:
return gen + 1
return 1
@@ -363,25 +377,35 @@ class FanChartDescWidget(FanChartBaseWidget):
"""
return self.get_radiusinout_for_generation(self.nrgen())[1]
- def get_radiusinout_for_generation(self,generation):
+ def get_radiusinout_for_generation(self, generation):
+ """
+ Get the in and out radius for the generation
+ """
radius_first_gen = 14 # fudged to make inner circle a bit tighter
if generation < N_GEN_SMALL:
radius_start = PIXELS_PER_GEN_SMALL * generation + radius_first_gen
- return (radius_start,radius_start + PIXELS_PER_GEN_SMALL)
+ return (radius_start, radius_start + PIXELS_PER_GEN_SMALL)
else:
- radius_start = PIXELS_PER_GEN_SMALL * N_GEN_SMALL + PIXELS_PER_GEN_LARGE \
- * ( generation - N_GEN_SMALL ) + radius_first_gen
- return (radius_start,radius_start + PIXELS_PER_GEN_LARGE)
+ radius_start = (PIXELS_PER_GEN_SMALL * N_GEN_SMALL +
+ PIXELS_PER_GEN_LARGE * (generation - N_GEN_SMALL)
+ + radius_first_gen)
+ return (radius_start, radius_start + PIXELS_PER_GEN_LARGE)
- def get_radiusinout_for_generation_pair(self,generation):
+ def get_radiusinout_for_gen_pair(self, generation):
+ """
+ Get the in and out radius for the father and mother
+ """
radiusin, radiusout = self.get_radiusinout_for_generation(generation)
- radius_spread = radiusout - radiusin - PIXELS_CHILDREN_GAP - PIXELS_PARTNER_GAP
+ radius_spread = (radiusout - radiusin -
+ PIXELS_CHILDREN_GAP - PIXELS_PARTNER_GAP)
radiusin_pers = radiusin + PIXELS_CHILDREN_GAP
- radiusout_pers = radiusin_pers + PIXELS_PER_GENPERSON_RATIO * radius_spread
+ radiusout_pers = (radiusin_pers +
+ PIXELS_PER_GENPERSON_RATIO * radius_spread)
radiusin_partner = radiusout_pers + PIXELS_PARTNER_GAP
radiusout_partner = radiusout
- return (radiusin_pers,radiusout_pers,radiusin_partner,radiusout_partner)
+ return (radiusin_pers, radiusout_pers,
+ radiusin_partner, radiusout_partner)
def people_generator(self):
"""
@@ -402,18 +426,18 @@ class FanChartDescWidget(FanChartBaseWidget):
parent, userdata = parentdata
yield (parent, userdata)
- def draw(self, cr=None, scale=1.0):
+ def draw(self, ctx=None, scale=1.0):
"""
The main method to do the drawing.
- If cr is given, we assume we draw draw raw on the cairo context cr
- To draw in GTK3 and use the allocation, set cr=None.
+ If ctx is given, we assume we draw draw raw on the cairo context ctx
+ To draw in GTK3 and use the allocation, set ctx=None.
Note: when drawing for display, to counter a Gtk issue with scrolling
or resizing the drawing window, we draw on a surface, then copy to the
drawing context when the Gtk 'draw' signal arrives.
"""
# first do size request of what we will need
halfdist = self.halfdist()
- if not cr: # Display
+ if not ctx: # Display
if self.form == FORM_CIRCLE:
size_w = size_h = 2 * halfdist
elif self.form == FORM_HALFCIRCLE:
@@ -429,67 +453,73 @@ class FanChartDescWidget(FanChartBaseWidget):
size_h = self.get_allocated_height()
self.surface = cairo.ImageSurface(cairo.FORMAT_ARGB32,
size_w, size_h)
- cr = cairo.Context(self.surface)
+ ctx = cairo.Context(self.surface)
self.center_xy = self.center_xy_from_delta()
- cr.translate(*self.center_xy)
+ ctx.translate(*self.center_xy)
else: # printing
if self.form == FORM_QUADRANT:
self.center_xy = self.CENTER, halfdist
else:
self.center_xy = halfdist, halfdist
- cr.scale(scale, scale)
- cr.translate(*self.center_xy)
+ ctx.scale(scale, scale)
+ ctx.translate(*self.center_xy)
- cr.save()
+ ctx.save()
# Draw center person:
- (person, dup, start, slice, parentfampos, nrfam, userdata, status) \
- = self.gen2people[0][0]
+ (person, dup, start, portion, dummy_parentfampos, dummy_nrfam,
+ userdata, status) = self.gen2people[0][0]
if person:
- r, g, b, a = self.background_box(person, 0, userdata)
- radiusin_pers,radiusout_pers,radiusin_partner,radiusout_partner = \
- self.get_radiusinout_for_generation_pair(0)
- if not self.innerring: radiusin_pers = TRANSLATE_PX
- self.draw_person(cr, person, radiusin_pers, radiusout_pers, math.pi/2, math.pi/2 + 2*math.pi,
- 0, False, userdata, is_central_person =True)
+ #r, g, b, a = self.background_box(person, 0, userdata)
+ (radiusin_pers, radiusout_pers, radiusin_partner,
+ radiusout_partner) = self.get_radiusinout_for_gen_pair(0)
+ if not self.innerring:
+ radiusin_pers = TRANSLATE_PX
+ self.draw_person(ctx, person, radiusin_pers, radiusout_pers,
+ math.pi / 2, math.pi / 2 + 2 * math.pi,
+ 0, False, userdata, is_central_person=True)
#draw center to move chart
- cr.set_source_rgb(0, 0, 0) # black
- cr.move_to(TRANSLATE_PX, 0)
- cr.arc(0, 0, TRANSLATE_PX, 0, 2 * math.pi)
+ ctx.set_source_rgb(0, 0, 0) # black
+ ctx.move_to(TRANSLATE_PX, 0)
+ ctx.arc(0, 0, TRANSLATE_PX, 0, 2 * math.pi)
if self.innerring: # has at least one parent
- cr.fill()
- self.draw_innerring_people(cr)
+ ctx.fill()
+ self.draw_innerring_people(ctx)
else:
- cr.stroke()
+ ctx.stroke()
#now write all the families and children
- cr.rotate(self.rotate_value * math.pi/180)
+ ctx.rotate(self.rotate_value * math.pi/180)
for gen in range(self.generations):
- radiusin_pers,radiusout_pers,radiusin_partner,radiusout_partner = \
- self.get_radiusinout_for_generation_pair(gen)
+ (radiusin_pers, radiusout_pers, radiusin_partner,
+ radiusout_partner) = self.get_radiusinout_for_gen_pair(gen)
if gen > 0:
for pdata in self.gen2people[gen]:
# person, duplicate or not, start angle, slice size,
# parent pos in fam, nrfam, userdata, status
- pers, dup, start, slice, pospar, nrfam, userdata, status = \
- pdata
+ (pers, dup, start, portion, dummy_pospar, dummy_nrfam,
+ userdata, status) = pdata
if status != COLLAPSED:
- self.draw_person(cr, pers, radiusin_pers, radiusout_pers,
- start, start + slice, gen, dup, userdata,
+ self.draw_person(ctx, pers, radiusin_pers,
+ radiusout_pers, start, start + portion,
+ gen, dup, userdata,
thick=status != NORMAL)
#if gen < self.generations-1:
for famdata in self.gen2fam[gen]:
# family, duplicate or not, start angle, slice size,
# spouse pos in gen, nrchildren, userdata, status
- fam, dup, start, slice, posfam, nrchild, userdata,\
- partner, status = famdata
+ (fam, dup, start, portion, dummy_posfam, dummy_nrchild,
+ userdata, partner, status) = famdata
if status != COLLAPSED:
more_pers_flag = (gen == self.generations - 1
- and len(fam.get_child_ref_list()) > 0)
- self.draw_person(cr, partner, radiusin_partner, radiusout_partner, start, start + slice,
- gen, dup, userdata, thick = (status != NORMAL), has_moregen_indicator = more_pers_flag )
- cr.restore()
+ and fam.get_child_ref_list())
+ self.draw_person(ctx, partner, radiusin_partner,
+ radiusout_partner, start, start + portion,
+ gen, dup, userdata,
+ thick=(status != NORMAL),
+ has_moregen_indicator=more_pers_flag)
+ ctx.restore()
if self.background in [BACKGROUND_GRAD_AGE, BACKGROUND_GRAD_PERIOD]:
- self.draw_gradient_legend(cr, halfdist)
+ self.draw_gradient_legend(ctx, halfdist)
def cell_address_under_cursor(self, curx, cury):
"""
@@ -497,21 +527,22 @@ class FanChartDescWidget(FanChartBaseWidget):
position x and y.
None if outside of diagram
"""
- radius, rads, raw_rads = self.cursor_to_polar(curx, cury, get_raw_rads=True)
+ radius, rads, raw_rads = self.cursor_to_polar(curx, cury,
+ get_raw_rads=True)
btype = TYPE_BOX_NORMAL
if radius < TRANSLATE_PX:
return None
elif (self.innerring and self.angle[-2] and
- radius < CHILDRING_WIDTH + TRANSLATE_PX):
+ radius < CHILDRING_WIDTH + TRANSLATE_PX):
generation = -2 # indication of one of the children
elif radius < self.CENTER:
generation = 0
else:
generation = None
for gen in range(self.generations):
- radiusin_pers,radiusout_pers,radiusin_partner,radiusout_partner \
- = self.get_radiusinout_for_generation_pair(gen)
+ (radiusin_pers, radiusout_pers, radiusin_partner,
+ radiusout_partner) = self.get_radiusinout_for_gen_pair(gen)
if radiusin_pers <= radius <= radiusout_pers:
generation, btype = gen, TYPE_BOX_NORMAL
break
@@ -521,24 +552,27 @@ class FanChartDescWidget(FanChartBaseWidget):
# find what person is in this position:
selected = None
- if not (generation is None) and 0 <= generation:
+ if not (generation is None) and generation > 0:
selected = self.personpos_at_angle(generation, rads, btype)
elif generation == -2:
- for p in range(len(self.angle[generation])):
- start, stop, state = self.angle[generation][p]
+ for idx in range(len(self.angle[generation])):
+ start, stop, dummy_state = self.angle[generation][idx]
if self.radian_in_bounds(start, raw_rads, stop):
- selected = p
+ selected = idx
break
if (generation is None or selected is None):
return None
return generation, selected, btype
- def draw_innerring_people(self, cr):
- cr.move_to(TRANSLATE_PX + CHILDRING_WIDTH, 0)
- cr.set_source_rgb(0, 0, 0) # black
- cr.set_line_width(1)
- cr.arc(0, 0, TRANSLATE_PX + CHILDRING_WIDTH, 0, 2 * math.pi)
- cr.stroke()
+ def draw_innerring_people(self, ctx):
+ """
+ Draw the innerring person
+ """
+ ctx.move_to(TRANSLATE_PX + CHILDRING_WIDTH, 0)
+ ctx.set_source_rgb(0, 0, 0) # black
+ ctx.set_line_width(1)
+ ctx.arc(0, 0, TRANSLATE_PX + CHILDRING_WIDTH, 0, 2 * math.pi)
+ ctx.stroke()
nrparent = len(self.innerring)
#Y axis is downward. positve angles are hence clockwise
startangle = math.pi
@@ -549,7 +583,7 @@ class FanChartDescWidget(FanChartBaseWidget):
else:
angleinc = 2 * math.pi / nrparent
for data in self.innerring:
- self.draw_innerring(cr, data[0], data[1], startangle, angleinc)
+ self.draw_innerring(ctx, data[0], data[1], startangle, angleinc)
startangle += angleinc
def personpos_at_angle(self, generation, rads, btype):
@@ -559,19 +593,19 @@ class FanChartDescWidget(FanChartBaseWidget):
selected = None
datas = None
if btype == TYPE_BOX_NORMAL:
- if generation==0:
+ if generation == 0:
return 0 # central person is always ok !
datas = self.gen2people[generation]
elif btype == TYPE_BOX_FAMILY:
datas = self.gen2fam[generation]
else:
return None
- for p, pdata in enumerate(datas):
+ for idx, pdata in enumerate(datas):
# person, duplicate or not, start angle, slice size,
# parent pos in fam, nrfam, userdata, status
start, stop = pdata[2], pdata[2] + pdata[3]
if self.radian_in_bounds(start, rads, stop):
- selected = p
+ selected = idx
break
return selected
@@ -581,7 +615,7 @@ class FanChartDescWidget(FanChartBaseWidget):
"""
generation, pos, btype = cell_address
if generation == -2:
- person, userdata = self.innerring[pos]
+ person, dummy_userdata = self.innerring[pos]
elif btype == TYPE_BOX_NORMAL:
# person, duplicate or not, start angle, slice size,
# parent pos in fam, nrfam, userdata, status
@@ -602,7 +636,9 @@ class FanChartDescWidget(FanChartBaseWidget):
return self.gen2fam[generation][pos][0]
def do_mouse_click(self):
- # no drag occured, expand or collapse the section
+ """
+ no drag occured, expand or collapse the section
+ """
self.toggle_cell_state(self._mouse_click_cell_address)
self._compute_angles(*self.rootangle_rad)
self._mouse_click = False
@@ -610,6 +646,9 @@ class FanChartDescWidget(FanChartBaseWidget):
self.queue_draw()
def toggle_cell_state(self, cell_address):
+ """
+ Toggle the person cell (EXPAND/COLLAPSE)
+ """
generation, selected, btype = cell_address
if generation < 1:
return
@@ -654,10 +693,12 @@ class FanChartDescGrampsGUI(FanChartGrampsGUI):
data.
"""
root_person_handle = self.get_active('Person')
- self.fan.set_values(root_person_handle, self.maxgen, self.flipupsidedownname, self.twolinename, self.background,
- self.fonttype, self.grad_start, self.grad_end,
- self.generic_filter, self.alpha_filter, self.form,
- self.angle_algo, self.dupcolor)
+ self.fan.set_values(root_person_handle, self.maxgen,
+ self.flipupsidedownname, self.twolinename,
+ self.background, self.fonttype, self.grad_start,
+ self.grad_end, self.generic_filter,
+ self.alpha_filter, self.form, self.angle_algo,
+ self.dupcolor, self.showid)
self.fan.reset()
self.fan.draw()
self.fan.queue_draw()
diff --git a/gramps/plugins/gramplet/fanchart2waygramplet.py b/gramps/plugins/gramplet/fanchart2waygramplet.py
index 3c3488fb1..2666a61ea 100644
--- a/gramps/plugins/gramplet/fanchart2waygramplet.py
+++ b/gramps/plugins/gramplet/fanchart2waygramplet.py
@@ -25,16 +25,6 @@
# Python modules
#
#-------------------------------------------------------------------------
-import gi
-gi.require_version('Gtk', '3.0')
-from gi.repository import Pango
-from gi.repository import Gtk
-import math
-from gi.repository import Gdk
-try:
- import cairo
-except ImportError:
- pass
#-------------------------------------------------------------------------
#
@@ -42,14 +32,14 @@ except ImportError:
#
#-------------------------------------------------------------------------
from gramps.gen.const import GRAMPS_LOCALE as glocale
-_ = glocale.translation.gettext
from gramps.gen.plug import Gramplet
-from gramps.gen.errors import WindowActiveError
-from gramps.gui.editors import EditPerson
-from gramps.gui.widgets.fanchart2way import (FanChart2WayWidget, FanChart2WayGrampsGUI,
- ANGLE_WEIGHT)
+from gramps.gui.widgets.fanchart2way import (FanChart2WayWidget,
+ FanChart2WayGrampsGUI,
+ ANGLE_WEIGHT)
from gramps.gui.widgets.fanchart import FORM_HALFCIRCLE, BACKGROUND_SCHEME1
+_ = glocale.translation.gettext
+
class FanChart2WayGramplet(FanChart2WayGrampsGUI, Gramplet):
"""
The Gramplet code that realizes the FanChartWidget.
@@ -71,11 +61,13 @@ class FanChart2WayGramplet(FanChart2WayGrampsGUI, Gramplet):
self.angle_algo = ANGLE_WEIGHT
self.flipupsidedownname = True
self.twolinename = True
+ self.showid = False
self.childring = False
self.background_gradient = True
#self.filter = filter
- self.set_fan(FanChart2WayWidget(self.dbstate, self.uistate, self.on_popup))
+ self.set_fan(FanChart2WayWidget(self.dbstate, self.uistate,
+ self.on_popup))
# Replace the standard textview with the fan chart widget:
self.gui.get_container_widget().remove(self.gui.textview)
self.gui.get_container_widget().add_with_viewport(self.fan)
@@ -83,7 +75,9 @@ class FanChart2WayGramplet(FanChart2WayGrampsGUI, Gramplet):
self.fan.show()
def init(self):
- self.set_tooltip(_("Click to expand/contract person\nRight-click for options\nClick and drag in open area to rotate"))
+ self.set_tooltip(_("Click to expand/contract person\n"
+ "Right-click for options\n"
+ "Click and drag in open area to rotate"))
def active_changed(self, handle):
"""
@@ -95,5 +89,6 @@ class FanChart2WayGramplet(FanChart2WayGrampsGUI, Gramplet):
def on_childmenu_changed(self, obj, person_handle):
"""Callback for the pulldown menu selection, changing to the person
attached with menu item."""
+ dummy_obj = obj
self.set_active('Person', person_handle)
return True
diff --git a/gramps/plugins/gramplet/fanchartdescgramplet.py b/gramps/plugins/gramplet/fanchartdescgramplet.py
index ecb791a08..d07f5de69 100644
--- a/gramps/plugins/gramplet/fanchartdescgramplet.py
+++ b/gramps/plugins/gramplet/fanchartdescgramplet.py
@@ -52,6 +52,7 @@ class FanChartDescGramplet(FanChartDescGrampsGUI, Gramplet):
self.angle_algo = ANGLE_WEIGHT
self.flipupsidedownname = True
self.twolinename = True
+ self.showid = False
self.set_fan(FanChartDescWidget(self.dbstate, self.uistate,
self.on_popup))
# Replace the standard textview with the fan chart widget:
@@ -75,5 +76,6 @@ class FanChartDescGramplet(FanChartDescGrampsGUI, Gramplet):
def on_childmenu_changed(self, obj, person_handle):
"""Callback for the pulldown menu selection, changing to the person
attached with menu item."""
+ dummy_obj = obj
self.set_active('Person', person_handle)
return True
diff --git a/gramps/plugins/gramplet/fanchartgramplet.py b/gramps/plugins/gramplet/fanchartgramplet.py
index 27a7b75c2..9aad9daf9 100644
--- a/gramps/plugins/gramplet/fanchartgramplet.py
+++ b/gramps/plugins/gramplet/fanchartgramplet.py
@@ -56,6 +56,7 @@ class FanChartGramplet(FanChartGrampsGUI, Gramplet):
self.generic_filter = None
self.alpha_filter = 0.2
self.form = FORM_HALFCIRCLE
+ self.showid = False
self.set_fan(FanChartWidget(self.dbstate, self.uistate, self.on_popup))
# Replace the standard textview with the fan chart widget:
self.gui.get_container_widget().remove(self.gui.textview)
@@ -77,5 +78,6 @@ class FanChartGramplet(FanChartGrampsGUI, Gramplet):
def on_childmenu_changed(self, obj, person_handle):
"""Callback for the pulldown menu selection, changing to the person
attached with menu item."""
+ dummy_obj = obj
self.set_active('Person', person_handle)
return True
diff --git a/gramps/plugins/view/fanchart2wayview.py b/gramps/plugins/view/fanchart2wayview.py
index a3b611382..879b11b76 100644
--- a/gramps/plugins/view/fanchart2wayview.py
+++ b/gramps/plugins/view/fanchart2wayview.py
@@ -31,11 +31,9 @@
# Python modules
#
#-------------------------------------------------------------------------
-from gi.repository import Gdk
from gi.repository import Gtk
import cairo
from gramps.gen.const import GRAMPS_LOCALE as glocale
-_ = glocale.translation.gettext
#-------------------------------------------------------------------------
#
@@ -51,6 +49,7 @@ from gramps.plugins.view.fanchartview import FanChartView
# the print settings to remember between print sessions
PRINT_SETTINGS = None
+_ = glocale.translation.gettext
class FanChart2WayView(fanchart2way.FanChart2WayGrampsGUI, NavigationView):
"""
@@ -67,6 +66,7 @@ class FanChart2WayView(fanchart2way.FanChart2WayGrampsGUI, NavigationView):
('interface.fanview-flipupsidedownname', True),
('interface.fanview-font', 'Sans'),
('interface.fanview-form', fanchart.FORM_CIRCLE),
+ ('interface.fanview-showid', False),
('interface.color-start-grad', '#ef2929'),
('interface.color-end-grad', '#3d37e9'),
('interface.angle-algorithm', fanchart2way.ANGLE_WEIGHT),
@@ -77,27 +77,30 @@ class FanChart2WayView(fanchart2way.FanChart2WayGrampsGUI, NavigationView):
self.uistate = uistate
NavigationView.__init__(self, _('2-Way Fan Chart'),
- pdata, dbstate, uistate,
- PersonBookmarks,
- nav_group)
- fanchart2way.FanChart2WayGrampsGUI.__init__(self, self.on_childmenu_changed)
+ pdata, dbstate, uistate,
+ PersonBookmarks, nav_group)
+ fanchart2way.FanChart2WayGrampsGUI.__init__(self,
+ self.on_childmenu_changed)
#set needed values
- self.generations_asc = self._config.get('interface.fanview-maxgen-asc')
- self.generations_desc = self._config.get('interface.fanview-maxgen-desc')
- self.background = self._config.get('interface.fanview-background')
- self.background_gradient = self._config.get('interface.fanview-background-gradient')
- self.radialtext = self._config.get('interface.fanview-radialtext')
- self.twolinename = self._config.get('interface.fanview-twolinename')
- self.flipupsidedownname = self._config.get('interface.fanview-flipupsidedownname')
- self.fonttype = self._config.get('interface.fanview-font')
+ scg = self._config.get
+ self.generations_asc = scg('interface.fanview-maxgen-asc')
+ self.generations_desc = scg('interface.fanview-maxgen-desc')
+ self.background = scg('interface.fanview-background')
+ self.background_gradient = scg('interface.fanview-background-gradient')
+ self.radialtext = scg('interface.fanview-radialtext')
+ self.twolinename = scg('interface.fanview-twolinename')
+ self.flipupsidedownname = scg('interface.fanview-flipupsidedownname')
+ self.fonttype = scg('interface.fanview-font')
- self.grad_start = self._config.get('interface.color-start-grad')
- self.grad_end = self._config.get('interface.color-end-grad')
+ self.grad_start = scg('interface.color-start-grad')
+ self.grad_end = scg('interface.color-end-grad')
self.form = fanchart.FORM_CIRCLE
- self.angle_algo = self._config.get('interface.angle-algorithm')
- self.dupcolor = self._config.get('interface.duplicate-color')
+ self.showid = scg('interface.fanview-showid')
+ self.angle_algo = scg('interface.angle-algorithm')
+ self.dupcolor = scg('interface.duplicate-color')
self.generic_filter = None
self.alpha_filter = 0.2
+ self.scrolledwindow = None
dbstate.connect('active-changed', self.active_changed)
dbstate.connect('database-changed', self.change_db)
@@ -131,7 +134,7 @@ class FanChart2WayView(fanchart2way.FanChart2WayGrampsGUI, NavigationView):
self.set_fan(fanchart2way.FanChart2WayWidget(self.dbstate, self.uistate,
self.on_popup))
self.scrolledwindow = Gtk.ScrolledWindow(hadjustment=None,
- vadjustment=None)
+ vadjustment=None)
self.scrolledwindow.set_policy(Gtk.PolicyType.AUTOMATIC,
Gtk.PolicyType.AUTOMATIC)
self.fan.show_all()
@@ -174,6 +177,7 @@ class FanChart2WayView(fanchart2way.FanChart2WayGrampsGUI, NavigationView):
"""
Method called when active person changes.
"""
+ dummy_handle = handle
# Reset everything but rotation angle (leave it as is)
self.update()
@@ -191,28 +195,43 @@ class FanChart2WayView(fanchart2way.FanChart2WayGrampsGUI, NavigationView):
self._add_db_signal('family-rebuild', self.person_rebuild)
def change_db(self, db):
+ """
+ We selected a new database
+ """
self._change_db(db)
if self.active:
self.bookmarks.redraw()
self.update()
def update(self):
+ """
+ Redraw the fan chart
+ """
self.main()
def goto_handle(self, handle):
+ """
+ Draw the fan chart for the active person
+ """
self.change_active(handle)
self.main()
- def get_active(self, object):
+ def get_active(self, obj):
"""overrule get_active, to support call as in Gramplets
"""
+ dummy_obj = obj
return NavigationView.get_active(self)
def person_rebuild(self, *args):
+ """
+ Redraw the fan chart for the person
+ """
+ dummy_args = args
self.update()
def person_rebuild_bm(self, *args):
"""Large change to person database"""
+ dummy_args = args
self.person_rebuild()
if self.active:
self.bookmarks.redraw()
@@ -221,6 +240,7 @@ class FanChart2WayView(fanchart2way.FanChart2WayGrampsGUI, NavigationView):
"""
Print or save the view that is currently shown
"""
+ dummy_obj = obj
widthpx = 2 * self.fan.halfdist()
heightpx = widthpx
@@ -231,6 +251,7 @@ class FanChart2WayView(fanchart2way.FanChart2WayGrampsGUI, NavigationView):
def on_childmenu_changed(self, obj, person_handle):
"""Callback for the pulldown menu selection, changing to the person
attached with menu item."""
+ dummy_obj = obj
self.change_active(person_handle)
return True
@@ -254,78 +275,76 @@ class FanChart2WayView(fanchart2way.FanChart2WayGrampsGUI, NavigationView):
"""
Function that builds the widget in the configuration dialog
"""
- nrentry = 9
grid = Gtk.Grid()
grid.set_border_width(12)
grid.set_column_spacing(6)
grid.set_row_spacing(6)
configdialog.add_spinner(grid, _("Max ancestor generations"), 0,
- 'interface.fanview-maxgen-asc', (1, 11),
- callback=self.cb_update_maxgen)
+ 'interface.fanview-maxgen-asc', (1, 11),
+ callback=self.cb_update_maxgen)
configdialog.add_spinner(grid, _("Max descendant generations"), 1,
- 'interface.fanview-maxgen-desc', (1, 11),
- callback=self.cb_update_maxgen)
- configdialog.add_combo(grid,
- _('Text Font'),
- 2, 'interface.fanview-font',
- self.allfonts, callback=self.cb_update_font, valueactive=True)
+ 'interface.fanview-maxgen-desc', (1, 11),
+ callback=self.cb_update_maxgen)
+ configdialog.add_combo(grid, _('Text Font'), 2,
+ 'interface.fanview-font',
+ self.allfonts, callback=self.cb_update_font,
+ valueactive=True)
backgrvals = (
- (fanchart.BACKGROUND_GENDER, _('Gender colors')),
- (fanchart.BACKGROUND_GRAD_GEN, _('Generation based gradient')),
- (fanchart.BACKGROUND_GRAD_AGE, _('Age (0-100) based gradient')),
- (fanchart.BACKGROUND_SINGLE_COLOR,
- _('Single main (filter) color')),
- (fanchart.BACKGROUND_GRAD_PERIOD, _('Time period based gradient')),
- (fanchart.BACKGROUND_WHITE, _('White')),
- (fanchart.BACKGROUND_SCHEME1, _('Color scheme classic report')),
- (fanchart.BACKGROUND_SCHEME2, _('Color scheme classic view')),
- )
+ (fanchart.BACKGROUND_GENDER, _('Gender colors')),
+ (fanchart.BACKGROUND_GRAD_GEN, _('Generation based gradient')),
+ (fanchart.BACKGROUND_GRAD_AGE, _('Age (0-100) based gradient')),
+ (fanchart.BACKGROUND_SINGLE_COLOR, _('Single main (filter) color')),
+ (fanchart.BACKGROUND_GRAD_PERIOD, _('Time period based gradient')),
+ (fanchart.BACKGROUND_WHITE, _('White')),
+ (fanchart.BACKGROUND_SCHEME1, _('Color scheme classic report')),
+ (fanchart.BACKGROUND_SCHEME2, _('Color scheme classic view')),
+ )
curval = self._config.get('interface.fanview-background')
nrval = 0
- for nr, val in backgrvals:
- if curval == nr:
+ for nbr, dummy_val in backgrvals:
+ if curval == nbr:
break
nrval += 1
- configdialog.add_combo(grid,
- _('Background'),
- 3, 'interface.fanview-background',
- backgrvals,
- callback=self.cb_update_background, valueactive=False,
- setactive=nrval
- )
+ configdialog.add_combo(grid, _('Background'), 3,
+ 'interface.fanview-background', backgrvals,
+ callback=self.cb_update_background,
+ valueactive=False, setactive=nrval)
# show names one two line
configdialog.add_checkbox(grid,
- _('Add global background colored gradient'),
- 4, 'interface.fanview-background-gradient')
+ _('Add global background colored gradient'),
+ 4, 'interface.fanview-background-gradient')
#colors, stored as hex values
configdialog.add_color(grid, _('Start gradient/Main color'), 5,
- 'interface.color-start-grad', col=1)
+ 'interface.color-start-grad', col=1)
configdialog.add_color(grid, _('End gradient/2nd color'), 6,
- 'interface.color-end-grad', col=1)
+ 'interface.color-end-grad', col=1)
configdialog.add_color(grid, _('Color for duplicates'), 7,
- 'interface.duplicate-color', col=1)
+ 'interface.duplicate-color', col=1)
# algo for the fan angle distribution
configdialog.add_combo(grid, _('Fan chart distribution'), 8,
- 'interface.angle-algorithm',
- ((fanchart2way.ANGLE_CHEQUI,
- _('Homogeneous children distribution')),
- (fanchart2way.ANGLE_WEIGHT,
- _('Size proportional to number of descendants')),
- ),
- callback=self.cb_update_anglealgo)
+ 'interface.angle-algorithm',
+ ((fanchart2way.ANGLE_CHEQUI,
+ _('Homogeneous children distribution')),
+ (fanchart2way.ANGLE_WEIGHT,
+ _('Size proportional to number'
+ ' of descendants')),
+ ),
+ callback=self.cb_update_anglealgo)
# show names one two line
- configdialog.add_checkbox(grid,
- _('Show names on two lines'),
- 9, 'interface.fanview-twolinename')
+ configdialog.add_checkbox(grid, _('Show names on two lines'),
+ 9, 'interface.fanview-twolinename')
# Flip names
- configdialog.add_checkbox(grid,
- _('Flip name on the left of the fan'),
- 10, 'interface.fanview-flipupsidedownname')
+ configdialog.add_checkbox(grid, _('Flip name on the left of the fan'),
+ 10, 'interface.fanview-flipupsidedownname')
+
+ # Show gramps id
+ configdialog.add_checkbox(grid, _('Show the gramps id'),
+ 11, 'interface.fanview-showid')
return _('Layout'), grid
@@ -336,22 +355,28 @@ class FanChart2WayView(fanchart2way.FanChart2WayGrampsGUI, NavigationView):
use it to monitor changes in the ini file
"""
self._config.connect('interface.color-start-grad',
- self.cb_update_color)
+ self.cb_update_color)
self._config.connect('interface.color-end-grad',
- self.cb_update_color)
+ self.cb_update_color)
self._config.connect('interface.duplicate-color',
- self.cb_update_color)
+ self.cb_update_color)
self._config.connect('interface.fanview-flipupsidedownname',
- self.cb_update_flipupsidedownname)
+ self.cb_update_flipupsidedownname)
self._config.connect('interface.fanview-twolinename',
- self.cb_update_twolinename)
+ self.cb_update_twolinename)
self._config.connect('interface.fanview-background-gradient',
- self.cb_update_background_gradient)
+ self.cb_update_background_gradient)
+ self._config.connect('interface.fanview-showid',
+ self.cb_update_showid)
def cb_update_maxgen(self, spinbtn, constant):
+ """
+ The maximum generations in the fanchart
+ """
self._config.set(constant, spinbtn.get_value_as_int())
- self.generations_asc = int(self._config.get('interface.fanview-maxgen-asc'))
- self.generations_desc = int(self._config.get('interface.fanview-maxgen-desc'))
+ scg = self._config.get
+ self.generations_asc = int(scg('interface.fanview-maxgen-asc'))
+ self.generations_desc = int(scg('interface.fanview-maxgen-desc'))
self.update()
def cb_update_twolinename(self, client, cnxn_id, entry, data):
@@ -361,11 +386,21 @@ class FanChart2WayView(fanchart2way.FanChart2WayGrampsGUI, NavigationView):
self.twolinename = (entry == 'True')
self.update()
+ def cb_update_showid(self, client, cnxn_id, entry, data):
+ """
+ Called when the configuration menu changes the showid setting.
+ """
+ self.showid = (entry == 'True')
+ self.update()
+
def cb_update_background(self, obj, constant):
+ """
+ The background selected
+ """
entry = obj.get_active()
Gtk.TreePath.new_from_string('%d' % entry)
val = int(obj.get_model().get_value(
- obj.get_model().get_iter_from_string('%d' % entry), 0))
+ obj.get_model().get_iter_from_string('%d' % entry), 0))
self._config.set(constant, val)
self.background = val
self.update()
@@ -378,12 +413,18 @@ class FanChart2WayView(fanchart2way.FanChart2WayGrampsGUI, NavigationView):
self.update()
def cb_update_form(self, obj, constant):
+ """
+ Update the fanchart form: CIRCLE, HALFCIRCLE or QUADRANT
+ """
entry = obj.get_active()
self._config.set(constant, entry)
self.form = entry
self.update()
def cb_update_anglealgo(self, obj, constant):
+ """
+ Update the angle algorythm : homogeneous children distribution or not
+ """
entry = obj.get_active()
self._config.set(constant, entry)
self.angle_algo = entry
@@ -400,12 +441,16 @@ class FanChart2WayView(fanchart2way.FanChart2WayGrampsGUI, NavigationView):
def cb_update_flipupsidedownname(self, client, cnxn_id, entry, data):
"""
- Called when the configuration menu changes the flipupsidedownname setting.
+ Called when the configuration menu changes the
+ flipupsidedownname setting.
"""
self.flipupsidedownname = (entry == 'True')
self.update()
def cb_update_font(self, obj, constant):
+ """
+ Update the choosed font
+ """
entry = obj.get_active()
self._config.set(constant, self.allfonts[entry][1])
self.fonttype = self.allfonts[entry][1]
@@ -440,6 +485,8 @@ class CairoPrintSave():
self.heightpx = heightpx
self.drawfunc = drawfunc
self.parent = parent
+ self.preview = None
+ self.previewopr = None
def run(self):
"""Create the physical output from the meta document.
@@ -473,7 +520,8 @@ class CairoPrintSave():
# run print dialog
while True:
self.preview = None
- res = operation.run(Gtk.PrintOperationAction.PRINT_DIALOG, self.parent)
+ res = operation.run(Gtk.PrintOperationAction.PRINT_DIALOG,
+ self.parent)
if self.preview is None: # cancel or print
break
# set up printing again; can't reuse PrintOperation?
@@ -493,20 +541,24 @@ class CairoPrintSave():
def on_draw_page(self, operation, context, page_nr):
"""Draw a page on a Cairo context.
"""
- cr = context.get_cairo_context()
+ dummy_operation = operation
+ dummy_page_nr = page_nr
+ ctx = context.get_cairo_context()
pxwidth = round(context.get_width())
pxheight = round(context.get_height())
scale = min(pxwidth/self.widthpx, pxheight/self.heightpx)
- self.drawfunc(None, cr, scale=scale)
+ self.drawfunc(None, ctx, scale=scale)
def on_paginate(self, operation, context):
"""Paginate the whole document in chunks.
We don't need this as there is only one page, however,
we provide a dummy holder here, because on_preview crashes if no
- default application is set with gir 3.3.2 (typically evince not installed)!
+ default application is set with gir 3.3.2
+ (typically evince not installed)!
It will provide the start of the preview dialog, which cannot be
started in on_preview
"""
+ dummy_context = context
finished = True
# update page number
operation.set_n_pages(1)
@@ -520,13 +572,15 @@ class CairoPrintSave():
def on_preview(self, operation, preview, context, parent):
"""Implement custom print preview functionality.
We provide a dummy holder here, because on_preview crashes if no
- default application is set with gir 3.3.2 (typically evince not installed)!
+ default application is set with gir 3.3.2
+ (typically evince not installed)!
"""
+ dummy_preview = preview
dlg = Gtk.MessageDialog(parent,
- flags=Gtk.DialogFlags.MODAL,
- type=Gtk.MessageType.WARNING,
- buttons=Gtk.ButtonsType.CLOSE,
- message_format=_('No preview available'))
+ flags=Gtk.DialogFlags.MODAL,
+ type=Gtk.MessageType.WARNING,
+ buttons=Gtk.ButtonsType.CLOSE,
+ message_format=_('No preview available'))
self.preview = dlg
self.previewopr = operation
#dlg.format_secondary_markup(msg2)
@@ -543,11 +597,16 @@ class CairoPrintSave():
except ValueError:
height = 0
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)
- cr = cairo.Context(surface)
- context.set_cairo_context(cr, 72.0, 72.0)
+ ctx = cairo.Context(surface)
+ context.set_cairo_context(ctx, 72.0, 72.0)
return True
def previewdestroy(self, dlg, res):
+ """
+ Destroy the preview page
+ """
+ dummy_dlg = dlg
+ dummy_res = res
self.preview.destroy()
self.previewopr.end_preview()
diff --git a/gramps/plugins/view/fanchartdescview.py b/gramps/plugins/view/fanchartdescview.py
index 00ca8f735..34a346925 100644
--- a/gramps/plugins/view/fanchartdescview.py
+++ b/gramps/plugins/view/fanchartdescview.py
@@ -30,11 +30,9 @@
# Python modules
#
#-------------------------------------------------------------------------
-from gi.repository import Gdk
from gi.repository import Gtk
import cairo
from gramps.gen.const import GRAMPS_LOCALE as glocale
-_ = glocale.translation.gettext
#-------------------------------------------------------------------------
#
@@ -50,6 +48,7 @@ from gramps.plugins.view.fanchartview import FanChartView
# the print settings to remember between print sessions
PRINT_SETTINGS = None
+_ = glocale.translation.gettext
class FanChartDescView(fanchartdesc.FanChartDescGrampsGUI, NavigationView):
"""
@@ -67,32 +66,36 @@ class FanChartDescView(fanchartdesc.FanChartDescGrampsGUI, NavigationView):
('interface.color-start-grad', '#ef2929'),
('interface.color-end-grad', '#3d37e9'),
('interface.angle-algorithm', fanchartdesc.ANGLE_WEIGHT),
- ('interface.duplicate-color', '#888a85')
+ ('interface.duplicate-color', '#888a85'),
+ ('interface.fanview-showid', False)
)
def __init__(self, pdata, dbstate, uistate, nav_group=0):
self.dbstate = dbstate
self.uistate = uistate
NavigationView.__init__(self, _('Descendant Fan Chart'),
- pdata, dbstate, uistate,
- PersonBookmarks,
- nav_group)
- fanchartdesc.FanChartDescGrampsGUI.__init__(self, self.on_childmenu_changed)
+ pdata, dbstate, uistate,
+ PersonBookmarks, nav_group)
+ fanchartdesc.FanChartDescGrampsGUI.__init__(self,
+ self.on_childmenu_changed)
#set needed values
- self.maxgen = self._config.get('interface.fanview-maxgen')
- self.background = self._config.get('interface.fanview-background')
- self.radialtext = self._config.get('interface.fanview-radialtext')
- self.twolinename = self._config.get('interface.fanview-twolinename')
- self.flipupsidedownname = self._config.get('interface.fanview-flipupsidedownname')
- self.fonttype = self._config.get('interface.fanview-font')
+ scg = self._config.get
+ self.maxgen = scg('interface.fanview-maxgen')
+ self.background = scg('interface.fanview-background')
+ self.radialtext = scg('interface.fanview-radialtext')
+ self.twolinename = scg('interface.fanview-twolinename')
+ self.flipupsidedownname = scg('interface.fanview-flipupsidedownname')
+ self.fonttype = scg('interface.fanview-font')
- self.grad_start = self._config.get('interface.color-start-grad')
- self.grad_end = self._config.get('interface.color-end-grad')
- self.form = self._config.get('interface.fanview-form')
- self.angle_algo = self._config.get('interface.angle-algorithm')
- self.dupcolor = self._config.get('interface.duplicate-color')
+ self.grad_start = scg('interface.color-start-grad')
+ self.grad_end = scg('interface.color-end-grad')
+ self.form = scg('interface.fanview-form')
+ self.angle_algo = scg('interface.angle-algorithm')
+ self.dupcolor = scg('interface.duplicate-color')
+ self.showid = scg('interface.fanview-showid')
self.generic_filter = None
self.alpha_filter = 0.2
+ self.scrolledwindow = None
dbstate.connect('active-changed', self.active_changed)
dbstate.connect('database-changed', self.change_db)
@@ -170,6 +173,7 @@ class FanChartDescView(fanchartdesc.FanChartDescGrampsGUI, NavigationView):
Method called when active person changes.
"""
# Reset everything but rotation angle (leave it as is)
+ dummy_handle = handle
self.update()
def _connect_db_signals(self):
@@ -186,28 +190,43 @@ class FanChartDescView(fanchartdesc.FanChartDescGrampsGUI, NavigationView):
self._add_db_signal('family-rebuild', self.person_rebuild)
def change_db(self, db):
+ """
+ We selected a new database
+ """
self._change_db(db)
if self.active:
self.bookmarks.redraw()
self.update()
def update(self):
+ """
+ Redraw the fan chart
+ """
self.main()
def goto_handle(self, handle):
+ """
+ Draw the fan chart for the active person
+ """
self.change_active(handle)
self.main()
- def get_active(self, object):
+ def get_active(self, obj):
"""overrule get_active, to support call as in Gramplets
"""
+ dummy_obj = obj
return NavigationView.get_active(self)
def person_rebuild(self, *args):
+ """
+ Redraw the fan chart for the person
+ """
+ dummy_args = args
self.update()
def person_rebuild_bm(self, *args):
"""Large change to person database"""
+ dummy_args = args
self.person_rebuild()
if self.active:
self.bookmarks.redraw()
@@ -216,6 +235,7 @@ class FanChartDescView(fanchartdesc.FanChartDescGrampsGUI, NavigationView):
"""
Print or save the view that is currently shown
"""
+ dummy_obj = obj
widthpx = 2 * self.fan.halfdist()
heightpx = widthpx
if self.form == fanchart.FORM_HALFCIRCLE:
@@ -231,6 +251,7 @@ class FanChartDescView(fanchartdesc.FanChartDescGrampsGUI, NavigationView):
def on_childmenu_changed(self, obj, person_handle):
"""Callback for the pulldown menu selection, changing to the person
attached with menu item."""
+ dummy_obj = obj
self.change_active(person_handle)
return True
@@ -254,76 +275,75 @@ class FanChartDescView(fanchartdesc.FanChartDescGrampsGUI, NavigationView):
"""
Function that builds the widget in the configuration dialog
"""
- nrentry = 9
grid = Gtk.Grid()
grid.set_border_width(12)
grid.set_column_spacing(6)
grid.set_row_spacing(6)
configdialog.add_spinner(grid, _("Max generations"), 0,
- 'interface.fanview-maxgen', (2, 16),
- callback=self.cb_update_maxgen)
- configdialog.add_combo(grid,
- _('Text Font'),
- 1, 'interface.fanview-font',
- self.allfonts, callback=self.cb_update_font, valueactive=True)
+ 'interface.fanview-maxgen', (2, 16),
+ callback=self.cb_update_maxgen)
+ configdialog.add_combo(grid, _('Text Font'),
+ 1, 'interface.fanview-font',
+ self.allfonts, callback=self.cb_update_font,
+ valueactive=True)
backgrvals = (
- (fanchart.BACKGROUND_GENDER, _('Gender colors')),
- (fanchart.BACKGROUND_GRAD_GEN, _('Generation based gradient')),
- (fanchart.BACKGROUND_GRAD_AGE, _('Age (0-100) based gradient')),
- (fanchart.BACKGROUND_SINGLE_COLOR,
- _('Single main (filter) color')),
- (fanchart.BACKGROUND_GRAD_PERIOD, _('Time period based gradient')),
- (fanchart.BACKGROUND_WHITE, _('White')),
- (fanchart.BACKGROUND_SCHEME1, _('Color scheme classic report')),
- (fanchart.BACKGROUND_SCHEME2, _('Color scheme classic view')),
- )
+ (fanchart.BACKGROUND_GENDER, _('Gender colors')),
+ (fanchart.BACKGROUND_GRAD_GEN, _('Generation based gradient')),
+ (fanchart.BACKGROUND_GRAD_AGE, _('Age (0-100) based gradient')),
+ (fanchart.BACKGROUND_SINGLE_COLOR,
+ _('Single main (filter) color')),
+ (fanchart.BACKGROUND_GRAD_PERIOD, _('Time period based gradient')),
+ (fanchart.BACKGROUND_WHITE, _('White')),
+ (fanchart.BACKGROUND_SCHEME1, _('Color scheme classic report')),
+ (fanchart.BACKGROUND_SCHEME2, _('Color scheme classic view')),
+ )
curval = self._config.get('interface.fanview-background')
nrval = 0
- for nr, val in backgrvals:
- if curval == nr:
+ for nbr, dummy_val in backgrvals:
+ if curval == nbr:
break
nrval += 1
- configdialog.add_combo(grid,
- _('Background'),
- 2, 'interface.fanview-background',
- backgrvals,
- callback=self.cb_update_background, valueactive=False,
- setactive=nrval
- )
+ configdialog.add_combo(grid, _('Background'),
+ 2, 'interface.fanview-background',
+ backgrvals, callback=self.cb_update_background,
+ valueactive=False, setactive=nrval)
#colors, stored as hex values
configdialog.add_color(grid, _('Start gradient/Main color'), 3,
- 'interface.color-start-grad', col=1)
+ 'interface.color-start-grad', col=1)
configdialog.add_color(grid, _('End gradient/2nd color'), 4,
- 'interface.color-end-grad', col=1)
+ 'interface.color-end-grad', col=1)
configdialog.add_color(grid, _('Color for duplicates'), 5,
- 'interface.duplicate-color', col=1)
+ 'interface.duplicate-color', col=1)
# form of the fan
configdialog.add_combo(grid, _('Fan chart type'), 6,
- 'interface.fanview-form',
- ((fanchart.FORM_CIRCLE, _('Full Circle')),
- (fanchart.FORM_HALFCIRCLE, _('Half Circle')),
- (fanchart.FORM_QUADRANT, _('Quadrant'))),
- callback=self.cb_update_form)
+ 'interface.fanview-form',
+ ((fanchart.FORM_CIRCLE, _('Full Circle')),
+ (fanchart.FORM_HALFCIRCLE, _('Half Circle')),
+ (fanchart.FORM_QUADRANT, _('Quadrant'))),
+ callback=self.cb_update_form)
# algo for the fan angle distribution
configdialog.add_combo(grid, _('Fan chart distribution'), 7,
- 'interface.angle-algorithm',
- ((fanchartdesc.ANGLE_CHEQUI,
- _('Homogeneous children distribution')),
- (fanchartdesc.ANGLE_WEIGHT,
- _('Size proportional to number of descendants')),
- ),
- callback=self.cb_update_anglealgo)
+ 'interface.angle-algorithm',
+ ((fanchartdesc.ANGLE_CHEQUI,
+ _('Homogeneous children distribution')),
+ (fanchartdesc.ANGLE_WEIGHT,
+ _('Size proportional to number'
+ ' of descendants')),
+ ),
+ callback=self.cb_update_anglealgo)
# show names one two line
- configdialog.add_checkbox(grid,
- _('Show names on two lines'),
- 8, 'interface.fanview-twolinename')
+ configdialog.add_checkbox(grid, _('Show names on two lines'),
+ 8, 'interface.fanview-twolinename')
# Flip names
- configdialog.add_checkbox(grid,
- _('Flip name on the left of the fan'),
- 9, 'interface.fanview-flipupsidedownname')
+ configdialog.add_checkbox(grid, _('Flip name on the left of the fan'),
+ 9, 'interface.fanview-flipupsidedownname')
+
+ # show gramps_id
+ configdialog.add_checkbox(grid, _('Show gramps id'),
+ 10, 'interface.fanview-showid')
return _('Layout'), grid
@@ -334,17 +354,22 @@ class FanChartDescView(fanchartdesc.FanChartDescGrampsGUI, NavigationView):
use it to monitor changes in the ini file
"""
self._config.connect('interface.color-start-grad',
- self.cb_update_color)
+ self.cb_update_color)
self._config.connect('interface.color-end-grad',
- self.cb_update_color)
+ self.cb_update_color)
self._config.connect('interface.duplicate-color',
- self.cb_update_color)
+ self.cb_update_color)
self._config.connect('interface.fanview-flipupsidedownname',
- self.cb_update_flipupsidedownname)
+ self.cb_update_flipupsidedownname)
self._config.connect('interface.fanview-twolinename',
- self.cb_update_twolinename)
+ self.cb_update_twolinename)
+ self._config.connect('interface.fanview-showid',
+ self.cb_update_showid)
def cb_update_maxgen(self, spinbtn, constant):
+ """
+ The maximum generations in the fanchart
+ """
self.maxgen = spinbtn.get_value_as_int()
self._config.set(constant, self.maxgen)
self.update()
@@ -357,21 +382,30 @@ class FanChartDescView(fanchartdesc.FanChartDescGrampsGUI, NavigationView):
self.update()
def cb_update_background(self, obj, constant):
+ """
+ Change the background
+ """
entry = obj.get_active()
Gtk.TreePath.new_from_string('%d' % entry)
val = int(obj.get_model().get_value(
- obj.get_model().get_iter_from_string('%d' % entry), 0))
+ obj.get_model().get_iter_from_string('%d' % entry), 0))
self._config.set(constant, val)
self.background = val
self.update()
def cb_update_form(self, obj, constant):
+ """
+ Update the fanchart form: CIRCLE, HALFCIRCLE or QUADRANT
+ """
entry = obj.get_active()
self._config.set(constant, entry)
self.form = entry
self.update()
def cb_update_anglealgo(self, obj, constant):
+ """
+ Update the angle algorythm : homogeneous children distribution or not
+ """
entry = obj.get_active()
self._config.set(constant, entry)
self.angle_algo = entry
@@ -388,12 +422,23 @@ class FanChartDescView(fanchartdesc.FanChartDescGrampsGUI, NavigationView):
def cb_update_flipupsidedownname(self, client, cnxn_id, entry, data):
"""
- Called when the configuration menu changes the flipupsidedownname setting.
+ Called when the configuration menu changes the
+ flipupsidedownname setting.
"""
self.flipupsidedownname = (entry == 'True')
self.update()
+ def cb_update_showid(self, client, cnxn_id, entry, data):
+ """
+ Called when the configuration menu changes the showid setting.
+ """
+ self.showid = (entry == 'True')
+ self.update()
+
def cb_update_font(self, obj, constant):
+ """
+ Change the font
+ """
entry = obj.get_active()
self._config.set(constant, self.allfonts[entry][1])
self.fonttype = self.allfonts[entry][1]
@@ -428,6 +473,8 @@ class CairoPrintSave:
self.heightpx = heightpx
self.drawfunc = drawfunc
self.parent = parent
+ self.preview = None
+ self.previewopr = None
def run(self):
"""Create the physical output from the meta document.
@@ -461,7 +508,8 @@ class CairoPrintSave:
# run print dialog
while True:
self.preview = None
- res = operation.run(Gtk.PrintOperationAction.PRINT_DIALOG, self.parent)
+ res = operation.run(Gtk.PrintOperationAction.PRINT_DIALOG,
+ self.parent)
if self.preview is None: # cancel or print
break
# set up printing again; can't reuse PrintOperation?
@@ -481,20 +529,24 @@ class CairoPrintSave:
def on_draw_page(self, operation, context, page_nr):
"""Draw a page on a Cairo context.
"""
- cr = context.get_cairo_context()
+ dummy_operation = operation
+ dummy_page_nr = page_nr
+ ctx = context.get_cairo_context()
pxwidth = round(context.get_width())
pxheight = round(context.get_height())
scale = min(pxwidth/self.widthpx, pxheight/self.heightpx)
- self.drawfunc(None, cr, scale=scale)
+ self.drawfunc(None, ctx, scale=scale)
def on_paginate(self, operation, context):
"""Paginate the whole document in chunks.
We don't need this as there is only one page, however,
we provide a dummy holder here, because on_preview crashes if no
- default application is set with gir 3.3.2 (typically evince not installed)!
+ default application is set with gir 3.3.2
+ (typically evince not installed)!
It will provide the start of the preview dialog, which cannot be
started in on_preview
"""
+ dummy_context = context
finished = True
# update page number
operation.set_n_pages(1)
@@ -508,13 +560,15 @@ class CairoPrintSave:
def on_preview(self, operation, preview, context, parent):
"""Implement custom print preview functionality.
We provide a dummy holder here, because on_preview crashes if no
- default application is set with gir 3.3.2 (typically evince not installed)!
+ default application is set with gir 3.3.2
+ (typically evince not installed)!
"""
+ dummy_preview = preview
dlg = Gtk.MessageDialog(parent,
- flags=Gtk.DialogFlags.MODAL,
- type=Gtk.MessageType.WARNING,
- buttons=Gtk.ButtonsType.CLOSE,
- message_format=_('No preview available'))
+ flags=Gtk.DialogFlags.MODAL,
+ type=Gtk.MessageType.WARNING,
+ buttons=Gtk.ButtonsType.CLOSE,
+ message_format=_('No preview available'))
self.preview = dlg
self.previewopr = operation
#dlg.format_secondary_markup(msg2)
@@ -531,11 +585,16 @@ class CairoPrintSave:
except ValueError:
height = 0
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)
- cr = cairo.Context(surface)
- context.set_cairo_context(cr, 72.0, 72.0)
+ ctx = cairo.Context(surface)
+ context.set_cairo_context(ctx, 72.0, 72.0)
return True
def previewdestroy(self, dlg, res):
+ """
+ Destroy the preview page
+ """
+ dummy_dlg = dlg
+ dummy_res = res
self.preview.destroy()
self.previewopr.end_preview()
diff --git a/gramps/plugins/view/fanchartview.py b/gramps/plugins/view/fanchartview.py
index ced026809..059b48d63 100644
--- a/gramps/plugins/view/fanchartview.py
+++ b/gramps/plugins/view/fanchartview.py
@@ -30,11 +30,9 @@
# Python modules
#
#-------------------------------------------------------------------------
-from gi.repository import Gdk
from gi.repository import Gtk
import cairo
from gramps.gen.const import GRAMPS_LOCALE as glocale
-_ = glocale.translation.sgettext
#-------------------------------------------------------------------------
#
@@ -48,6 +46,7 @@ from gramps.gui.utils import SystemFonts
# the print settings to remember between print sessions
PRINT_SETTINGS = None
+_ = glocale.translation.sgettext
class FanChartView(fanchart.FanChartGrampsGUI, NavigationView):
"""
@@ -63,6 +62,7 @@ class FanChartView(fanchart.FanChartGrampsGUI, NavigationView):
('interface.fanview-flipupsidedownname', True),
('interface.fanview-font', 'Sans'),
('interface.fanview-form', fanchart.FORM_CIRCLE),
+ ('interface.fanview-showid', False),
('interface.color-start-grad', '#ef2929'),
('interface.color-end-grad', '#3d37e9'),
)
@@ -71,24 +71,26 @@ class FanChartView(fanchart.FanChartGrampsGUI, NavigationView):
self.uistate = uistate
NavigationView.__init__(self, _('Fan Chart'),
- pdata, dbstate, uistate,
- PersonBookmarks,
- nav_group)
+ pdata, dbstate, uistate,
+ PersonBookmarks, nav_group)
fanchart.FanChartGrampsGUI.__init__(self, self.on_childmenu_changed)
#set needed values
- self.maxgen = self._config.get('interface.fanview-maxgen')
- self.background = self._config.get('interface.fanview-background')
- self.childring = self._config.get('interface.fanview-childrenring')
- self.radialtext = self._config.get('interface.fanview-radialtext')
- self.twolinename = self._config.get('interface.fanview-twolinename')
- self.flipupsidedownname = self._config.get('interface.fanview-flipupsidedownname')
- self.fonttype = self._config.get('interface.fanview-font')
+ scg = self._config.get
+ self.maxgen = scg('interface.fanview-maxgen')
+ self.background = scg('interface.fanview-background')
+ self.childring = scg('interface.fanview-childrenring')
+ self.radialtext = scg('interface.fanview-radialtext')
+ self.twolinename = scg('interface.fanview-twolinename')
+ self.flipupsidedownname = scg('interface.fanview-flipupsidedownname')
+ self.fonttype = scg('interface.fanview-font')
- self.grad_start = self._config.get('interface.color-start-grad')
- self.grad_end = self._config.get('interface.color-end-grad')
- self.form = self._config.get('interface.fanview-form')
+ self.grad_start = scg('interface.color-start-grad')
+ self.grad_end = scg('interface.color-end-grad')
+ self.form = scg('interface.fanview-form')
+ self.showid = scg('interface.fanview-showid')
self.generic_filter = None
self.alpha_filter = 0.2
+ self.scrolledwindow = None
dbstate.connect('active-changed', self.active_changed)
dbstate.connect('database-changed', self.change_db)
@@ -119,7 +121,8 @@ class FanChartView(fanchart.FanChartGrampsGUI, NavigationView):
return None
def build_widget(self):
- self.set_fan(fanchart.FanChartWidget(self.dbstate, self.uistate, self.on_popup))
+ self.set_fan(fanchart.FanChartWidget(self.dbstate, self.uistate,
+ self.on_popup))
self.scrolledwindow = Gtk.ScrolledWindow(hadjustment=None,
vadjustment=None)
self.scrolledwindow.set_policy(Gtk.PolicyType.AUTOMATIC,
@@ -266,6 +269,7 @@ class FanChartView(fanchart.FanChartGrampsGUI, NavigationView):
"""
Method called when active person changes.
"""
+ dummy_handle = handle
# Reset everything but rotation angle (leave it as is)
self.update()
@@ -283,28 +287,43 @@ class FanChartView(fanchart.FanChartGrampsGUI, NavigationView):
self._add_db_signal('family-rebuild', self.person_rebuild)
def change_db(self, db):
+ """
+ We selected a new database
+ """
self._change_db(db)
if self.active:
self.bookmarks.redraw()
self.update()
def update(self):
+ """
+ Redraw the fan chart
+ """
self.main()
def goto_handle(self, handle):
+ """
+ Draw the fan chart for the active person
+ """
self.change_active(handle)
self.main()
- def get_active(self, object):
+ def get_active(self, obj):
"""overrule get_active, to support call as in Gramplets
"""
+ dummy_obj = obj
return NavigationView.get_active(self)
def person_rebuild(self, *args):
+ """
+ Redraw the fan chart for the person
+ """
+ dummy_args = args
self.update()
def person_rebuild_bm(self, *args):
"""Large change to person database"""
+ dummy_args = args
self.person_rebuild()
if self.active:
self.bookmarks.redraw()
@@ -313,6 +332,7 @@ class FanChartView(fanchart.FanChartGrampsGUI, NavigationView):
"""
Print or save the view that is currently shown
"""
+ dummy_obj = obj
widthpx = 2 * self.fan.halfdist()
heightpx = widthpx
if self.form == fanchart.FORM_HALFCIRCLE:
@@ -328,6 +348,7 @@ class FanChartView(fanchart.FanChartGrampsGUI, NavigationView):
def on_childmenu_changed(self, obj, person_handle):
"""Callback for the pulldown menu selection, changing to the person
attached with menu item."""
+ dummy_obj = obj
self.change_active(person_handle)
return True
@@ -351,68 +372,66 @@ class FanChartView(fanchart.FanChartGrampsGUI, NavigationView):
"""
Function that builds the widget in the configuration dialog
"""
- nrentry = 9
+ nrentry = 10
grid = Gtk.Grid()
grid.set_border_width(12)
grid.set_column_spacing(6)
grid.set_row_spacing(6)
configdialog.add_spinner(grid, _("Max generations"), 0,
- 'interface.fanview-maxgen', (1, 16),
- callback=self.cb_update_maxgen)
- configdialog.add_combo(grid,
- _('Text Font'),
- 1, 'interface.fanview-font',
- self.allfonts, callback=self.cb_update_font, valueactive=True)
+ 'interface.fanview-maxgen', (1, 16),
+ callback=self.cb_update_maxgen)
+ configdialog.add_combo(grid, _('Text Font'),
+ 1, 'interface.fanview-font',
+ self.allfonts, callback=self.cb_update_font,
+ valueactive=True)
backgrvals = (
- (fanchart.BACKGROUND_GENDER, _('Gender colors')),
- (fanchart.BACKGROUND_GRAD_GEN, _('Generation based gradient')),
- (fanchart.BACKGROUND_GRAD_AGE, _('Age (0-100) based gradient')),
- (fanchart.BACKGROUND_SINGLE_COLOR,
- _('Single main (filter) color')),
- (fanchart.BACKGROUND_GRAD_PERIOD, _('Time period based gradient')),
- (fanchart.BACKGROUND_WHITE, _('White')),
- (fanchart.BACKGROUND_SCHEME1, _('Color scheme classic report')),
- (fanchart.BACKGROUND_SCHEME2, _('Color scheme classic view')),
- )
+ (fanchart.BACKGROUND_GENDER, _('Gender colors')),
+ (fanchart.BACKGROUND_GRAD_GEN, _('Generation based gradient')),
+ (fanchart.BACKGROUND_GRAD_AGE, _('Age (0-100) based gradient')),
+ (fanchart.BACKGROUND_SINGLE_COLOR, _('Single main (filter) color')),
+ (fanchart.BACKGROUND_GRAD_PERIOD, _('Time period based gradient')),
+ (fanchart.BACKGROUND_WHITE, _('White')),
+ (fanchart.BACKGROUND_SCHEME1, _('Color scheme classic report')),
+ (fanchart.BACKGROUND_SCHEME2, _('Color scheme classic view')),
+ )
curval = self._config.get('interface.fanview-background')
nrval = 0
- for nr, val in backgrvals:
- if curval == nr:
+ for nbr, dummy_val in backgrvals:
+ if curval == nbr:
break
nrval += 1
- configdialog.add_combo(grid,
- _('Background'),
- 2, 'interface.fanview-background',
- backgrvals,
- callback=self.cb_update_background, valueactive=False, setactive=nrval
- )
+ configdialog.add_combo(grid, _('Background'),
+ 2, 'interface.fanview-background', backgrvals,
+ callback=self.cb_update_background,
+ valueactive=False, setactive=nrval)
#colors, stored as hex values
configdialog.add_color(grid, _('Start gradient/Main color'), 3,
- 'interface.color-start-grad', col=1)
+ 'interface.color-start-grad', col=1)
configdialog.add_color(grid, _('End gradient/2nd color'), 4,
- 'interface.color-end-grad', col=1)
+ 'interface.color-end-grad', col=1)
# form of the fan
configdialog.add_combo(grid, _('Fan chart type'), 5,
- 'interface.fanview-form',
- ((0, _('Full Circle')), (1,_('Half Circle')),
- (2, _('Quadrant'))),
- callback=self.cb_update_form)
+ 'interface.fanview-form',
+ ((0, _('Full Circle')), (1, _('Half Circle')),
+ (2, _('Quadrant'))),
+ callback=self.cb_update_form)
# show names one two line
- configdialog.add_checkbox(grid,
- _('Show names on two lines'),
- 6, 'interface.fanview-twolinename')
+ configdialog.add_checkbox(grid, _('Show names on two lines'),
+ 6, 'interface.fanview-twolinename')
# Flip names
- configdialog.add_checkbox(grid,
- _('Flip name on the left of the fan'),
- 7, 'interface.fanview-flipupsidedownname')
+ configdialog.add_checkbox(grid, _('Flip name on the left of the fan'),
+ 7, 'interface.fanview-flipupsidedownname')
# options users should not change:
- configdialog.add_checkbox(grid,
- _('Show children ring'),
- nrentry-1, 'interface.fanview-childrenring')
+ configdialog.add_checkbox(grid, _('Show children ring'),
+ nrentry-2, 'interface.fanview-childrenring')
+
+ # Show the gramps_id
+ configdialog.add_checkbox(grid, _('Show gramps id'),
+ nrentry-1, 'interface.fanview-showid')
# options we don't show on the dialog
##configdialog.add_checkbox(table,
## _('Allow radial text'),
@@ -427,33 +446,44 @@ class FanChartView(fanchart.FanChartGrampsGUI, NavigationView):
use it to monitor changes in the ini file
"""
self._config.connect('interface.fanview-childrenring',
- self.cb_update_childrenring)
+ self.cb_update_childrenring)
self._config.connect('interface.fanview-twolinename',
- self.cb_update_twolinename)
+ self.cb_update_twolinename)
self._config.connect('interface.fanview-flipupsidedownname',
- self.cb_update_flipupsidedownname)
+ self.cb_update_flipupsidedownname)
self._config.connect('interface.fanview-radialtext',
- self.cb_update_radialtext)
+ self.cb_update_radialtext)
+ self._config.connect('interface.fanview-showid',
+ self.cb_update_showid)
self._config.connect('interface.color-start-grad',
- self.cb_update_color)
+ self.cb_update_color)
self._config.connect('interface.color-end-grad',
- self.cb_update_color)
+ self.cb_update_color)
def cb_update_maxgen(self, spinbtn, constant):
+ """
+ The maximum generations in the fanchart
+ """
self.maxgen = spinbtn.get_value_as_int()
self._config.set(constant, self.maxgen)
self.update()
def cb_update_background(self, obj, constant):
+ """
+ Change the background
+ """
entry = obj.get_active()
Gtk.TreePath.new_from_string('%d' % entry)
val = int(obj.get_model().get_value(
- obj.get_model().get_iter_from_string('%d' % entry), 0))
+ obj.get_model().get_iter_from_string('%d' % entry), 0))
self._config.set(constant, val)
self.background = val
self.update()
def cb_update_form(self, obj, constant):
+ """
+ Update the fanchart form: CIRCLE, HALFCIRCLE or QUADRANT
+ """
entry = obj.get_active()
self._config.set(constant, entry)
self.form = entry
@@ -463,20 +493,21 @@ class FanChartView(fanchart.FanChartGrampsGUI, NavigationView):
"""
Called when the configuration menu changes the childrenring setting.
"""
- if entry == 'True':
- self.childring = True
- else:
- self.childring = False
+ self.childring = (entry == 'True')
self.update()
def cb_update_radialtext(self, client, cnxn_id, entry, data):
"""
Called when the configuration menu changes the childrenring setting.
"""
- if entry == 'True':
- self.radialtext = True
- else:
- self.radialtext = False
+ self.radialtext = (entry == 'True')
+ self.update()
+
+ def cb_update_showid(self, client, cnxn_id, entry, data):
+ """
+ Called when the configuration menu changes the showid setting.
+ """
+ self.showid = (entry == 'True')
self.update()
def cb_update_color(self, client, cnxn_id, entry, data):
@@ -496,12 +527,16 @@ class FanChartView(fanchart.FanChartGrampsGUI, NavigationView):
def cb_update_flipupsidedownname(self, client, cnxn_id, entry, data):
"""
- Called when the configuration menu changes the flipupsidedownname setting.
+ Called when the configuration menu changes the
+ flipupsidedownname setting.
"""
self.flipupsidedownname = (entry == 'True')
self.update()
def cb_update_font(self, obj, constant):
+ """
+ Change the font
+ """
entry = obj.get_active()
self._config.set(constant, self.allfonts[entry][1])
self.fonttype = self.allfonts[entry][1]
@@ -536,6 +571,8 @@ class CairoPrintSave:
self.heightpx = heightpx
self.drawfunc = drawfunc
self.parent = parent
+ self.preview = None
+ self.previewopr = None
def run(self):
"""Create the physical output from the meta document.
@@ -569,7 +606,8 @@ class CairoPrintSave:
# run print dialog
while True:
self.preview = None
- res = operation.run(Gtk.PrintOperationAction.PRINT_DIALOG, self.parent)
+ res = operation.run(Gtk.PrintOperationAction.PRINT_DIALOG,
+ self.parent)
if self.preview is None: # cancel or print
break
# set up printing again; can't reuse PrintOperation?
@@ -589,20 +627,24 @@ class CairoPrintSave:
def on_draw_page(self, operation, context, page_nr):
"""Draw a page on a Cairo context.
"""
- cr = context.get_cairo_context()
+ dummy_operation = operation
+ dummy_page_nr = page_nr
+ ctx = context.get_cairo_context()
pxwidth = round(context.get_width())
pxheight = round(context.get_height())
scale = min(pxwidth/self.widthpx, pxheight/self.heightpx)
- self.drawfunc(None, cr, scale=scale)
+ self.drawfunc(None, ctx, scale=scale)
def on_paginate(self, operation, context):
"""Paginate the whole document in chunks.
We don't need this as there is only one page, however,
we provide a dummy holder here, because on_preview crashes if no
- default application is set with gir 3.3.2 (typically evince not installed)!
+ default application is set with gir 3.3.2
+ (typically evince not installed)!
It will provide the start of the preview dialog, which cannot be
started in on_preview
"""
+ dummy_context = context
finished = True
# update page number
operation.set_n_pages(1)
@@ -616,13 +658,15 @@ class CairoPrintSave:
def on_preview(self, operation, preview, context, parent):
"""Implement custom print preview functionality.
We provide a dummy holder here, because on_preview crashes if no
- default application is set with gir 3.3.2 (typically evince not installed)!
+ default application is set with gir 3.3.2
+ (typically evince not installed)!
"""
+ dummy_preview = preview
dlg = Gtk.MessageDialog(parent,
- flags=Gtk.DialogFlags.MODAL,
- type=Gtk.MessageType.WARNING,
- buttons=Gtk.ButtonsType.CLOSE,
- message_format=_('No preview available'))
+ flags=Gtk.DialogFlags.MODAL,
+ type=Gtk.MessageType.WARNING,
+ buttons=Gtk.ButtonsType.CLOSE,
+ message_format=_('No preview available'))
self.preview = dlg
self.previewopr = operation
#dlg.format_secondary_markup(msg2)
@@ -639,11 +683,16 @@ class CairoPrintSave:
except ValueError:
height = 0
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)
- cr = cairo.Context(surface)
- context.set_cairo_context(cr, 72.0, 72.0)
+ ctx = cairo.Context(surface)
+ context.set_cairo_context(ctx, 72.0, 72.0)
return True
def previewdestroy(self, dlg, res):
+ """
+ Destroy the preview page
+ """
+ dummy_dlg = dlg
+ dummy_res = res
self.preview.destroy()
self.previewopr.end_preview()