Symbols enhancement

* Add the possibility to set all default value to a string.
* Gui configuration improvement.
* Possibility to drag and drop a symbol from the symbol list.  In this case, the glyph must be present in the current font to be displayed.
* Replace death symbol by buried, cremated or killed symbol depending on the event type.
This commit is contained in:
Serge Noiraud 2022-02-23 20:24:22 +01:00 committed by GitHub
parent 2393c4bb41
commit 84da4b896b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 381 additions and 418 deletions

View File

@ -313,9 +313,18 @@ register('plugin.hiddenplugins', [])
register('plugin.addonplugins', [])
register('utf8.in-use', False)
register('utf8.available-fonts', [])
register('utf8.selected-font', "")
register('utf8.death-symbol', 13)
register('utf8.selected-font', '')
register('utf8.death-symbol', 2)
register('utf8.birth-symbol', "*")
register('utf8.baptism-symbol', "~")
register('utf8.marriage-symbol', "oo")
register('utf8.engaged-symbol', "o")
register('utf8.divorce-symbol', "o|o")
register('utf8.partner-symbol', "o-o")
register('utf8.dead-symbol', "")
register('utf8.buried-symbol', "[]")
register('utf8.cremated-symbol', "")
register('utf8.killed-symbol', "x")
if __debug__: # enable a simple CLI test to see if the datestrings exist
register('test.january', _("|January", "localized lexeme inflections"))

View File

@ -35,13 +35,13 @@ from html import escape
# Gramps modules
#
#-------------------------------------------------------------------------
from gramps.gen.utils.symbols import Symbols
from ..lib import EventType
from ..datehandler import get_date
from ..display.name import displayer as name_displayer
from ..display.place import displayer as place_displayer
from .db import (get_birth_or_fallback, get_death_or_fallback,
get_marriage_or_fallback)
from gramps.gen.utils.symbols import Symbols
#-------------------------------------------------------------------------
#
@ -57,24 +57,26 @@ class FormattingHelper:
self.uistate = uistate
self._text_cache = {}
self._markup_cache = {}
self.symbols = Symbols()
self.reload_symbols()
def reload_symbols(self):
self.symbols = Symbols()
self.clear_cache()
if self.uistate and self.uistate.symbols:
death_idx = self.uistate.death_symbol
self.male = self.symbols.get_symbol_for_string(self.symbols.SYMBOL_MALE)
self.female = self.symbols.get_symbol_for_string(self.symbols.SYMBOL_FEMALE)
self.bth = self.symbols.get_symbol_for_string(self.symbols.SYMBOL_BIRTH)
self.marr = self.symbols.get_symbol_for_string(self.symbols.SYMBOL_MARRIAGE)
gsfs = self.symbols.get_symbol_for_string
self.male = gsfs(self.symbols.SYMBOL_MALE)
self.female = gsfs(self.symbols.SYMBOL_FEMALE)
self.bth = gsfs(self.symbols.SYMBOL_BIRTH)
self.marr = gsfs(self.symbols.SYMBOL_MARRIAGE)
self.dth = self.symbols.get_death_symbol_for_char(death_idx)
else:
death_idx = self.symbols.DEATH_SYMBOL_LATIN_CROSS
self.male = self.symbols.get_symbol_fallback(self.symbols.SYMBOL_MALE)
self.female = self.symbols.get_symbol_fallback(self.symbols.SYMBOL_FEMALE)
self.marr = self.symbols.get_symbol_fallback(self.symbols.SYMBOL_MARRIAGE)
self.bth = self.symbols.get_symbol_fallback(self.symbols.SYMBOL_BIRTH)
gsf = self.symbols.get_symbol_fallback
self.male = gsf(self.symbols.SYMBOL_MALE)
self.female = gsf(self.symbols.SYMBOL_FEMALE)
self.marr = gsf(self.symbols.SYMBOL_MARRIAGE)
self.bth = gsf(self.symbols.SYMBOL_BIRTH)
self.dth = self.symbols.get_death_symbol_fallback(death_idx)
def format_relation(self, family, line_count, use_markup=False):
@ -149,7 +151,7 @@ class FormattingHelper:
text = place_title
return text
def format_person( self, person, line_count, use_markup=False):
def format_person(self, person, line_count, use_markup=False):
"""fromat how info about a person should be presented
"""
if not person:
@ -212,7 +214,7 @@ class FormattingHelper:
self._text_cache[person.handle][line_count] = text
return text
def clear_cache( self):
def clear_cache(self):
"""clear the cache of kept format strings
"""
self._text_cache = {}

View File

