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('plugin.addonplugins', [])
register('utf8.in-use', False) register('utf8.in-use', False)
register('utf8.available-fonts', []) register('utf8.selected-font', '')
register('utf8.selected-font', "") register('utf8.death-symbol', 2)
register('utf8.death-symbol', 13) 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 if __debug__: # enable a simple CLI test to see if the datestrings exist
register('test.january', _("|January", "localized lexeme inflections")) register('test.january', _("|January", "localized lexeme inflections"))

View File

@ -35,13 +35,13 @@ from html import escape
# Gramps modules # Gramps modules
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
from gramps.gen.utils.symbols import Symbols
from ..lib import EventType from ..lib import EventType
from ..datehandler import get_date from ..datehandler import get_date
from ..display.name import displayer as name_displayer from ..display.name import displayer as name_displayer
from ..display.place import displayer as place_displayer from ..display.place import displayer as place_displayer
from .db import (get_birth_or_fallback, get_death_or_fallback, from .db import (get_birth_or_fallback, get_death_or_fallback,
get_marriage_or_fallback) get_marriage_or_fallback)
from gramps.gen.utils.symbols import Symbols
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
@ -57,24 +57,26 @@ class FormattingHelper:
self.uistate = uistate self.uistate = uistate
self._text_cache = {} self._text_cache = {}
self._markup_cache = {} self._markup_cache = {}
self.symbols = Symbols()
self.reload_symbols() self.reload_symbols()
def reload_symbols(self): def reload_symbols(self):
self.symbols = Symbols()
self.clear_cache() self.clear_cache()
if self.uistate and self.uistate.symbols: if self.uistate and self.uistate.symbols:
death_idx = self.uistate.death_symbol death_idx = self.uistate.death_symbol
self.male = self.symbols.get_symbol_for_string(self.symbols.SYMBOL_MALE) gsfs = self.symbols.get_symbol_for_string
self.female = self.symbols.get_symbol_for_string(self.symbols.SYMBOL_FEMALE) self.male = gsfs(self.symbols.SYMBOL_MALE)
self.bth = self.symbols.get_symbol_for_string(self.symbols.SYMBOL_BIRTH) self.female = gsfs(self.symbols.SYMBOL_FEMALE)
self.marr = self.symbols.get_symbol_for_string(self.symbols.SYMBOL_MARRIAGE) 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) self.dth = self.symbols.get_death_symbol_for_char(death_idx)
else: else:
death_idx = self.symbols.DEATH_SYMBOL_LATIN_CROSS death_idx = self.symbols.DEATH_SYMBOL_LATIN_CROSS
self.male = self.symbols.get_symbol_fallback(self.symbols.SYMBOL_MALE) gsf = self.symbols.get_symbol_fallback
self.female = self.symbols.get_symbol_fallback(self.symbols.SYMBOL_FEMALE) self.male = gsf(self.symbols.SYMBOL_MALE)
self.marr = self.symbols.get_symbol_fallback(self.symbols.SYMBOL_MARRIAGE) self.female = gsf(self.symbols.SYMBOL_FEMALE)
self.bth = self.symbols.get_symbol_fallback(self.symbols.SYMBOL_BIRTH) self.marr = gsf(self.symbols.SYMBOL_MARRIAGE)
self.bth = gsf(self.symbols.SYMBOL_BIRTH)
self.dth = self.symbols.get_death_symbol_fallback(death_idx) self.dth = self.symbols.get_death_symbol_fallback(death_idx)
def format_relation(self, family, line_count, use_markup=False): def format_relation(self, family, line_count, use_markup=False):
@ -149,7 +151,7 @@ class FormattingHelper:
text = place_title text = place_title
return text 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 """fromat how info about a person should be presented
""" """
if not person: if not person:
@ -170,7 +172,7 @@ class FormattingHelper:
if birth and use_markup and birth.get_type() != EventType.BIRTH: if birth and use_markup and birth.get_type() != EventType.BIRTH:
bdate = "<i>%s</i>" % escape(get_date(birth)) bdate = "<i>%s</i>" % escape(get_date(birth))
bplace = "<i>%s</i>" % escape(self.get_place_name( bplace = "<i>%s</i>" % escape(self.get_place_name(
birth.get_place_handle())) birth.get_place_handle()))
elif birth and use_markup: elif birth and use_markup:
bdate = escape(get_date(birth)) bdate = escape(get_date(birth))
bplace = escape(self.get_place_name(birth.get_place_handle())) bplace = escape(self.get_place_name(birth.get_place_handle()))
@ -184,7 +186,7 @@ class FormattingHelper:
if death and use_markup and death.get_type() != EventType.DEATH: if death and use_markup and death.get_type() != EventType.DEATH:
ddate = "<i>%s</i>" % escape(get_date(death)) ddate = "<i>%s</i>" % escape(get_date(death))
dplace = "<i>%s</i>" % escape(self.get_place_name( dplace = "<i>%s</i>" % escape(self.get_place_name(
death.get_place_handle())) death.get_place_handle()))
elif death and use_markup: elif death and use_markup:
ddate = escape(get_date(death)) ddate = escape(get_date(death))
dplace = escape(self.get_place_name(death.get_place_handle())) dplace = escape(self.get_place_name(death.get_place_handle()))
@ -212,7 +214,7 @@ class FormattingHelper:
self._text_cache[person.handle][line_count] = text self._text_cache[person.handle][line_count] = text
return text return text
def clear_cache( self): def clear_cache(self):
"""clear the cache of kept format strings """clear the cache of kept format strings
""" """
self._text_cache = {} self._text_cache = {}

View File

@ -27,6 +27,8 @@
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
from gramps.gen.const import GRAMPS_LOCALE as glocale from gramps.gen.const import GRAMPS_LOCALE as glocale
from gramps.gen.config import config
_ = glocale.translation.sgettext _ = glocale.translation.sgettext
# pylint: disable=superfluous-parens # pylint: disable=superfluous-parens
@ -34,96 +36,107 @@ _ = glocale.translation.sgettext
class Symbols(object): class Symbols(object):
# genealogical symbols # genealogical symbols
SYMBOL_FEMALE = 0 SYMBOL_FEMALE = 0
SYMBOL_MALE = 1 SYMBOL_MALE = 1
SYMBOL_ASEXUAL_SEXLESS = 2 # Unknown SYMBOL_ASEXUAL_SEXLESS = 2 # Unknown
SYMBOL_LESBIAN = 3 SYMBOL_LESBIAN = 3
SYMBOL_MALE_HOMOSEXUAL = 4 SYMBOL_MALE_HOMOSEXUAL = 4
SYMBOL_HETEROSEXUAL = 5 SYMBOL_HETEROSEXUAL = 5
SYMBOL_HERMAPHRODITE = 6 SYMBOL_HERMAPHRODITE = 6
SYMBOL_TRANSGENDER = 7 SYMBOL_TRANSGENDER = 7
SYMBOL_NEUTER = 8 SYMBOL_NEUTER = 8
SYMBOL_ILLEGITIM = 9
SYMBOL_ILLEGITIM = 9 SYMBOL_BIRTH = 10
SYMBOL_BIRTH = 10 SYMBOL_BAPTISM = 11 # CHRISTENING
SYMBOL_BAPTISM = 11 # CHRISTENING SYMBOL_ENGAGED = 12
SYMBOL_ENGAGED = 12 SYMBOL_MARRIAGE = 13
SYMBOL_MARRIAGE = 13 SYMBOL_DIVORCE = 14
SYMBOL_DIVORCE = 14 SYMBOL_UNMARRIED_PARTNERSHIP = 15
SYMBOL_UNMARRIED_PARTNERSHIP = 15 SYMBOL_BURIED = 16
SYMBOL_BURIED = 16 SYMBOL_CREMATED = 17 # Funeral urn
SYMBOL_CREMATED = 17 # Funeral urn SYMBOL_KILLED_IN_ACTION = 18
SYMBOL_KILLED_IN_ACTION = 18 SYMBOL_EXTINCT = 19
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 # genealogical death symbols
DEATH_SYMBOL_NONE = 0 DEATH_SYMBOL_NONE = 0
DEATH_SYMBOL_X = 1 DEATH_SYMBOL_X = 1
DEATH_SYMBOL_SKULL = 2 DEATH_SYMBOL_SKULL = 2
DEATH_SYMBOL_ANKH = 3 DEATH_SYMBOL_ANKH = 3
DEATH_SYMBOL_ORTHODOX_CROSS = 4 DEATH_SYMBOL_ORTHODOX_CROSS = 4
DEATH_SYMBOL_CHI_RHO = 5 DEATH_SYMBOL_CHI_RHO = 5
DEATH_SYMBOL_LORRAINE_CROSS = 6 DEATH_SYMBOL_LORRAINE_CROSS = 6
DEATH_SYMBOL_JERUSALEM_CROSS = 7 DEATH_SYMBOL_JERUSALEM_CROSS = 7
DEATH_SYMBOL_STAR_CRESCENT = 8 DEATH_SYMBOL_STAR_CRESCENT = 8
DEATH_SYMBOL_WEST_SYRIAC_CROSS = 9 DEATH_SYMBOL_WEST_SYRIAC_CROSS = 9
DEATH_SYMBOL_EAST_SYRIAC_CROSS = 10 DEATH_SYMBOL_EAST_SYRIAC_CROSS = 10
DEATH_SYMBOL_HEAVY_GREEK_CROSS = 11 DEATH_SYMBOL_HEAVY_GREEK_CROSS = 11
DEATH_SYMBOL_LATIN_CROSS = 12 DEATH_SYMBOL_LATIN_CROSS = 12
DEATH_SYMBOL_SHADOWED_LATIN_CROSS = 13 DEATH_SYMBOL_SHADOWED_LATIN_CROSS = 13
DEATH_SYMBOL_MALTESE_CROSS = 14 DEATH_SYMBOL_MALTESE_CROSS = 14
DEATH_SYMBOL_STAR_OF_DAVID = 15 DEATH_SYMBOL_STAR_OF_DAVID = 15
DEATH_SYMBOL_DEAD = 16 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): def __init__(self):
self.symbols = None 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 # functions for general symbols
# #

View File

@ -410,7 +410,7 @@ class ConfigureDialog(ManagedWindow):
if not callback: if not callback:
callback = self.update_entry callback = self.update_entry
if label: if label:
lwidget = BasicLabel(_("%s: ") % label) # Translators: for French lwidget = BasicLabel(_("%s: ") % label) # translators: for French
entry = Gtk.Entry() entry = Gtk.Entry()
if localized_config: if localized_config:
entry.set_text(config.get(constant)) entry.set_text(config.get(constant))
@ -709,7 +709,7 @@ class GrampsPreferences(ConfigureDialog):
hbox.pack_start(lwidget, False, False, 0) hbox.pack_start(lwidget, False, False, 0)
hbox.pack_start(self.color_scheme_box, 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_btn.set_tooltip_text(
_('Restore colors for current theme to default.')) _('Restore colors for current theme to default.'))
restore_btn.connect('clicked', self.restore_colors) restore_btn.connect('clicked', self.restore_colors)
@ -865,19 +865,19 @@ class GrampsPreferences(ConfigureDialog):
_("Common")), _("Common")),
"%s, %s %s (%s)" % (_("Surname"), _("Given"), _("Suffix"), "%s, %s %s (%s)" % (_("Surname"), _("Given"), _("Suffix"),
_("Nickname")), _("Nickname")),
"%s, %s %s (%s)" % (_("Surname"), _("Common", "Name"), _("Suffix"), "%s, %s %s (%s)" % (_("Surname"), _("Name|Common"), _("Suffix"),
_("Nickname")), _("Nickname")),
"%s, %s %s" % (_("Surname"), _("Common", "Name"), _("Suffix")), "%s, %s %s" % (_("Surname"), _("Name|Common"), _("Suffix")),
"%s, %s %s (%s)" % (_("SURNAME"), _("Given"), _("Suffix"), "%s, %s %s (%s)" % (_("SURNAME"), _("Given"), _("Suffix"),
_("Call")), _("Call")),
"%s, %s (%s)" % (_("Surname"), _("Given"), _("Common", "Name")), "%s, %s (%s)" % (_("Surname"), _("Given"), _("Name|Common")),
"%s, %s (%s)" % (_("Surname"), _("Common", "Name"), _("Nickname")), "%s, %s (%s)" % (_("Surname"), _("Name|Common"), _("Nickname")),
"%s %s" % (_("Given"), _("Surname")), "%s %s" % (_("Given"), _("Surname")),
"%s %s, %s" % (_("Given"), _("Surname"), _("Suffix")), "%s %s, %s" % (_("Given"), _("Surname"), _("Suffix")),
"%s %s %s" % (_("Given"), _("NotPatronymic"), _("Patronymic")), "%s %s %s" % (_("Given"), _("NotPatronymic"), _("Patronymic")),
"%s, %s %s (%s)" % (_("SURNAME"), _("Given"), _("Suffix"), "%s, %s %s (%s)" % (_("SURNAME"), _("Given"), _("Suffix"),
_("Common")), _("Common")),
"%s, %s (%s)" % (_("SURNAME"), _("Given"), _("Common", "Name")), "%s, %s (%s)" % (_("SURNAME"), _("Given"), _("Name|Common")),
"%s, %s (%s)" % (_("SURNAME"), _("Given"), _("Nickname")), "%s, %s (%s)" % (_("SURNAME"), _("Given"), _("Nickname")),
"%s %s" % (_("Given"), _("SURNAME")), "%s %s" % (_("Given"), _("SURNAME")),
"%s %s, %s" % (_("Given"), _("SURNAME"), _("Suffix")), "%s %s, %s" % (_("Given"), _("SURNAME"), _("Suffix")),
@ -1084,7 +1084,7 @@ class GrampsPreferences(ConfigureDialog):
grid.attach(self.insert_button, 0, 1, 1, 1) grid.attach(self.insert_button, 0, 1, 1, 1)
grid.attach(self.remove_button, 1, 1, 1, 1) grid.attach(self.remove_button, 1, 1, 1, 1)
grid.attach(self.edit_button, 2, 1, 1, 1) grid.attach(self.edit_button, 2, 1, 1, 1)
self.format_list = format_tree self.format_list = format_tree
self.name_column = name_column self.name_column = name_column
return grid return grid
@ -1849,9 +1849,7 @@ class GrampsPreferences(ConfigureDialog):
formats = [_("Never"), formats = [_("Never"),
_("Every 15 minutes"), _("Every 15 minutes"),
_("Every 30 minutes"), _("Every 30 minutes"),
_("Every hour"), _("Every hour")]
_("Every 12 hours"),
_("Every day")]
list(map(obox.append_text, formats)) list(map(obox.append_text, formats))
active = config.get('database.autobackup') active = config.get('database.autobackup')
obox.set_active(active) obox.set_active(active)
@ -1949,8 +1947,6 @@ class GrampsPreferences(ConfigureDialog):
for plugin in sorted(backend_plugins, key=lambda plugin: plugin.name): for plugin in sorted(backend_plugins, key=lambda plugin: plugin.name):
if plugin.id == default: if plugin.id == default:
active = count active = count
if plugin.id == 'bsddb':
continue # bsddb is deprecated, so don't allow setting
model.append(row=[count, plugin.name, plugin.id]) model.append(row=[count, plugin.name, plugin.id])
count += 1 count += 1
obox.set_model(model) obox.set_model(model)
@ -1970,10 +1966,12 @@ class GrampsPreferences(ConfigureDialog):
Show dialog to choose media directory. Show dialog to choose media directory.
""" """
f = Gtk.FileChooserDialog(title=_("Select media directory"), f = Gtk.FileChooserDialog(title=_("Select media directory"),
transient_for=self.window, parent=self.window,
action=Gtk.FileChooserAction.SELECT_FOLDER) action=Gtk.FileChooserAction.SELECT_FOLDER,
f.add_buttons(_('_Cancel'), Gtk.ResponseType.CANCEL, buttons=(_('_Cancel'),
_('_Apply'), Gtk.ResponseType.OK) Gtk.ResponseType.CANCEL,
_('_Apply'),
Gtk.ResponseType.OK))
mpath = media_path(self.dbstate.db) mpath = media_path(self.dbstate.db)
f.set_current_folder(os.path.dirname(mpath)) f.set_current_folder(os.path.dirname(mpath))
@ -2018,10 +2016,12 @@ class GrampsPreferences(ConfigureDialog):
Show dialog to choose backup directory. Show dialog to choose backup directory.
""" """
f = Gtk.FileChooserDialog(title=_("Select backup directory"), f = Gtk.FileChooserDialog(title=_("Select backup directory"),
transient_for=self.window, parent=self.window,
action=Gtk.FileChooserAction.SELECT_FOLDER) action=Gtk.FileChooserAction.SELECT_FOLDER,
f.add_buttons(_('_Cancel'), Gtk.ResponseType.CANCEL, buttons=(_('_Cancel'),
_('_Apply'), Gtk.ResponseType.OK) Gtk.ResponseType.CANCEL,
_('_Apply'),
Gtk.ResponseType.OK))
backup_path = config.get('database.backup-path') backup_path = config.get('database.backup-path')
if not backup_path: if not backup_path:
backup_path = config.get('database.path') backup_path = config.get('database.path')
@ -2081,253 +2081,194 @@ class GrampsPreferences(ConfigureDialog):
self.grid.set_border_width(12) self.grid.set_border_width(12)
self.grid.set_column_spacing(6) self.grid.set_column_spacing(6)
self.grid.set_row_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' message = _('If checked, use the standard genealogic symbols (death '
' which is able to show all genealogical symbols\n\n' 'symbol is user selectable).\n'
'If you select the "use symbols" checkbox, ' 'If not checked, you can use the lower panel to customize '
'Gramps will use the selected font if it exists.' 'the symbols yourself.'
) )
message += '\n' message += '\n\n'
message += _('This can be useful if you want to add phonetic in ' 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' 'a note to show how to pronounce a name or if you mix'
' multiple languages like greek and russian.' ' multiple languages like greek and russian.'
) )
self.add_text(self.grid, message, self.add_checkbox(self.grid, _('Use symbols'), 0, 'utf8.in-use',
0, line_wrap=True) extra_callback=self.activate_change_font,
self.add_checkbox(self.grid, tooltip=message)
_('Use symbols'), symbols = Symbols()
1, all_sbls = symbols.get_death_symbols()
'utf8.in-use', all_symbols = []
extra_callback=self.activate_change_font for symbol in all_sbls:
) all_symbols.append(symbol[1] + " " + symbol[0])
message = _('Be careful, if you click on the "Try to find" button, it can ' self.all_death_symbols = list(enumerate(all_symbols))
'take a while before you can continue (10 minutes or more). ' self.combo = self.add_combo(self.grid,
'\nIf you cancel the process, nothing will be changed.' _('Select default death symbol'),
) 4, 'utf8.death-symbol',
self.add_text(self.grid, message, self.all_death_symbols,
2, line_wrap=True) callback=self.utf8_update_death_symbol,
available_fonts = config.get('utf8.available-fonts') valueactive=False)
self.all_avail_fonts = list(enumerate(available_fonts)) self.utf8_show_example()
if len(available_fonts) > 0: self.show_default_symbols()
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)
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)
if config.get('utf8.selected-font') != "":
self.utf8_show_example()
return _('Symbols'), self.grid return _('Genealogical Symbols'), self.grid
def can_we_use_genealogical_fonts(self, obj): def activate_change_font(self, obj=None):
try: self.uistate.reload_symbols()
import fontconfig self.show_default_symbols()
from gramps.gui.utils import ProgressMeter self.uistate.emit('font-changed')
from collections import defaultdict
except: def utf8_show_example(self):
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
try: try:
# remove the old messages with old font # remove the old messages with old font
self.grid.remove_row(8)
self.grid.remove_row(7) self.grid.remove_row(7)
self.grid.remove_row(6) self.grid.remove_row(6)
self.grid.remove_row(5) self.grid.remove_row(5)
except: except:
pass 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') font = config.get('utf8.selected-font')
symbols = Symbols() 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() self.sym_buf = Gtk.TextBuffer()
scrollw.set_size_request(600, 100) self.sym_text = Gtk.TextView.new_with_buffer(self.sym_buf)
text = Gtk.Label() self.sym_text.set_has_tooltip(True)
text.set_line_wrap(True) self.sym_text.props.halign = Gtk.Align.START
self.activate_change_font() self.sym_text.connect("query_tooltip", self.sym_tooltip)
text.set_halign(Gtk.Align.START) for (tooltip, text, _tsym) in symbols.all_symbols:
text.set_markup("<span font='%s'>%s</span>" % (font, my_characters)) text = ' ' + text + ' '
scrollw.add(text) tag = self.sym_buf.create_tag(tag_name=tooltip, font=font,
scrollw.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) size_points=16.0)
self.grid.attach(scrollw, 1, 7, 8, 1) _iter = self.sym_buf.get_end_iter()
self.sym_buf.insert_with_tags(_iter, text, tag)
my_characters = ""
for idx in range(symbols.SYMBOL_FEMALE, symbols.SYMBOL_EXTINCT+1):
my_characters += symbols.get_symbol_for_string(idx) + " "
death_symbl = config.get('utf8.death-symbol') death_symbl = config.get('utf8.death-symbol')
my_characters += symbols.get_death_symbol_for_char(death_symbl) text = ' ' + symbols.get_death_symbol_for_char(death_symbl) + ' '
text = Gtk.Label() tooltip = (_("Death:") + '\n' +
text.set_line_wrap(True) symbols.get_death_symbol_name(death_symbl))
text.set_halign(Gtk.Align.START) tag = self.sym_buf.create_tag(tag_name=tooltip, font=font,
text.set_markup("<big><big><big><big><span font='%s'>%s</span>" size_points=14.0)
"</big></big></big></big>" % (font, my_characters)) _iter = self.sym_buf.get_end_iter()
self.grid.attach(text, 1, 8, 8, 1) self.sym_buf.insert_with_tags(_iter, text, tag)
scrollw.show_all() self.sym_text.set_editable(False)
text.show_all() 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): def sym_tooltip(self, widget, w_x, w_y, key_mode, tooltip):
self.progress.close() """ show a tooltip for each genealogic symbol """
self.in_progress = False 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): def utf8_update_death_symbol(self, obj, constant):
entry = obj.get_active() entry = obj.get_active()
config.set(constant, entry) config.set(constant, entry)
self.utf8_show_example() 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.gradcol = None
self.in_drag = False self.in_drag = False
self._mouse_click_cell_address = None self._mouse_click_cell_address = None
self.symbols = Symbols()
self.reload_symbols() self.reload_symbols()
def reload_symbols(self): def reload_symbols(self):
self.symbols = Symbols()
dth_idx = self.uistate.death_symbol dth_idx = self.uistate.death_symbol
if self.uistate.symbols: 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) self.dth = self.symbols.get_death_symbol_for_char(dth_idx)
else: 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) self.dth = self.symbols.get_death_symbol_fallback(dth_idx)
def reset(self): def reset(self):
@ -664,7 +666,7 @@ class FanChartBaseWidget(Gtk.DrawingArea):
if self.showid: if self.showid:
name += " (" + person.gramps_id + ")" name += " (" + person.gramps_id + ")"
if self.uistate.symbols and not alive: if self.uistate.symbols and not alive:
name = self.dth + ' ' + name name = self.dth + ' ' + name
self.draw_text(ctx, name, radiusin, radiusout, start, stop, self.draw_text(ctx, name, radiusin, radiusout, start, stop,
draw_radial, fontcolor, bold) draw_radial, fontcolor, bold)
else: else:

View File

@ -577,12 +577,15 @@ class PedigreeView(NavigationView):
self.uistate.connect('font-changed', self.reload_symbols) self.uistate.connect('font-changed', self.reload_symbols)
def reload_symbols(self): def reload_symbols(self):
self.symbols = Symbols()
dth_idx = self.uistate.death_symbol dth_idx = self.uistate.death_symbol
if self.uistate.symbols: 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) self.dth = self.symbols.get_death_symbol_for_char(dth_idx)
else: 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) self.dth = self.symbols.get_death_symbol_fallback(dth_idx)
def get_handle_from_gramps_id(self, gid): def get_handle_from_gramps_id(self, gid):

View File

@ -78,7 +78,7 @@ from gramps.gen.errors import WindowActiveError
from gramps.gui.views.bookmarks import PersonBookmarks from gramps.gui.views.bookmarks import PersonBookmarks
from gramps.gen.const import CUSTOM_FILTERS from gramps.gen.const import CUSTOM_FILTERS
from gramps.gen.utils.db import (get_birth_or_fallback, get_death_or_fallback, from gramps.gen.utils.db import (get_birth_or_fallback, get_death_or_fallback,
preset_name) preset_name)
from gramps.gui.ddtargets import DdTargets from gramps.gui.ddtargets import DdTargets
from gramps.gen.utils.symbols import Symbols from gramps.gen.utils.symbols import Symbols
@ -128,10 +128,8 @@ class RelationshipView(NavigationView):
) )
def __init__(self, pdata, dbstate, uistate, nav_group=0): def __init__(self, pdata, dbstate, uistate, nav_group=0):
NavigationView.__init__(self, _('Relationships'), NavigationView.__init__(self, _('Relationships'), pdata, dbstate,
pdata, dbstate, uistate, uistate, PersonBookmarks, nav_group)
PersonBookmarks,
nav_group)
dbstate.connect('database-changed', self.change_db) dbstate.connect('database-changed', self.change_db)
uistate.connect('nameformat-changed', self.build_tree) uistate.connect('nameformat-changed', self.build_tree)
@ -153,7 +151,6 @@ class RelationshipView(NavigationView):
self.theme = self._config.get('preferences.relation-display-theme') self.theme = self._config.get('preferences.relation-display-theme')
self.toolbar_visible = config.get('interface.toolbar-on') self.toolbar_visible = config.get('interface.toolbar-on')
self.age_precision = config.get('preferences.age-display-precision') self.age_precision = config.get('preferences.age-display-precision')
self.symbols = Symbols()
self.reload_symbols() self.reload_symbols()
def get_handle_from_gramps_id(self, gid): def get_handle_from_gramps_id(self, gid):
@ -177,13 +174,14 @@ class RelationshipView(NavigationView):
self.callman.add_db_signal('person-update', self.person_update) self.callman.add_db_signal('person-update', self.person_update)
self.callman.add_db_signal('person-rebuild', self.person_rebuild) self.callman.add_db_signal('person-rebuild', self.person_rebuild)
self.callman.add_db_signal('family-update', self.family_update) self.callman.add_db_signal('family-update', self.family_update)
self.callman.add_db_signal('family-add', self.family_add) self.callman.add_db_signal('family-add', self.family_add)
self.callman.add_db_signal('family-delete', self.family_delete) self.callman.add_db_signal('family-delete', self.family_delete)
self.callman.add_db_signal('family-rebuild', self.family_rebuild) self.callman.add_db_signal('family-rebuild', self.family_rebuild)
self.callman.add_db_signal('person-delete', self.redraw) self.callman.add_db_signal('person-delete', self.redraw)
def reload_symbols(self): def reload_symbols(self):
self.symbols = Symbols()
if self.uistate and self.uistate.symbols: if self.uistate and self.uistate.symbols:
gsfs = self.symbols.get_symbol_for_string gsfs = self.symbols.get_symbol_for_string
self.male = gsfs(self.symbols.SYMBOL_MALE) self.male = gsfs(self.symbols.SYMBOL_MALE)
@ -581,7 +579,7 @@ class RelationshipView(NavigationView):
list(map(self.header.remove, self.header.get_children())) list(map(self.header.remove, self.header.get_children()))
self.child = None self.child = None
if self.active: if self.active:
self.bookmarks.redraw() self.bookmarks.redraw()
self.redraw() self.redraw()
def get_name(self, handle, use_gender=False): def get_name(self, handle, use_gender=False):
@ -627,7 +625,7 @@ class RelationshipView(NavigationView):
old_vadjust = self.scroll.get_vadjustment().get_lower() old_vadjust = self.scroll.get_vadjustment().get_lower()
self.old_handle = obj self.old_handle = obj
self.scroll.get_vadjustment().set_value( self.scroll.get_vadjustment().set_value(
self.scroll.get_vadjustment().get_lower()) self.scroll.get_vadjustment().get_lower())
if self.redrawing: if self.redrawing:
return False return False
self.redrawing = True self.redrawing = True
@ -657,7 +655,7 @@ class RelationshipView(NavigationView):
family_handle_list = person.get_parent_family_handle_list() 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: if family_handle_list:
for family_handle in 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() family_handle_list = person.get_family_handle_list()
if not self.reorder_sensitive: 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: if family_handle_list:
for family_handle in family_handle_list: for family_handle in family_handle_list:
@ -794,11 +792,10 @@ class RelationshipView(NavigationView):
if not showed_death: if not showed_death:
subgrid.attach(widgets.BasicLabel(_("%s") % death_title), subgrid.attach(widgets.BasicLabel(_("%s") % death_title),
1, 2, 1, 1) 1, 2, 1, 1)
deathwidget = widgets.BasicLabel(self.format_event(death)) deathwidget = widgets.BasicLabel(self.format_event(death))
deathwidget.set_selectable(True) deathwidget.set_selectable(True)
subgrid.attach(deathwidget, subgrid.attach(deathwidget, 2, 2, 1, 1)
2, 2, 1, 1)
mbox = Gtk.Box() mbox = Gtk.Box()
mbox.add(grid) mbox.add(grid)
@ -809,9 +806,8 @@ class RelationshipView(NavigationView):
mobj = self.dbstate.db.get_media_from_handle(image_list[0].ref) mobj = self.dbstate.db.get_media_from_handle(image_list[0].ref)
if mobj and mobj.get_mime_type()[0:5] == "image": if mobj and mobj.get_mime_type()[0:5] == "image":
pixbuf = get_thumbnail_image( pixbuf = get_thumbnail_image(
media_path_full(self.dbstate.db, media_path_full(self.dbstate.db, mobj.get_path()),
mobj.get_path()), rectangle=image_list[0].get_rectangle())
rectangle=image_list[0].get_rectangle())
image = Gtk.Image() image = Gtk.Image()
image.set_from_pixbuf(pixbuf) image.set_from_pixbuf(pixbuf)
button = Gtk.Button() button = Gtk.Button()
@ -914,11 +910,12 @@ class RelationshipView(NavigationView):
msg = "" msg = ""
return 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 Write a Family header row
Shows following elements: 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) msg = '<span style="italic" weight="heavy">%s</span>' % escape(title)
hbox = Gtk.Box() hbox = Gtk.Box()
@ -933,9 +930,9 @@ class RelationshipView(NavigationView):
arrow = widgets.ExpandCollapseArrow(False, arrow = widgets.ExpandCollapseArrow(False,
self.expand_collapse_press, self.expand_collapse_press,
(person, family.handle)) (person, family.handle))
else : else:
arrow = Gtk.Arrow(arrow_type=Gtk.ArrowType.RIGHT, arrow = Gtk.Arrow(arrow_type=Gtk.ArrowType.RIGHT,
shadow_type=Gtk.ShadowType.OUT) shadow_type=Gtk.ShadowType.OUT)
hbox.pack_start(arrow, False, True, 0) hbox.pack_start(arrow, False, True, 0)
hbox.pack_start(label, True, True, 0) hbox.pack_start(label, True, True, 0)
# Allow to drag this family # Allow to drag this family
@ -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) family = self.dbstate.db.get_family_from_handle(family_handle)
if not family: if not family:
return return
@ -1044,16 +1041,16 @@ class RelationshipView(NavigationView):
childmsg = ngettext(" ({number_of} sibling)", childmsg = ngettext(" ({number_of} sibling)",
" ({number_of} siblings)", count " ({number_of} siblings)", count
).format(number_of=count) ).format(number_of=count)
elif count == 1 : elif count == 1:
gender = self.dbstate.db.get_person_from_handle( gender = self.dbstate.db.get_person_from_handle(
child_list[0]).gender child_list[0]).gender
if gender == Person.MALE : if gender == Person.MALE:
childmsg = _(" (1 brother)") childmsg = _(" (1 brother)")
elif gender == Person.FEMALE : elif gender == Person.FEMALE:
childmsg = _(" (1 sister)") childmsg = _(" (1 sister)")
else : else:
childmsg = _(" (1 sibling)") childmsg = _(" (1 sibling)")
else : else:
childmsg = _(" (only child)") childmsg = _(" (only child)")
self.family = family self.family = family
box = self.get_people_box(family.get_father_handle(), box = self.get_people_box(family.get_father_handle(),
@ -1062,7 +1059,7 @@ class RelationshipView(NavigationView):
eventbox = widgets.ShadeBox(self.use_shade) eventbox = widgets.ShadeBox(self.use_shade)
eventbox.add(box) eventbox.add(box)
self.child.attach(eventbox, _PDATA_START, self.row, self.child.attach(eventbox, _PDATA_START, self.row,
_PDATA_STOP-_PDATA_START, 1) _PDATA_STOP-_PDATA_START, 1)
self.row += 1 # now advance it self.row += 1 # now advance it
else: else:
self.write_label(_("%s:") % _('Parents'), family, True, person) self.write_label(_("%s:") % _('Parents'), family, True, person)
@ -1099,16 +1096,16 @@ class RelationshipView(NavigationView):
childmsg = ngettext(" ({number_of} sibling)", childmsg = ngettext(" ({number_of} sibling)",
" ({number_of} siblings)", count " ({number_of} siblings)", count
).format(number_of=count) ).format(number_of=count)
elif count == 1 : elif count == 1:
gender = self.dbstate.db.get_person_from_handle( gender = self.dbstate.db.get_person_from_handle(
child_list[0]).gender child_list[0]).gender
if gender == Person.MALE : if gender == Person.MALE:
childmsg = _(" (1 brother)") childmsg = _(" (1 brother)")
elif gender == Person.FEMALE : elif gender == Person.FEMALE:
childmsg = _(" (1 sister)") childmsg = _(" (1 sister)")
else : else:
childmsg = _(" (1 sibling)") childmsg = _(" (1 sibling)")
else : else:
childmsg = _(" (only child)") childmsg = _(" (only child)")
self.family = None self.family = None
box = self.get_people_box(post_msg=childmsg) box = self.get_people_box(post_msg=childmsg)
@ -1213,7 +1210,7 @@ class RelationshipView(NavigationView):
parent = len(person.get_parent_family_handle_list()) > 0 parent = len(person.get_parent_family_handle_list()) > 0
format = '' format = ''
relation_display_theme = self._config.get( relation_display_theme = self._config.get(
'preferences.relation-display-theme') 'preferences.relation-display-theme')
if parent: if parent:
emph = True emph = True
else: else:
@ -1483,11 +1480,11 @@ class RelationshipView(NavigationView):
handle = event_ref.ref handle = event_ref.ref
event = self.dbstate.db.get_event_from_handle(handle) event = self.dbstate.db.get_event_from_handle(handle)
if (event and event.get_type().is_relationship_event() and if (event and event.get_type().is_relationship_event() and
(event_ref.get_role() == EventRoleType.FAMILY or (event_ref.get_role() == EventRoleType.FAMILY or
event_ref.get_role() == EventRoleType.PRIMARY)): event_ref.get_role() == EventRoleType.PRIMARY)):
if event.get_type() == EventType.MARRIAGE: if event.get_type() == EventType.MARRIAGE:
etype = self.marriage etype = self.marriage
elif event.get_type() == EventType.DIVORCE: elif event.get_type() == EventType.DIVORCE:
etype = self.divorce etype = self.divorce
else: else:
etype = event.get_type().string etype = event.get_type().string
@ -1513,7 +1510,7 @@ class RelationshipView(NavigationView):
else: else:
pname = None pname = None
dobj = None dobj = None
value = { 'event_type' : ename, } value = {'event_type' : ename}
if dobj: if dobj:
if pname: if pname:
@ -1532,7 +1529,7 @@ class RelationshipView(NavigationView):
self.write_data( self.write_data(
vbox, '%(event_type)s' % value, start_col, stop_col) 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) family = self.dbstate.db.get_family_from_handle(family_handle)
if family is None: if family is None:
from gramps.gui.dialog import WarningDialog from gramps.gui.dialog import WarningDialog
@ -1564,7 +1561,7 @@ class RelationshipView(NavigationView):
childmsg = ngettext(" ({number_of} child)", childmsg = ngettext(" ({number_of} child)",
" ({number_of} children)", count " ({number_of} children)", count
).format(number_of=count) ).format(number_of=count)
else : else:
childmsg = _(" (no children)") childmsg = _(" (no children)")
self.family = family self.family = family
box = self.get_people_box(handle, post_msg=childmsg) box = self.get_people_box(handle, post_msg=childmsg)
@ -1610,7 +1607,7 @@ class RelationshipView(NavigationView):
childmsg = ngettext(" ({number_of} child)", childmsg = ngettext(" ({number_of} child)",
" ({number_of} children)", count " ({number_of} children)", count
).format(number_of=count) ).format(number_of=count)
else : else:
childmsg = _(" (no children)") childmsg = _(" (no children)")
self.family = None self.family = None
box = self.get_people_box(post_msg=childmsg) box = self.get_people_box(post_msg=childmsg)
@ -1868,12 +1865,10 @@ class RelationshipView(NavigationView):
grid.set_column_spacing(6) grid.set_column_spacing(6)
grid.set_row_spacing(6) grid.set_row_spacing(6)
configdialog.add_checkbox(grid, configdialog.add_checkbox(grid, _('Use shading'),
_('Use shading'), 0, 'preferences.relation-shade')
0, 'preferences.relation-shade') configdialog.add_checkbox(grid, _('Display edit buttons'),
configdialog.add_checkbox(grid, 1, 'preferences.releditbtn')
_('Display edit buttons'),
1, 'preferences.releditbtn')
checkbox = Gtk.CheckButton(label=_('View links as website links')) checkbox = Gtk.CheckButton(label=_('View links as website links'))
theme = self._config.get('preferences.relation-display-theme') theme = self._config.get('preferences.relation-display-theme')
checkbox.set_active(theme == 'WEBPAGE') checkbox.set_active(theme == 'WEBPAGE')
@ -1890,12 +1885,10 @@ class RelationshipView(NavigationView):
grid.set_border_width(12) grid.set_border_width(12)
grid.set_column_spacing(6) grid.set_column_spacing(6)
grid.set_row_spacing(6) grid.set_row_spacing(6)
configdialog.add_checkbox(grid, configdialog.add_checkbox(grid, _('Show Details'),
_('Show Details'), 0, 'preferences.family-details')
0, 'preferences.family-details') configdialog.add_checkbox(grid, _('Show Siblings'),
configdialog.add_checkbox(grid, 1, 'preferences.family-siblings')
_('Show Siblings'),
1, 'preferences.family-siblings')
return _('Content'), grid return _('Content'), grid
@ -1906,11 +1899,11 @@ class RelationshipView(NavigationView):
if obj.get_active(): if obj.get_active():
self.theme = 'WEBPAGE' self.theme = 'WEBPAGE'
self._config.set('preferences.relation-display-theme', self._config.set('preferences.relation-display-theme',
'WEBPAGE') 'WEBPAGE')
else: else:
self.theme = 'CLASSIC' self.theme = 'CLASSIC'
self._config.set('preferences.relation-display-theme', self._config.set('preferences.relation-display-theme',
'CLASSIC') 'CLASSIC')
def _get_configure_page_funcs(self): def _get_configure_page_funcs(self):
""" """
@ -1926,7 +1919,7 @@ class RelationshipView(NavigationView):
# Function to return if person has children # Function to return if person has children
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
def has_children(db,p): def has_children(db, p):
""" """
Return if a person has children. Return if a person has children.
""" """
@ -1941,9 +1934,9 @@ def has_children(db,p):
def button_activated(event, mouse_button): def button_activated(event, mouse_button):
if (event.type == Gdk.EventType.BUTTON_PRESS and if (event.type == Gdk.EventType.BUTTON_PRESS and
event.button == mouse_button) or \ event.button == mouse_button) or \
(event.type == Gdk.EventType.KEY_PRESS and (event.type == Gdk.EventType.KEY_PRESS and
event.keyval in (_RETURN, _KP_ENTER, _SPACE)): event.keyval in (_RETURN, _KP_ENTER, _SPACE)):
return True return True
else: else:
return False return False