@ -27,6 +27,8 @@
#
#-------------------------------------------------------------------------
from gramps.gen.const import GRAMPS_LOCALE as glocale
from gramps.gen.config import config
_ = glocale.translation.sgettext
# pylint: disable=superfluous-parens
@ -43,7 +45,6 @@ class Symbols(object):
SYMBOL_HERMAPHRODITE = 6
SYMBOL_TRANSGENDER = 7
SYMBOL_NEUTER = 8
SYMBOL_ILLEGITIM = 9
SYMBOL_BIRTH = 10
SYMBOL_BAPTISM = 11 # CHRISTENING
@ -56,31 +57,6 @@ class Symbols(object):
SYMBOL_KILLED_IN_ACTION = 18
SYMBOL_EXTINCT = 19
all_symbols = [
# Name UNICODE SUBSTITUTION
(_("Female"), '\u2640', ""),
(_("Male"), '\u2642', ""),
(_("Asexuality, sexless, genderless"), '\u26aa', ""),
(_("Lesbianism"), '\u26a2', "oo"),
(_("Male homosexuality"), '\u26a3', "oo"),
(_("Heterosexuality"), '\u26a4', "oo"),
(_("Transgender, hermaphrodite (in entomology)"), '\u26a5', ""),
(_("Transgender"), '\u26a6', ""),
(_("Neuter"), '\u26b2', ""),
(_("Illegitimate"), '\u229b', ""),
(_("Birth"), '\u002a', "*"),
(_("Baptism/Christening"), '\u007e', "~"),
(_("Engaged"), '\u26ac', "o"),
(_("Marriage"), '\u26ad', "oo"),
(_("Divorce"), '\u26ae', "o|o"),
(_("Unmarried partnership"), '\u26af', "o-o"),
(_("Buried"), '\u26b0', "d"),
(_("Cremated/Funeral urn"), '\u26b1', "d"),
(_("Killed in action"), '\u2694', "d"),
(_("Extinct"), '\u2021', ""),
]
# genealogical death symbols
DEATH_SYMBOL_NONE = 0
DEATH_SYMBOL_X = 1
@ -100,30 +76,67 @@ class Symbols(object):
DEATH_SYMBOL_STAR_OF_DAVID = 15
DEATH_SYMBOL_DEAD = 16
# The following is used in the global preferences in the display tab.
# Name
# UNICODE SUBSTITUTION
death_symbols = [(_("Nothing"), "", ""),
("x", "x", "x"),
(_("Skull and crossbones"), "\u2620", "+"),
(_("Ankh"), "\u2625", "+"),
(_("Orthodox cross"), "\u2626", "+"),
(_("Chi rho"), "\u2627", "+"),
(_("Cross of Lorraine"), "\u2628", "+"),
(_("Cross of Jerusalem"), "\u2629", "+"),
(_("Star and crescent"), "\u262a", "+"),
(_("West Syriac cross"), "\u2670", "+"),
(_("East Syriac cross"), "\u2671", "+"),
(_("Heavy Greek cross"), "\u271a", "+"),
(_("Latin cross"), "\u271d", "+"),
(_("Shadowed White Latin cross"), "\u271e", "+"),
(_("Maltese cross"), "\u2720", "+"),
(_("Star of David"), "\u2721", "+"),
(_("Dead"), _("Dead"), _("Dead"))
]
def __init__(self):
self.symbols = None
self.all_symbols = [
# Name UNICODE SUBSTITUTION
(_("Female"), '\u2640', ""),
(_("Male"), '\u2642', ""),
(_("Asexuality, sexless, genderless"), '\u26aa', ""),
(_("Lesbianism"), '\u26a2', ""),
(_("Male homosexuality"), '\u26a3', ""),
(_("Heterosexuality"), '\u26a4', ""),
(_("Transgender, hermaphrodite (in entomology)"), '\u26a5', ""),
(_("Transgender"), '\u26a6', ""),
(_("Neuter"), '\u26b2', ""),
(_("Illegitimate"), '\u229b', ""),
(_("Birth"), '\u002a', config.get('utf8.birth-symbol')),
(_("Baptism/Christening"), '\u007e',
config.get('utf8.baptism-symbol')),
(_("Engaged"), '\u26ac', config.get('utf8.engaged-symbol')),
(_("Marriage"), '\u26ad', config.get('utf8.marriage-symbol')),
(_("Divorce"), '\u26ae', config.get('utf8.divorce-symbol')),
(_("Unmarried partnership"), '\u26af',
config.get('utf8.partner-symbol')),
(_("Buried"), '\u26b0', config.get('utf8.buried-symbol')),
(_("Cremated/Funeral urn"), '\u26b1',
config.get('utf8.cremated-symbol')),
(_("Killed in action"), '\u2694', config.get('utf8.killed-symbol')),
(_("Extinct"), '\u2021', "")]
# The following is used in the global preferences in the display tab.
# Name UNICODE SUBSTITUTION
self.death_symbols = [(_("Nothing"), "", ""),
("x", "x", "x"),
(_("Skull and crossbones"), "\u2620",
config.get('utf8.dead-symbol')),
(_("Ankh"), "\u2625",
config.get('utf8.dead-symbol')),
(_("Orthodox cross"), "\u2626",
config.get('utf8.dead-symbol')),
(_("Chi rho"), "\u2627",
config.get('utf8.dead-symbol')),
(_("Cross of Lorraine"), "\u2628",
config.get('utf8.dead-symbol')),
(_("Cross of Jerusalem"), "\u2629",
config.get('utf8.dead-symbol')),
(_("Star and crescent"), "\u262a",
config.get('utf8.dead-symbol')),
(_("West Syriac cross"), "\u2670",
config.get('utf8.dead-symbol')),
(_("East Syriac cross"), "\u2671",
config.get('utf8.dead-symbol')),
(_("Heavy Greek cross"), "\u271a",
config.get('utf8.dead-symbol')),
(_("Latin cross"), "\u271d",
config.get('utf8.dead-symbol')),
(_("Shadowed White Latin cross"), "\u271e",
config.get('utf8.dead-symbol')),
(_("Maltese cross"), "\u2720",
config.get('utf8.dead-symbol')),
(_("Star of David"), "\u2721",
config.get('utf8.dead-symbol')),
(_("Dead"), ("Dead"), _("Dead"))]
#
# functions for general symbols
#

View File

@ -410,7 +410,7 @@ class ConfigureDialog(ManagedWindow):
if not callback:
callback = self.update_entry
if label:
lwidget = BasicLabel(_("%s: ") % label) # Translators: for French
lwidget = BasicLabel(_("%s: ") % label) # translators: for French
entry = Gtk.Entry()
if localized_config:
entry.set_text(config.get(constant))
@ -709,7 +709,7 @@ class GrampsPreferences(ConfigureDialog):
hbox.pack_start(lwidget, False, False, 0)
hbox.pack_start(self.color_scheme_box, False, False, 0)
restore_btn = Gtk.Button(label=_('Restore to defaults'))
restore_btn = Gtk.Button(_('Restore to defaults'))
restore_btn.set_tooltip_text(
_('Restore colors for current theme to default.'))
restore_btn.connect('clicked', self.restore_colors)
@ -865,19 +865,19 @@ class GrampsPreferences(ConfigureDialog):
_("Common")),
"%s, %s %s (%s)" % (_("Surname"), _("Given"), _("Suffix"),
_("Nickname")),
"%s, %s %s (%s)" % (_("Surname"), _("Common", "Name"), _("Suffix"),
"%s, %s %s (%s)" % (_("Surname"), _("Name|Common"), _("Suffix"),
_("Nickname")),
"%s, %s %s" % (_("Surname"), _("Common", "Name"), _("Suffix")),
"%s, %s %s" % (_("Surname"), _("Name|Common"), _("Suffix")),
"%s, %s %s (%s)" % (_("SURNAME"), _("Given"), _("Suffix"),
_("Call")),
"%s, %s (%s)" % (_("Surname"), _("Given"), _("Common", "Name")),
"%s, %s (%s)" % (_("Surname"), _("Common", "Name"), _("Nickname")),
"%s, %s (%s)" % (_("Surname"), _("Given"), _("Name|Common")),
"%s, %s (%s)" % (_("Surname"), _("Name|Common"), _("Nickname")),
"%s %s" % (_("Given"), _("Surname")),
"%s %s, %s" % (_("Given"), _("Surname"), _("Suffix")),
"%s %s %s" % (_("Given"), _("NotPatronymic"), _("Patronymic")),
"%s, %s %s (%s)" % (_("SURNAME"), _("Given"), _("Suffix"),
_("Common")),
"%s, %s (%s)" % (_("SURNAME"), _("Given"), _("Common", "Name")),
"%s, %s (%s)" % (_("SURNAME"), _("Given"), _("Name|Common")),
"%s, %s (%s)" % (_("SURNAME"), _("Given"), _("Nickname")),
"%s %s" % (_("Given"), _("SURNAME")),
"%s %s, %s" % (_("Given"), _("SURNAME"), _("Suffix")),
@ -1849,9 +1849,7 @@ class GrampsPreferences(ConfigureDialog):
formats = [_("Never"),
_("Every 15 minutes"),
_("Every 30 minutes"),
_("Every hour"),
_("Every 12 hours"),
_("Every day")]
_("Every hour")]
list(map(obox.append_text, formats))
active = config.get('database.autobackup')
obox.set_active(active)
@ -1949,8 +1947,6 @@ class GrampsPreferences(ConfigureDialog):
for plugin in sorted(backend_plugins, key=lambda plugin: plugin.name):
if plugin.id == default:
active = count
if plugin.id == 'bsddb':
continue # bsddb is deprecated, so don't allow setting
model.append(row=[count, plugin.name, plugin.id])
count += 1
obox.set_model(model)
@ -1970,10 +1966,12 @@ class GrampsPreferences(ConfigureDialog):
Show dialog to choose media directory.
"""
f = Gtk.FileChooserDialog(title=_("Select media directory"),
transient_for=self.window,
action=Gtk.FileChooserAction.SELECT_FOLDER)
f.add_buttons(_('_Cancel'), Gtk.ResponseType.CANCEL,
_('_Apply'), Gtk.ResponseType.OK)
parent=self.window,
action=Gtk.FileChooserAction.SELECT_FOLDER,
buttons=(_('_Cancel'),
Gtk.ResponseType.CANCEL,
_('_Apply'),
Gtk.ResponseType.OK))
mpath = media_path(self.dbstate.db)
f.set_current_folder(os.path.dirname(mpath))
@ -2018,10 +2016,12 @@ class GrampsPreferences(ConfigureDialog):
Show dialog to choose backup directory.
"""
f = Gtk.FileChooserDialog(title=_("Select backup directory"),
transient_for=self.window,
action=Gtk.FileChooserAction.SELECT_FOLDER)
f.add_buttons(_('_Cancel'), Gtk.ResponseType.CANCEL,
_('_Apply'), Gtk.ResponseType.OK)
parent=self.window,
action=Gtk.FileChooserAction.SELECT_FOLDER,
buttons=(_('_Cancel'),
Gtk.ResponseType.CANCEL,
_('_Apply'),
Gtk.ResponseType.OK))
backup_path = config.get('database.backup-path')
if not backup_path:
backup_path = config.get('database.path')
@ -2081,253 +2081,194 @@ class GrampsPreferences(ConfigureDialog):
self.grid.set_border_width(12)
self.grid.set_column_spacing(6)
self.grid.set_row_spacing(6)
self.combo = None
self.choosefont = None
self.symbols_grid = self.create_grid()
message = _('This tab gives you the possibility to use one font'
' which is able to show all genealogical symbols\n\n'
'If you select the "use symbols" checkbox, '
'Gramps will use the selected font if it exists.'
message = _('If checked, use the standard genealogic symbols (death '
'symbol is user selectable).\n'
'If not checked, you can use the lower panel to customize '
'the symbols yourself.'
)
message += '\n'
message += '\n\n'
message += _('This can be useful if you want to add phonetic in '
'a note to show how to pronounce a name or if you mix'
' multiple languages like greek and russian.'
)
self.add_text(self.grid, message,
0, line_wrap=True)
self.add_checkbox(self.grid,
_('Use symbols'),
1,
'utf8.in-use',
extra_callback=self.activate_change_font
)
message = _('Be careful, if you click on the "Try to find" button, it can '
'take a while before you can continue (10 minutes or more). '
'\nIf you cancel the process, nothing will be changed.'
)
self.add_text(self.grid, message,
2, line_wrap=True)
available_fonts = config.get('utf8.available-fonts')
self.all_avail_fonts = list(enumerate(available_fonts))
if len(available_fonts) > 0:
self.add_text(self.grid,
_('You have already run the tool to search for genealogy fonts.'
'\nRun it again only if you added fonts on your system.'
),
3, line_wrap=True)
self.add_button(self.grid,
_('Try to find'),
4,
'utf8.in-use',
extra_callback=self.can_we_use_genealogical_fonts)
sel_font = config.get('utf8.selected-font')
if len(available_fonts) > 0:
try:
active_val = available_fonts.index(sel_font)
except:
active_val = 0
self.add_combo(self.grid,
_('Choose font'),
5, 'utf8.selected-font',
self.all_avail_fonts,
callback=self.utf8_update_font,
valueactive=True, setactive=active_val)
self.add_checkbox(self.grid, _('Use symbols'), 0, 'utf8.in-use',
extra_callback=self.activate_change_font,
tooltip=message)
symbols = Symbols()
all_sbls = symbols.get_death_symbols()
all_symbols = []
for symbol in all_sbls:
all_symbols.append(symbol[1] + " " + symbol[0])
self.all_death_symbols = list(enumerate(all_symbols))
pos = config.get('utf8.death-symbol')
combo = self.add_combo(self.grid,
self.combo = self.add_combo(self.grid,
_('Select default death symbol'),
6, 'utf8.death-symbol',
4, 'utf8.death-symbol',
self.all_death_symbols,
callback=self.utf8_update_death_symbol,
valueactive=True, setactive='')
combo.set_active(pos)
if config.get('utf8.selected-font') != "":
valueactive=False)
self.utf8_show_example()
self.show_default_symbols()
return _('Symbols'), self.grid
return _('Genealogical Symbols'), self.grid
def can_we_use_genealogical_fonts(self, obj):
try:
import fontconfig
from gramps.gui.utils import ProgressMeter
from collections import defaultdict
except:
from gramps.gui.dialog import WarningDialog
WarningDialog(_("Cannot look for genealogical fonts"),
_("I am not able to select genealogical fonts. "
"Please, install the module fontconfig for python 3."),
parent=self.uistate.window)
return False
def activate_change_font(self, obj=None):
self.uistate.reload_symbols()
self.show_default_symbols()
self.uistate.emit('font-changed')
def utf8_show_example(self):
try:
# remove the old messages with old font
self.grid.remove_row(8)
self.grid.remove_row(7)
self.grid.remove_row(6)
self.grid.remove_row(5)
except:
pass
fonts = fontconfig.query()
all_fonts = defaultdict(set)
symbols = Symbols()
nb_symbols = symbols.get_how_many_symbols()
self.in_progress = True
self.progress = ProgressMeter(_('Checking available genealogical fonts'),
can_cancel=True,
cancel_callback=self.stop_looking_for_font,
parent=self.uistate.window)
self.progress.set_pass(_('Looking for all fonts with genealogical symbols.'), nb_symbols*len(fonts))
for path in fonts:
if not self.in_progress:
return # We clicked on Cancel
font = fontconfig.FcFont(path)
local = get_env_var('LANGUAGE', 'en')
if isinstance(font.family, list):
fontname = None
for lang,fam in font.family:
if lang == local:
fontname = fam
if not fontname:
fontname = font.family[0][1]
else:
if local in font.family:
fontname = font.family[local]
else:
for lang, name in font.family: # version 0.6.0 use dict
fontname = name
break
for rand in range(symbols.SYMBOL_MALE, symbols.SYMBOL_EXTINCT+1):
string = symbols.get_symbol_for_html(rand)
value = symbols.get_symbol_for_string(rand)
if font.has_char(value):
all_fonts[fontname].add(value)
self.progress.step()
for rand in range(symbols.DEATH_SYMBOL_SKULL,
symbols.DEATH_SYMBOL_DEAD):
value = symbols.get_death_symbol_for_char(rand)
if font.has_char(value):
all_fonts[fontname].add(value)
self.progress.step()
self.progress.close()
available_fonts = []
for font, font_usage in all_fonts.items():
if not font_usage:
continue
if len(font_usage) == nb_symbols: # If the font use all symbols
available_fonts.append(font)
config.set('utf8.available-fonts', available_fonts)
sel_font = config.get('utf8.selected-font')
try:
active_val = available_fonts.index(sel_font)
except:
active_val = 0
if len(available_fonts) > 0:
self.all_avail_fonts = list(enumerate(available_fonts))
choosefont = self.add_combo(self.grid,
_('Choose font'),
5, 'utf8.selected-font',
self.all_avail_fonts, callback=self.utf8_update_font,
valueactive=True, setactive=active_val)
if len(available_fonts) == 1:
single_font = self.all_avail_fonts[choosefont.get_active()][0]
config.set('utf8.selected-font',
self.all_avail_fonts[single_font][1])
self.utf8_show_example()
symbols = Symbols()
all_sbls = symbols.get_death_symbols()
all_symbols = []
for symbol in all_sbls:
all_symbols.append(symbol[1] + " " + symbol[0])
self.all_death_symbols = list(enumerate(all_symbols))
pos = config.get('utf8.death-symbol')
combo = self.add_combo(self.grid,
_('Select default death symbol'),
6, 'utf8.death-symbol',
self.all_death_symbols,
callback=self.utf8_update_death_symbol,
valueactive=True, setactive='')
combo.set_active(pos)
else:
self.add_text(self.grid,
_('You have no font with genealogical symbols on your '
'system. Gramps will not be able to use symbols.'
),
6, line_wrap=True)
config.set('utf8.selected-font',"")
self.grid.show_all()
self.in_progress = False
def utf8_update_font(self, obj, constant):
entry = obj.get_active()
config.set(constant, self.all_avail_fonts[entry][1])
self.utf8_show_example()
def activate_change_font(self, obj=None):
if obj:
if not obj.get_active():
# reset to the system default
self.uistate.viewmanager.reset_font()
font = config.get('utf8.selected-font')
if not self.uistate.viewmanager.change_font(font):
# We can't change the font, so reset the checkbox.
if obj:
obj.set_active(False)
self.uistate.reload_symbols()
self.uistate.emit('font-changed')
def utf8_show_example(self):
from gi.repository import Pango
from gramps.gen.utils.grampslocale import _LOCALE_NAMES as X
from string import ascii_letters
try:
# remove the old messages with old font
self.grid.remove_row(8)
self.grid.remove_row(7)
except:
pass
font = config.get('utf8.selected-font')
symbols = Symbols()
my_characters = _("What you will see") + " :\n"
my_characters += ascii_letters
my_characters += " àäâçùéèiïîêëiÉÀÈïÏËÄœŒÅåØøìòô ...\n"
for k,v in sorted(X.items()):
lang = Pango.Language.from_string(k)
my_characters += v[2] + ":\t" + lang.get_sample_string() + "\n"
scrollw = Gtk.ScrolledWindow()
scrollw.set_size_request(600, 100)
text = Gtk.Label()
text.set_line_wrap(True)
self.activate_change_font()
text.set_halign(Gtk.Align.START)
text.set_markup("<span font='%s'>%s</span>" % (font, my_characters))
scrollw.add(text)
scrollw.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
self.grid.attach(scrollw, 1, 7, 8, 1)
my_characters = ""
for idx in range(symbols.SYMBOL_FEMALE, symbols.SYMBOL_EXTINCT+1):
my_characters += symbols.get_symbol_for_string(idx) + " "
self.sym_buf = Gtk.TextBuffer()
self.sym_text = Gtk.TextView.new_with_buffer(self.sym_buf)
self.sym_text.set_has_tooltip(True)
self.sym_text.props.halign = Gtk.Align.START
self.sym_text.connect("query_tooltip", self.sym_tooltip)
for (tooltip, text, _tsym) in symbols.all_symbols:
text = ' ' + text + ' '
tag = self.sym_buf.create_tag(tag_name=tooltip, font=font,
size_points=16.0)
_iter = self.sym_buf.get_end_iter()
self.sym_buf.insert_with_tags(_iter, text, tag)
death_symbl = config.get('utf8.death-symbol')
my_characters += symbols.get_death_symbol_for_char(death_symbl)
text = Gtk.Label()
text.set_line_wrap(True)
text.set_halign(Gtk.Align.START)
text.set_markup("<big><big><big><big><span font='%s'>%s</span>"
"</big></big></big></big>" % (font, my_characters))
self.grid.attach(text, 1, 8, 8, 1)
scrollw.show_all()
text.show_all()
text = ' ' + symbols.get_death_symbol_for_char(death_symbl) + ' '
tooltip = (_("Death:") + '\n' +
symbols.get_death_symbol_name(death_symbl))
tag = self.sym_buf.create_tag(tag_name=tooltip, font=font,
size_points=14.0)
_iter = self.sym_buf.get_end_iter()
self.sym_buf.insert_with_tags(_iter, text, tag)
self.sym_text.set_editable(False)
self.grid.attach(self.sym_text, 1, 6, 8, 1)
self.sym_text.show()
self.show_default_symbols()
def stop_looking_for_font(self, *args, **kwargs):
self.progress.close()
self.in_progress = False
def sym_tooltip(self, widget, w_x, w_y, key_mode, tooltip):
""" show a tooltip for each genealogic symbol """
if key_mode:
offset = self.sym_buf.props.cursor_position
iter_ = self.sym_buf.get_iter_at_offset(offset)
else:
# x. y are valid
b_x, b_y = self.sym_text.window_to_buffer_coords(
Gtk.TextWindowType.TEXT, w_x, w_y)
iter_ = self.sym_text.get_iter_at_position(b_x, b_y)
if isinstance(iter_, tuple):
iter_ = iter_.iter
tags = iter_.get_tags()
if tags:
tooltip.set_text(tags[0].props.name)
return True # if tooltip is to be shown
return False
def utf8_update_death_symbol(self, obj, constant):
entry = obj.get_active()
config.set(constant, entry)
self.utf8_show_example()
self.uistate.emit('font-changed')
def symbol_value_change(self, obj, constant):
entry = obj.get_text()
config.set(constant, entry)
idx = 0
for symbol in self.symbols:
if obj == self.symbols[symbol]:
self.set_substitution_symbol(self.symbol_list[idx][1], entry)
idx += 1
def reset_substitution_symbol(self, *args):
""" reset the substitution symbol to the default """
self.set_substitution_symbol('utf8.birth-symbol', "*")
self.set_substitution_symbol('utf8.baptism-symbol', "~")
self.set_substitution_symbol('utf8.marriage-symbol', "oo")
self.set_substitution_symbol('utf8.engaged-symbol', "o")
self.set_substitution_symbol('utf8.divorce-symbol', "o|o")
self.set_substitution_symbol('utf8.partner-symbol', "o-o")
self.set_substitution_symbol('utf8.dead-symbol', "")
self.set_substitution_symbol('utf8.buried-symbol', "[]")
self.set_substitution_symbol('utf8.cremated-symbol', "")
self.set_substitution_symbol('utf8.killed-symbol', "x")
self.show_default_symbols()
def show_default_symbols(self):
# prepare scrolled window for symbols
try:
self.grid.remove_row(7)
self.symbols_grid.remove_row(5)
self.symbols_grid.remove_row(4)
self.symbols_grid.remove_row(3)
self.symbols_grid.remove_row(2)
self.symbols_grid.remove_row(1)
self.symbols_grid.remove_row(0)
except:
pass
scroll_window = Gtk.ScrolledWindow()
scroll_window.add(self.symbols_grid)
scroll_window.set_vexpand(True)
scroll_window.set_policy(Gtk.PolicyType.NEVER,
Gtk.PolicyType.AUTOMATIC)
self.grid.attach(scroll_window, 0, 7, 5, 1)
if self.symbols_grid and self.uistate.symbols:
self.symbols_grid.set_sensitive(False)
else:
self.symbols_grid.set_sensitive(True)
self.symbol_list = [
(_("Birth"), 'utf8.birth-symbol', 1, 1),
(_("Baptism"), 'utf8.baptism-symbol', 1, 3),
(_("Engaged"), 'utf8.engaged-symbol', 2, 1),
(_("Marriage"), 'utf8.marriage-symbol', 2, 3),
(_("Partner"), 'utf8.partner-symbol', 3, 1),
(_("Divorce"), 'utf8.divorce-symbol', 3, 3),
(_("Death"), 'utf8.dead-symbol', 4, 1),
(_("Killed"), 'utf8.killed-symbol', 4, 3),
(_("Buried"), 'utf8.buried-symbol', 5, 1),
(_("Cremated/Funeral urn"), 'utf8.cremated-symbol', 5, 3),
]
symbol_title = _('Default genealogy symbols replacement')
symbol_label = Gtk.Label()
symbol_label.set_halign(Gtk.Align.START)
symbol_label.set_markup(_('<b>%s</b>') % symbol_title)
self.symbols_grid.attach(symbol_label, 0, 0, 3, 1)
symbol_reset = _('Restore to defaults')
button = Gtk.Button(label=symbol_reset)
button.connect('clicked', self.reset_substitution_symbol)
self.symbols_grid.attach(button, 4, 0, 4, 1)
symbol_tooltip = _('You can set any text you want for this field.'
'\nYou can drag and drop a symbol from the symbol '
'list above.\nIt will be visible only if your font '
'contains this glyph.'
)
# add symbols values to scrolled window
self.symbols = {}
for symbol in self.symbol_list:
self.symbols[symbol[0]] = entry = self.add_entry(
self.symbols_grid, symbol[0], symbol[2], symbol[1],
self.symbol_value_change, col_attach=symbol[3])
entry.set_tooltip_text(symbol_tooltip)
entry.set_max_width_chars(12)
entry.set_width_chars(12)
entry.set_halign(Gtk.Align.START)
scroll_window.show_all()
def set_substitution_symbol(self, symbol, value):
""" set the substitution symbol to string """
config.set(symbol, value)
self.uistate.emit('font-changed')

View File

@ -199,16 +199,18 @@ class FanChartBaseWidget(Gtk.DrawingArea):
self.gradcol = None
self.in_drag = False
self._mouse_click_cell_address = None
self.symbols = Symbols()
self.reload_symbols()
def reload_symbols(self):
self.symbols = Symbols()
dth_idx = self.uistate.death_symbol
if self.uistate.symbols:
self.bth = self.symbols.get_symbol_for_string(self.symbols.SYMBOL_BIRTH)
self.bth = self.symbols.get_symbol_for_string(
self.symbols.SYMBOL_BIRTH)
self.dth = self.symbols.get_death_symbol_for_char(dth_idx)
else:
self.bth = self.symbols.get_symbol_fallback(self.symbols.SYMBOL_BIRTH)
self.bth = self.symbols.get_symbol_fallback(
self.symbols.SYMBOL_BIRTH)
self.dth = self.symbols.get_death_symbol_fallback(dth_idx)
def reset(self):

View File

@ -577,12 +577,15 @@ class PedigreeView(NavigationView):
self.uistate.connect('font-changed', self.reload_symbols)
def reload_symbols(self):
self.symbols = Symbols()
dth_idx = self.uistate.death_symbol
if self.uistate.symbols:
self.bth = self.symbols.get_symbol_for_string(self.symbols.SYMBOL_BIRTH)
self.bth = self.symbols.get_symbol_for_string(
self.symbols.SYMBOL_BIRTH)
self.dth = self.symbols.get_death_symbol_for_char(dth_idx)
else:
self.bth = self.symbols.get_symbol_fallback(self.symbols.SYMBOL_BIRTH)
self.bth = self.symbols.get_symbol_fallback(
self.symbols.SYMBOL_BIRTH)
self.dth = self.symbols.get_death_symbol_fallback(dth_idx)
def get_handle_from_gramps_id(self, gid):

View File

@ -128,10 +128,8 @@ class RelationshipView(NavigationView):
)
def __init__(self, pdata, dbstate, uistate, nav_group=0):
NavigationView.__init__(self, _('Relationships'),
pdata, dbstate, uistate,
PersonBookmarks,
nav_group)
NavigationView.__init__(self, _('Relationships'), pdata, dbstate,
uistate, PersonBookmarks, nav_group)
dbstate.connect('database-changed', self.change_db)
uistate.connect('nameformat-changed', self.build_tree)
@ -153,7 +151,6 @@ class RelationshipView(NavigationView):
self.theme = self._config.get('preferences.relation-display-theme')
self.toolbar_visible = config.get('interface.toolbar-on')
self.age_precision = config.get('preferences.age-display-precision')
self.symbols = Symbols()
self.reload_symbols()
def get_handle_from_gramps_id(self, gid):
@ -184,6 +181,7 @@ class RelationshipView(NavigationView):
self.callman.add_db_signal('person-delete', self.redraw)
def reload_symbols(self):
self.symbols = Symbols()
if self.uistate and self.uistate.symbols:
gsfs = self.symbols.get_symbol_for_string
self.male = gsfs(self.symbols.SYMBOL_MALE)
@ -657,7 +655,7 @@ class RelationshipView(NavigationView):
family_handle_list = person.get_parent_family_handle_list()
self.reorder_sensitive = len(family_handle_list)> 1
self.reorder_sensitive = len(family_handle_list) > 1
if family_handle_list:
for family_handle in family_handle_list:
@ -670,7 +668,7 @@ class RelationshipView(NavigationView):
family_handle_list = person.get_family_handle_list()
if not self.reorder_sensitive:
self.reorder_sensitive = len(family_handle_list)> 1
self.reorder_sensitive = len(family_handle_list) > 1
if family_handle_list:
for family_handle in family_handle_list:
@ -797,8 +795,7 @@ class RelationshipView(NavigationView):
1, 2, 1, 1)
deathwidget = widgets.BasicLabel(self.format_event(death))
deathwidget.set_selectable(True)
subgrid.attach(deathwidget,
2, 2, 1, 1)
subgrid.attach(deathwidget, 2, 2, 1, 1)
mbox = Gtk.Box()
mbox.add(grid)
@ -809,8 +806,7 @@ class RelationshipView(NavigationView):
mobj = self.dbstate.db.get_media_from_handle(image_list[0].ref)
if mobj and mobj.get_mime_type()[0:5] == "image":
pixbuf = get_thumbnail_image(
media_path_full(self.dbstate.db,
mobj.get_path()),
media_path_full(self.dbstate.db, mobj.get_path()),
rectangle=image_list[0].get_rectangle())
image = Gtk.Image()
image.set_from_pixbuf(pixbuf)
@ -914,11 +910,12 @@ class RelationshipView(NavigationView):
msg = ""
return msg
def write_label(self, title, family, is_parent, person = None):
def write_label(self, title, family, is_parent, person=None):
"""
Write a Family header row
Shows following elements:
(collapse/expand arrow, Parents/Family title label, Family gramps_id, and add-choose-edit-delete buttons)
(collapse/expand arrow, Parents/Family title label, Family gramps_id,
and add-choose-edit-delete buttons)
"""
msg = '<span style="italic" weight="heavy">%s</span>' % escape(title)
hbox = Gtk.Box()
@ -933,7 +930,7 @@ class RelationshipView(NavigationView):
arrow = widgets.ExpandCollapseArrow(False,
self.expand_collapse_press,
(person, family.handle))
else :
else:
arrow = Gtk.Arrow(arrow_type=Gtk.ArrowType.RIGHT,
shadow_type=Gtk.ShadowType.OUT)
hbox.pack_start(arrow, False, True, 0)
@ -1024,7 +1021,7 @@ class RelationshipView(NavigationView):
######################################################################
def write_parents(self, family_handle, person = None):
def write_parents(self, family_handle, person=None):
family = self.dbstate.db.get_family_from_handle(family_handle)
if not family:
return
@ -1044,16 +1041,16 @@ class RelationshipView(NavigationView):
childmsg = ngettext(" ({number_of} sibling)",
" ({number_of} siblings)", count
).format(number_of=count)
elif count == 1 :
elif count == 1:
gender = self.dbstate.db.get_person_from_handle(
child_list[0]).gender
if gender == Person.MALE :
if gender == Person.MALE:
childmsg = _(" (1 brother)")
elif gender == Person.FEMALE :
elif gender == Person.FEMALE:
childmsg = _(" (1 sister)")
else :
else:
childmsg = _(" (1 sibling)")
else :
else:
childmsg = _(" (only child)")
self.family = family
box = self.get_people_box(family.get_father_handle(),
@ -1099,16 +1096,16 @@ class RelationshipView(NavigationView):
childmsg = ngettext(" ({number_of} sibling)",
" ({number_of} siblings)", count
).format(number_of=count)
elif count == 1 :
elif count == 1:
gender = self.dbstate.db.get_person_from_handle(
child_list[0]).gender
if gender == Person.MALE :
if gender == Person.MALE:
childmsg = _(" (1 brother)")
elif gender == Person.FEMALE :
elif gender == Person.FEMALE:
childmsg = _(" (1 sister)")
else :
else:
childmsg = _(" (1 sibling)")
else :
else:
childmsg = _(" (only child)")
self.family = None
box = self.get_people_box(post_msg=childmsg)
@ -1513,7 +1510,7 @@ class RelationshipView(NavigationView):
else:
pname = None
dobj = None
value = { 'event_type' : ename, }
value = {'event_type' : ename}
if dobj:
if pname:
@ -1532,7 +1529,7 @@ class RelationshipView(NavigationView):
self.write_data(
vbox, '%(event_type)s' % value, start_col, stop_col)
def write_family(self, family_handle, person = None):
def write_family(self, family_handle, person=None):
family = self.dbstate.db.get_family_from_handle(family_handle)
if family is None:
from gramps.gui.dialog import WarningDialog
@ -1564,7 +1561,7 @@ class RelationshipView(NavigationView):
childmsg = ngettext(" ({number_of} child)",
" ({number_of} children)", count
).format(number_of=count)
else :
else:
childmsg = _(" (no children)")
self.family = family
box = self.get_people_box(handle, post_msg=childmsg)
@ -1610,7 +1607,7 @@ class RelationshipView(NavigationView):
childmsg = ngettext(" ({number_of} child)",
" ({number_of} children)", count
).format(number_of=count)
else :
else:
childmsg = _(" (no children)")
self.family = None
box = self.get_people_box(post_msg=childmsg)
@ -1868,11 +1865,9 @@ class RelationshipView(NavigationView):
grid.set_column_spacing(6)
grid.set_row_spacing(6)
configdialog.add_checkbox(grid,
_('Use shading'),
configdialog.add_checkbox(grid, _('Use shading'),
0, 'preferences.relation-shade')
configdialog.add_checkbox(grid,
_('Display edit buttons'),
configdialog.add_checkbox(grid, _('Display edit buttons'),
1, 'preferences.releditbtn')
checkbox = Gtk.CheckButton(label=_('View links as website links'))
theme = self._config.get('preferences.relation-display-theme')
@ -1890,11 +1885,9 @@ class RelationshipView(NavigationView):
grid.set_border_width(12)
grid.set_column_spacing(6)
grid.set_row_spacing(6)
configdialog.add_checkbox(grid,
_('Show Details'),
configdialog.add_checkbox(grid, _('Show Details'),
0, 'preferences.family-details')
configdialog.add_checkbox(grid,
_('Show Siblings'),
configdialog.add_checkbox(grid, _('Show Siblings'),
1, 'preferences.family-siblings')
return _('Content'), grid
@ -1926,7 +1919,7 @@ class RelationshipView(NavigationView):
# Function to return if person has children
#
#-------------------------------------------------------------------------
def has_children(db,p):
def has_children(db, p):
"""
Return if a person has children.
"""