diff --git a/data/css/ancestortree.css b/data/css/ancestortree.css
index 5e6ff1d0e..9b53b54d8 100644
--- a/data/css/ancestortree.css
+++ b/data/css/ancestortree.css
@@ -180,6 +180,10 @@ Females Web_Gender_Female.png
#treeContainer div.female span.unlinked {
background:url(../images/Web_Gender_Female.png) #FFC0CB no-repeat top right;
}
+#treeContainer div.other a,
+#treeContainer div.other span.unlinked {
+ background:url(../images/Web_Gender_Other.png) #94EF9E no-repeat top right;
+}
#treeContainer div.unknown a,
#treeContainer div.unknown span.unlinked {
background-color: #000;
diff --git a/data/tests/imp_sample.gramps b/data/tests/imp_sample.gramps
index 9f4b108e0..7f2c7a260 100644
--- a/data/tests/imp_sample.gramps
+++ b/data/tests/imp_sample.gramps
@@ -919,7 +919,7 @@
- U
+ X
Magnes
Smith
diff --git a/gramps/gen/config.py b/gramps/gen/config.py
index 49924111c..882d1d1a2 100644
--- a/gramps/gen/config.py
+++ b/gramps/gen/config.py
@@ -289,6 +289,8 @@ register('colors.male-alive', ['#b8cee6', '#1f344a'])
register('colors.male-dead', ['#b8cee6', '#2d3039'])
register('colors.female-alive', ['#feccf0', '#62242D'])
register('colors.female-dead', ['#feccf0', '#3a292b'])
+register('colors.other-alive', ['#94ef9e', '#285b27'])
+register('colors.other-dead', ['#94ef9e', '#062304'])
register('colors.unknown-alive', ['#f3dbb6', '#75507B'])
register('colors.unknown-dead', ['#f3dbb6', '#35103b'])
register('colors.family', ['#eeeeee', '#454545'])
@@ -302,6 +304,8 @@ register('colors.border-male-alive', ['#1f4986', '#171d26'])
register('colors.border-male-dead', ['#000000', '#000000'])
register('colors.border-female-alive', ['#861f69', '#261111'])
register('colors.border-female-dead', ['#000000', '#000000'])
+register('colors.border-other-alive', ['#2a5f16', '#26a269'])
+register('colors.border-other-dead', ['#000000', '#000000'])
register('colors.border-unknown-alive', ['#8e5801', '#8e5801'])
register('colors.border-unknown-dead', ['#000000', '#000000'])
register('colors.border-family', ['#cccccc', '#252525'])
diff --git a/gramps/gen/filters/rules/person/__init__.py b/gramps/gen/filters/rules/person/__init__.py
index 14da55bd7..7812cec52 100644
--- a/gramps/gen/filters/rules/person/__init__.py
+++ b/gramps/gen/filters/rules/person/__init__.py
@@ -51,6 +51,7 @@ from ._hasnickname import HasNickname
from ._hasnote import HasNote
from ._hasnotematchingsubstringof import HasNoteMatchingSubstringOf
from ._hasnoteregexp import HasNoteRegexp
+from ._hasothergender import HasOtherGender
from ._hasrelationship import HasRelationship
from ._hassourcecount import HasSourceCount
from ._hassourceof import HasSourceOf
@@ -120,8 +121,9 @@ from ._hassoundexname import HasSoundexName
editor_rule_list = [
Everyone,
IsFemale,
- HasUnknownGender,
IsMale,
+ HasOtherGender,
+ HasUnknownGender,
IsDefaultPerson,
IsBookmarked,
HasAlternateName,
diff --git a/gramps/gen/filters/rules/person/_hasothergender.py b/gramps/gen/filters/rules/person/_hasothergender.py
new file mode 100644
index 000000000..eba966bf0
--- /dev/null
+++ b/gramps/gen/filters/rules/person/_hasothergender.py
@@ -0,0 +1,50 @@
+#
+# Gramps - a GTK+/GNOME based genealogy program
+#
+# Copyright (C) 2002-2006 Donald N. Allingham
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+
+#-------------------------------------------------------------------------
+#
+# Standard Python modules
+#
+#-------------------------------------------------------------------------
+from ....const import GRAMPS_LOCALE as glocale
+_ = glocale.translation.gettext
+
+#-------------------------------------------------------------------------
+#
+# Gramps modules
+#
+#-------------------------------------------------------------------------
+from .. import Rule
+from ....lib.person import Person
+
+#-------------------------------------------------------------------------
+#
+# HasOtherGender
+#
+#-------------------------------------------------------------------------
+class HasOtherGender(Rule):
+ """Rule that checks for a person that has other gender"""
+
+ name = _('People who are neither male nor female')
+ category = _('General filters')
+ description = _('Matches all people with other gender')
+
+ def apply(self, db, person):
+ return person.gender == Person.OTHER
diff --git a/gramps/gen/lib/genderstats.py b/gramps/gen/lib/genderstats.py
index 0b4bc3ed7..271c922e8 100644
--- a/gramps/gen/lib/genderstats.py
+++ b/gramps/gen/lib/genderstats.py
@@ -98,7 +98,7 @@ class GenderStats:
female += increment
if female < 0:
female = 0
- elif gender == Person.UNKNOWN:
+ elif gender in (Person.UNKNOWN, Person.OTHER):
unknown += increment
if unknown < 0:
unknown = 0
diff --git a/gramps/gen/lib/person.py b/gramps/gen/lib/person.py
index 00ec9462d..4c9c2d5d2 100644
--- a/gramps/gen/lib/person.py
+++ b/gramps/gen/lib/person.py
@@ -73,6 +73,7 @@ class Person(CitationBase, NoteBase, AttributeBase, MediaBase,
"""
+ OTHER = 3
UNKNOWN = 2
MALE = 1
FEMALE = 0
@@ -644,10 +645,12 @@ class Person(CitationBase, NoteBase, AttributeBase, MediaBase,
- Person.MALE
- Person.FEMALE
+ - Person.OTHER
- Person.UNKNOWN
:type gender: int
"""
- if gender not in (Person.MALE, Person.FEMALE, Person.UNKNOWN):
+ if gender not in (Person.MALE, Person.FEMALE, Person.OTHER,
+ Person.UNKNOWN):
raise ValueError('Attempt to assign invalid gender')
self.__gender = gender
@@ -659,6 +662,7 @@ class Person(CitationBase, NoteBase, AttributeBase, MediaBase,
- Person.MALE
- Person.FEMALE
+ - Person.OTHER
- Person.UNKNOWN
:rtype: int
"""
diff --git a/gramps/gen/plug/docgen/treedoc.py b/gramps/gen/plug/docgen/treedoc.py
index 354a73eb3..2fe8d4a53 100644
--- a/gramps/gen/plug/docgen/treedoc.py
+++ b/gramps/gen/plug/docgen/treedoc.py
@@ -434,7 +434,7 @@ class TreeDocBase(BaseDoc, TreeDoc):
self.write(level+1, 'male,\n')
elif person.gender == Person.FEMALE:
self.write(level+1, 'female,\n')
- elif person.gender == Person.UNKNOWN:
+ elif person.gender in (Person.UNKNOWN, Person.OTHER):
self.write(level+1, 'neuter,\n')
name = person.get_primary_name()
nick = name.get_nick_name()
diff --git a/gramps/gen/utils/string.py b/gramps/gen/utils/string.py
index b75155975..16b9e72fc 100644
--- a/gramps/gen/utils/string.py
+++ b/gramps/gen/utils/string.py
@@ -46,6 +46,7 @@ gender = {
Person.MALE : _("male"),
Person.FEMALE : _("female"),
Person.UNKNOWN : _("unknown", "gender"),
+ Person.OTHER : _("other", "gender"),
}
def format_gender(type):
diff --git a/gramps/gen/utils/symbols.py b/gramps/gen/utils/symbols.py
index 8631cafc8..4fc0907ef 100644
--- a/gramps/gen/utils/symbols.py
+++ b/gramps/gen/utils/symbols.py
@@ -83,10 +83,10 @@ class Symbols(object):
(_("Female"), '\u2640', ""),
(_("Male"), '\u2642', ""),
(_("Asexuality, sexless, genderless"), '\u26aa', ""),
+ (_("Transgender, hermaphrodite (in entomology)"), '\u26a5', ""),
(_("Lesbianism"), '\u26a2', ""),
(_("Male homosexuality"), '\u26a3', ""),
(_("Heterosexuality"), '\u26a4', ""),
- (_("Transgender, hermaphrodite (in entomology)"), '\u26a5', ""),
(_("Transgender"), '\u26a6', ""),
(_("Neuter"), '\u26b2', ""),
(_("Illegitimate"), '\u229b', ""),
diff --git a/gramps/gen/utils/unknown.py b/gramps/gen/utils/unknown.py
index bf326475f..0753338d2 100644
--- a/gramps/gen/utils/unknown.py
+++ b/gramps/gen/utils/unknown.py
@@ -181,7 +181,7 @@ def add_personref_to_family(family, person):
(family.get_mother_handle() is None)):
family.set_mother_handle(person_handle)
else:
- # This includes cases of Person.UNKNOWN
+ # This includes cases of Person.UNKNOWN and Person.OTHER
if family.get_father_handle() is None:
family.set_father_handle(person_handle)
else:
diff --git a/gramps/gui/configure.py b/gramps/gui/configure.py
index 4d7c13c18..8f660df4b 100644
--- a/gramps/gui/configure.py
+++ b/gramps/gui/configure.py
@@ -720,9 +720,10 @@ class GrampsPreferences(ConfigureDialog):
color_type = {'Male': _('Colors for Male persons'),
'Female': _('Colors for Female persons'),
+ 'Other': _('Colors for people who are neither male nor female'),
'Unknown': _('Colors for Unknown persons'),
'Family': _('Colors for Family nodes'),
- 'Other': _('Other colors')}
+ 'Misc': _('Other colors')}
bg_alive_text = _('Background for Alive')
bg_dead_text = _('Background for Dead')
@@ -741,6 +742,11 @@ class GrampsPreferences(ConfigureDialog):
(bg_dead_text, 'female-dead', 2, 1, 'Female'),
(brd_alive_text, 'border-female-alive', 1, 4, 'Female'),
(brd_dead_text, 'border-female-dead', 2, 4, 'Female'),
+ # for other
+ (bg_alive_text, 'other-alive', 1, 1, 'Other'),
+ (bg_dead_text, 'other-dead', 2, 1, 'Other'),
+ (brd_alive_text, 'border-other-alive', 1, 4, 'Other'),
+ (brd_dead_text, 'border-other-dead', 2, 4, 'Other'),
# for unknown
(bg_alive_text, 'unknown-alive', 1, 1, 'Unknown'),
(bg_dead_text, 'unknown-dead', 2, 1, 'Unknown'),
@@ -759,7 +765,7 @@ class GrampsPreferences(ConfigureDialog):
(_('Border for Divorced'),
'border-family-divorced', 7, 4, 'Family'),
# for other
- (_('Background for Home Person'), 'home-person', 1, 1, 'Other'),
+ (_('Background for Home Person'), 'home-person', 1, 1, 'Misc'),
]
# prepare scrolled window for colors settings
diff --git a/gramps/gui/editors/editperson.py b/gramps/gui/editors/editperson.py
index 81daa1254..8a2a06258 100644
--- a/gramps/gui/editors/editperson.py
+++ b/gramps/gui/editors/editperson.py
@@ -339,7 +339,8 @@ class EditPerson(EditPrimary):
(
(_('female'), Person.FEMALE),
(_('male'), Person.MALE),
- (_('unknown'), Person.UNKNOWN)
+ (_('unknown', 'gender'), Person.UNKNOWN),
+ (_('other', 'gender'), Person.OTHER)
),
self.db.readonly)
@@ -1110,4 +1111,5 @@ class GenderDialog(Gtk.MessageDialog):
self.add_button(_('_Male'), Person.MALE)
self.add_button(_('_Female'), Person.FEMALE)
+ self.add_button(_('_Other'), Person.OTHER)
self.add_button(_('_Unknown'), Person.UNKNOWN)
diff --git a/gramps/gui/filters/sidebar/_personsidebarfilter.py b/gramps/gui/filters/sidebar/_personsidebarfilter.py
index 7d11fdc85..8b97b991a 100644
--- a/gramps/gui/filters/sidebar/_personsidebarfilter.py
+++ b/gramps/gui/filters/sidebar/_personsidebarfilter.py
@@ -49,7 +49,7 @@ from gramps.gen.filters.rules.person import (RegExpName, RegExpIdOf, IsMale,
IsFemale, HasUnknownGender,
HasEvent, HasTag, HasBirth,
HasDeath, HasNoteRegexp,
- MatchesFilter)
+ MatchesFilter, HasOtherGender)
def extract_text(entry_widget):
"""
@@ -91,7 +91,8 @@ class PersonSidebarFilter(SidebarFilter):
self.filter_note = widgets.BasicEntry()
self.filter_gender = Gtk.ComboBoxText()
list(map(self.filter_gender.append_text,
- [ _('any'), _('male'), _('female'), _('unknown') ]))
+ [ _('any'), _('male'), _('female'), _('other', 'gender'),
+ _('unknown', 'gender') ]))
self.filter_gender.set_active(0)
self.filter_regex = Gtk.CheckButton(label=_('Use regular expressions'))
@@ -208,6 +209,8 @@ class PersonSidebarFilter(SidebarFilter):
generic_filter.add_rule(IsMale([]))
elif gender == 2:
generic_filter.add_rule(IsFemale([]))
+ elif gender == 3:
+ generic_filter.add_rule(HasOtherGender([]))
else:
generic_filter.add_rule(HasUnknownGender([]))
diff --git a/gramps/gui/merge/mergeperson.py b/gramps/gui/merge/mergeperson.py
index 8927f6065..42850ea33 100644
--- a/gramps/gui/merge/mergeperson.py
+++ b/gramps/gui/merge/mergeperson.py
@@ -61,7 +61,7 @@ _GLADE_FILE = "mergeperson.glade"
# Translators: needed for French, ignore otherwise
KEYVAL = _("%(key)s:\t%(value)s")
-sex = ( _("female"), _("male"), _("unknown") )
+sex = ( _("female"), _("male"), _("other"), _("unknown") )
def name_of(person):
"""Return string with name and ID of a person."""
diff --git a/gramps/gui/utils.py b/gramps/gui/utils.py
index cf661ecb8..3d2231d2c 100644
--- a/gramps/gui/utils.py
+++ b/gramps/gui/utils.py
@@ -494,6 +494,13 @@ def color_graph_box(alive=False, gender=Person.MALE):
else:
return (config.get('colors.female-dead')[scheme],
config.get('colors.border-female-dead')[scheme])
+ elif gender == Person.OTHER:
+ if alive:
+ return (config.get('colors.other-alive')[scheme],
+ config.get('colors.border-other-alive')[scheme])
+ else:
+ return (config.get('colors.other-dead')[scheme],
+ config.get('colors.border-other-dead')[scheme])
elif gender == Person.UNKNOWN:
if alive:
return (config.get('colors.unknown-alive')[scheme],
diff --git a/gramps/gui/views/treemodels/peoplemodel.py b/gramps/gui/views/treemodels/peoplemodel.py
index e2c70c2ff..6fb3bed15 100644
--- a/gramps/gui/views/treemodels/peoplemodel.py
+++ b/gramps/gui/views/treemodels/peoplemodel.py
@@ -95,7 +95,7 @@ class PeopleBaseModel(BaseModel):
"""
Basic Model interface to handle the PersonViews
"""
- _GENDER = [ _('female'), _('male'), _('unknown') ]
+ _GENDER = [ _('female'), _('male'), _('unknown'), _('other') ]
def __init__(self, db):
"""
diff --git a/gramps/gui/widgets/fanchart.py b/gramps/gui/widgets/fanchart.py
index 83fedab4b..30dc9e490 100644
--- a/gramps/gui/widgets/fanchart.py
+++ b/gramps/gui/widgets/fanchart.py
@@ -483,6 +483,8 @@ class FanChartBaseWidget(Gtk.DrawingArea):
color = self.colors[generation % len(self.colors)]
if person.gender == Person.MALE:
color = [x*.9 for x in color]
+ elif person.gender == Person.OTHER:
+ color = [x*.8 for x in color]
# now we set transparency data
if self.filter and not self.filter.match(person.handle,
self.dbstate.db):
diff --git a/gramps/plugins/db/dbapi/test/db_test.py b/gramps/plugins/db/dbapi/test/db_test.py
index 7204a046c..01db47304 100644
--- a/gramps/plugins/db/dbapi/test/db_test.py
+++ b/gramps/plugins/db/dbapi/test/db_test.py
@@ -832,7 +832,7 @@ class DbPersonTest(unittest.TestCase):
self.__add_person(Person.FEMALE, 'Mary', 'Baker', trans)
self.__add_person(Person.FEMALE, 'Mary', 'Clark', trans)
self.__add_person(Person.MALE, 'Mary', 'Davis', trans)
- self.__add_person(Person.FEMALE, 'Mary', 'Evans', trans)
+ self.__add_person(Person.OTHER, 'Mary', 'Evans', trans)
def tearDown(self):
with DbTxn('Remove test objects', self.db) as trans:
@@ -859,11 +859,11 @@ class DbPersonTest(unittest.TestCase):
def test_gender_stats(self):
stats = self.db.genderStats
self.assertEqual(stats.name_stats('John'), (3, 1, 1))
- self.assertEqual(stats.name_stats('Mary'), (1, 4, 0))
+ self.assertEqual(stats.name_stats('Mary'), (1, 3, 1))
self.db.save_gender_stats(stats)
saved = self.db.get_gender_stats()
self.assertEqual(saved['John'], (3, 1, 1))
- self.assertEqual(saved['Mary'], (1, 4, 0))
+ self.assertEqual(saved['Mary'], (1, 3, 1))
if __name__ == "__main__":
diff --git a/gramps/plugins/drawreport/statisticschart.py b/gramps/plugins/drawreport/statisticschart.py
index 794314d6a..c5831cdee 100644
--- a/gramps/plugins/drawreport/statisticschart.py
+++ b/gramps/plugins/drawreport/statisticschart.py
@@ -312,9 +312,10 @@ class _options:
(SORT_KEY, "Item name", _("Item name"))
]
opt_genders = [
- (Person.UNKNOWN, "Both", _("Both")),
+ (Person.UNKNOWN, "All", _("All")),
(Person.MALE, "Men", _("Men")),
- (Person.FEMALE, "Women", _("Women"))
+ (Person.FEMALE, "Women", _("Women")),
+ (Person.OTHER, "Other", _("Other"))
]
@@ -419,6 +420,8 @@ class Extract:
return [_T_("Men")]
if person.gender == Person.FEMALE:
return [_T_("Women")]
+ if person.gender == Person.OTHER:
+ return [_T_("Other")]
return [_T_("Gender unknown")]
def get_year(self, event):
@@ -794,6 +797,8 @@ class StatisticsChart(Report):
genders = self._("Men")
elif gender == Person.FEMALE:
genders = self._("Women")
+ elif gender == Person.OTHER:
+ genders = self._("Other")
else:
genders = None
diff --git a/gramps/plugins/export/exportcsv.py b/gramps/plugins/export/exportcsv.py
index b8f5cb26e..50aa746a9 100644
--- a/gramps/plugins/export/exportcsv.py
+++ b/gramps/plugins/export/exportcsv.py
@@ -396,6 +396,8 @@ class CSVWriter:
gender = gender_map[Person.MALE]
elif gender == Person.FEMALE:
gender = gender_map[Person.FEMALE]
+ elif gender == Person.OTHER:
+ gender = gender_map[Person.OTHER]
else:
gender = gender_map[Person.UNKNOWN]
# Birth:
diff --git a/gramps/plugins/export/exportgedcom.py b/gramps/plugins/export/exportgedcom.py
index 21b92c4ea..933c4d592 100644
--- a/gramps/plugins/export/exportgedcom.py
+++ b/gramps/plugins/export/exportgedcom.py
@@ -512,14 +512,16 @@ class GedcomWriter(UpdateCallback):
Write out the gender of the person to the file.
If the gender is not male or female, simply do not output anything.
- The only valid values are M (male) or F (female). So if the geneder is
- unknown, we output nothing.
+ The only valid values are M (male), F (female) and X (other). So if
+ the gender is unknown, we output nothing.
"""
if person.get_gender() == Person.MALE:
self._writeln(1, "SEX", "M")
elif person.get_gender() == Person.FEMALE:
self._writeln(1, "SEX", "F")
+ elif person.get_gender() == Person.OTHER:
+ self._writeln(1, "SEX", "X")
def _lds_ords(self, obj, level):
"""
diff --git a/gramps/plugins/export/exportvcard.py b/gramps/plugins/export/exportvcard.py
index ee62ea30b..cda6236a5 100644
--- a/gramps/plugins/export/exportvcard.py
+++ b/gramps/plugins/export/exportvcard.py
@@ -260,6 +260,8 @@ class VCardWriter:
gender_value = 'Male'
elif gender == Person.FEMALE:
gender_value = 'Female'
+ elif gender == Person.OTHER:
+ gender_value = 'Other'
log.info("gender: %s -> %s" % (gender, gender_value))
if gender_value:
self.writeln("X-GENDER:%s" % (gender_value))
diff --git a/gramps/plugins/export/exportxml.py b/gramps/plugins/export/exportxml.py
index fac655b08..08830e5ea 100644
--- a/gramps/plugins/export/exportxml.py
+++ b/gramps/plugins/export/exportxml.py
@@ -521,6 +521,8 @@ class GrampsXmlWriter(UpdateCallback):
self.write_line("gender","M",index+1)
elif person.get_gender() == Person.FEMALE:
self.write_line("gender","F",index+1)
+ elif person.get_gender() == Person.OTHER:
+ self.write_line("gender","X",index+1)
else:
self.write_line("gender","U",index+1)
self.dump_name(person.get_primary_name(),False,index+1)
diff --git a/gramps/plugins/gramplet/statsgramplet.py b/gramps/plugins/gramplet/statsgramplet.py
index baa4e6ab9..251c01cf3 100644
--- a/gramps/plugins/gramplet/statsgramplet.py
+++ b/gramps/plugins/gramplet/statsgramplet.py
@@ -79,6 +79,7 @@ class StatsGramplet(Gramplet):
missing_bday = 0
males = 0
females = 0
+ others = 0
unknowns = 0
bytes_cnt = 0
notfound = []
@@ -132,6 +133,8 @@ class StatsGramplet(Gramplet):
females += 1
elif person.get_gender() == Person.MALE:
males += 1
+ elif person.get_gender() == Person.OTHER:
+ others += 1
else:
unknowns += 1
if not cnt % _YIELD_INTERVAL:
@@ -149,6 +152,10 @@ class StatsGramplet(Gramplet):
self.link(_("%s:") % _("Females"), 'Filter', 'females')
self.append_text(" %s" % females)
self.append_text("\n")
+ self.link(_("%s:") % _("Individuals with other gender"),
+ 'Filter', 'people with other gender')
+ self.append_text(" %s" % others)
+ self.append_text("\n")
self.link(_("%s:") % _("Individuals with unknown gender"),
'Filter', 'people with unknown gender')
self.append_text(" %s" % unknowns)
diff --git a/gramps/plugins/graph/gvfamilylines.py b/gramps/plugins/graph/gvfamilylines.py
index 9215135a4..b64a80ffd 100644
--- a/gramps/plugins/graph/gvfamilylines.py
+++ b/gramps/plugins/graph/gvfamilylines.py
@@ -292,6 +292,11 @@ class FamilyLinesOptions(MenuReportOptions):
color_females.set_help(_('The color to use to display women.'))
add_option('colorfemales', color_females)
+ color_other = ColorOption(_('Other'), '#94ef9e')
+ color_other.set_help(_('The color to use to display people who are '
+ 'neither men nor women.'))
+ add_option('colorother', color_other)
+
color_unknown = ColorOption(_('Unknown'), '#e0e0e0')
color_unknown.set_help(_('The color to use '
'when the gender is unknown.'))
@@ -378,6 +383,7 @@ class FamilyLinesReport(Report):
self._gidlist = get_value('gidlist')
self._colormales = get_value('colormales')
self._colorfemales = get_value('colorfemales')
+ self._colorother = get_value('colorother')
self._colorunknown = get_value('colorunknown')
self._colorfamilies = get_value('colorfamilies')
self._limitparents = get_value('limitparents')
@@ -806,6 +812,8 @@ class FamilyLinesReport(Report):
colour = self._colormales
elif gender == Person.FEMALE:
colour = self._colorfemales
+ elif gender == Person.OTHER:
+ colour = self._colorother
# see if we have surname colours that match this person
surname = person.get_primary_name().get_surname()
diff --git a/gramps/plugins/graph/gvhourglass.py b/gramps/plugins/graph/gvhourglass.py
index 370246666..3656f62ff 100644
--- a/gramps/plugins/graph/gvhourglass.py
+++ b/gramps/plugins/graph/gvhourglass.py
@@ -112,6 +112,7 @@ class HourGlassReport(Report):
self.colorize = menu.get_option_by_name('color').get_value()
self.colors = {'male': menu.get_option_by_name('colormales').get_value(),
'female': menu.get_option_by_name('colorfemales').get_value(),
+ 'other': menu.get_option_by_name('colorother').get_value(),
'unknown': menu.get_option_by_name('colorunknown').get_value(),
'family': menu.get_option_by_name('colorfamilies').get_value()
}
@@ -332,6 +333,8 @@ class HourGlassReport(Report):
color = self.colors['male']
elif gender == person.FEMALE:
color = self.colors['female']
+ elif gender == person.OTHER:
+ color = self.colors['other']
else:
color = self.colors['unknown']
elif self.colorize == 'filled':
@@ -340,6 +343,8 @@ class HourGlassReport(Report):
fill = self.colors['male']
elif gender == person.FEMALE:
fill = self.colors['female']
+ elif gender == person.OTHER:
+ fill = self.colors['other']
else:
fill = self.colors['unknown']
return(shape, style, color, fill)
@@ -426,6 +431,11 @@ class HourGlassOptions(MenuReportOptions):
color_females.set_help(_('The color to use to display women.'))
menu.add_option(category_name, 'colorfemales', color_females)
+ color_other = ColorOption(_('Other'), '#94ef9e')
+ color_other.set_help(_('The color to use to display people who are '
+ 'neither men nor women.'))
+ menu.add_option(category_name, 'colorother', color_other)
+
color_unknown = ColorOption(_('Unknown'), '#e0e0e0')
color_unknown.set_help(_('The color to use '
'when the gender is unknown.'))
diff --git a/gramps/plugins/graph/gvrelgraph.py b/gramps/plugins/graph/gvrelgraph.py
index 71457a33a..9c1f40171 100644
--- a/gramps/plugins/graph/gvrelgraph.py
+++ b/gramps/plugins/graph/gvrelgraph.py
@@ -156,11 +156,13 @@ class RelGraphReport(Report):
self.colorize = get_value('color')
color_males = get_value('colormales')
color_females = get_value('colorfemales')
+ color_other = get_value('colorother')
color_unknown = get_value('colorunknown')
color_families = get_value('colorfamilies')
self.colors = {
'male': color_males,
'female': color_females,
+ 'other': color_other,
'unknown': color_unknown,
'family': color_families
}
@@ -558,6 +560,8 @@ class RelGraphReport(Report):
color = self.colors['male']
elif gender == person.FEMALE:
color = self.colors['female']
+ elif gender == person.OTHER:
+ color = self.colors['other']
else:
color = self.colors['unknown']
elif self.colorize == 'filled':
@@ -566,6 +570,8 @@ class RelGraphReport(Report):
fill = self.colors['male']
elif gender == person.FEMALE:
fill = self.colors['female']
+ elif gender == person.OTHER:
+ fill = self.colors['other']
else:
fill = self.colors['unknown']
return(shape, style, color, fill)
@@ -949,6 +955,11 @@ class RelGraphOptions(MenuReportOptions):
color_females.set_help(_('The color to use to display women.'))
add_option('colorfemales', color_females)
+ color_other = ColorOption(_('Other'), '#94ef9e')
+ color_other.set_help(_('The color to use to display people who are '
+ 'neither men nor women.'))
+ add_option('colorother', color_other)
+
color_unknown = ColorOption(_('Unknown'), '#e0e0e0')
color_unknown.set_help(
_('The color to use when the gender is unknown.')
diff --git a/gramps/plugins/importer/importcsv.py b/gramps/plugins/importer/importcsv.py
index 957287385..61101a7be 100644
--- a/gramps/plugins/importer/importcsv.py
+++ b/gramps/plugins/importer/importcsv.py
@@ -571,6 +571,8 @@ class CSVParser:
gender = Person.MALE
elif gender == gender_map[Person.FEMALE].lower():
gender = Person.FEMALE
+ elif gender == gender_map[Person.OTHER].lower():
+ gender = Person.OTHER
else:
gender = Person.UNKNOWN
child.set_gender(gender)
@@ -720,6 +722,8 @@ class CSVParser:
gender = Person.MALE
elif gender == gender_map[Person.FEMALE].lower():
gender = Person.FEMALE
+ elif gender == gender_map[Person.OTHER].lower():
+ gender = Person.OTHER
else:
gender = Person.UNKNOWN
person.set_gender(gender)
diff --git a/gramps/plugins/importer/importvcard.py b/gramps/plugins/importer/importvcard.py
index 375bb30f2..8e3d3c2fd 100644
--- a/gramps/plugins/importer/importvcard.py
+++ b/gramps/plugins/importer/importvcard.py
@@ -577,6 +577,8 @@ class VCardParser:
gender = Person.MALE
elif gender_value == 'F':
gender = Person.FEMALE
+ elif gender_value == 'O':
+ gender = Person.OTHER
else:
return
self.person.set_gender(gender)
diff --git a/gramps/plugins/importer/importxml.py b/gramps/plugins/importer/importxml.py
index f135c357b..0f5e5fe2d 100644
--- a/gramps/plugins/importer/importxml.py
+++ b/gramps/plugins/importer/importxml.py
@@ -2848,6 +2848,8 @@ class GrampsParser(UpdateCallback):
self.person.set_gender (Person.MALE)
elif t == "F":
self.person.set_gender (Person.FEMALE)
+ elif t == "X":
+ self.person.set_gender (Person.OTHER)
else:
self.person.set_gender (Person.UNKNOWN)
diff --git a/gramps/plugins/lib/libgedcom.py b/gramps/plugins/lib/libgedcom.py
index d180dce1a..eda0e6ac5 100644
--- a/gramps/plugins/lib/libgedcom.py
+++ b/gramps/plugins/lib/libgedcom.py
@@ -597,6 +597,7 @@ QUALITY_MAP = {
SEX_MAP = {
'F' : Person.FEMALE,
'M' : Person.MALE,
+ 'X' : Person.OTHER,
}
FAMILYCONSTANTEVENTS = {
diff --git a/gramps/plugins/lib/libnarrate.py b/gramps/plugins/lib/libnarrate.py
index 33a593ed0..04ea28468 100644
--- a/gramps/plugins/lib/libnarrate.py
+++ b/gramps/plugins/lib/libnarrate.py
@@ -1474,7 +1474,7 @@ class Narrator:
'modified_date' : bdate,
}
- gender = self.__person.get_gender()
+ gender = self.__get_gender()
if bdate:
if bdate_mod:
@@ -1591,7 +1591,7 @@ class Narrator:
'month_year' : ddate,
}
- gender = self.__person.get_gender()
+ gender = self.__get_gender()
if ddate and ddate_mod:
if dplace and self.__verbose:
@@ -1661,7 +1661,7 @@ class Narrator:
else:
name_index = _NAME_INDEX_EXCLUDE_NAME
- gender = self.__person.get_gender()
+ gender = self.__get_gender()
text = ""
@@ -1772,7 +1772,7 @@ class Narrator:
else:
name_index = _NAME_INDEX_EXCLUDE_NAME
- gender = self.__person.get_gender()
+ gender = self.__get_gender()
text = ""
@@ -1883,7 +1883,7 @@ class Narrator:
else:
name_index = _NAME_INDEX_EXCLUDE_NAME
- gender = self.__person.get_gender()
+ gender = self.__get_gender()
text = ""
@@ -2045,7 +2045,7 @@ class Narrator:
elif dobj and dobj.get_day_valid():
date_full = 1
- gender = self.__person.get_gender()
+ gender = self.__get_gender()
# This would be much simpler, excepting for translation considerations
# Currently support FamilyRelType's:
@@ -2214,7 +2214,7 @@ class Narrator:
else:
index = _NAME_INDEX_EXCLUDE_NAME
- gender = self.__person.get_gender()
+ gender = self.__get_gender()
text = ""
if mother_name and father_name and self.__verbose:
@@ -2236,6 +2236,15 @@ class Narrator:
return text
+ def __get_gender(self):
+ """
+ Return a gender to be used for translations.
+ """
+ gender = self.__person.get_gender()
+ if gender == Person.OTHER:
+ gender = Person.UNKNOWN
+ return gender
+
def __get_age_at_death(self):
"""
Calculate the age the person died.
diff --git a/gramps/plugins/quickview/filterbyname.py b/gramps/plugins/quickview/filterbyname.py
index 34ddb04c9..53ea9c3da 100644
--- a/gramps/plugins/quickview/filterbyname.py
+++ b/gramps/plugins/quickview/filterbyname.py
@@ -57,6 +57,8 @@ fname_map = {'all': _('all', 'Filtering_on'),
'all notes': _('all notes', 'Filtering_on'),
'males': _('males', 'Filtering_on'),
'females': _('females', 'Filtering_on'),
+ 'people with other gender':
+ _('people with other gender', 'Filtering_on'),
'people with unknown gender':
_('people with unknown gender', 'Filtering_on'),
'incomplete names':
@@ -294,10 +296,18 @@ def run(database, document, filter_name, *args, **kwargs):
str(person.get_primary_name().get_type()))
matches += 1
+ elif (filter_name == 'people with other gender'):
+ stab.columns(_("Person"), _("Birth Date"), _("Name type"))
+ for person in database.iter_people():
+ if person.gender == Person.OTHER:
+ stab.row(person, sdb.birth_or_fallback(person),
+ str(person.get_primary_name().get_type()))
+ matches += 1
+
elif (filter_name == 'people with unknown gender'):
stab.columns(_("Person"), _("Birth Date"), _("Name type"))
for person in database.iter_people():
- if person.gender not in [Person.FEMALE, Person.MALE]:
+ if person.gender == Person.UNKNOWN:
stab.row(person, sdb.birth_or_fallback(person),
str(person.get_primary_name().get_type()))
matches += 1
diff --git a/gramps/plugins/test/tools_test.py b/gramps/plugins/test/tools_test.py
index 9d915eaf7..80e6cf346 100644
--- a/gramps/plugins/test/tools_test.py
+++ b/gramps/plugins/test/tools_test.py
@@ -145,8 +145,8 @@ class ToolControl(unittest.TestCase):
"1 invalid birth event name was fixed",
"1 invalid death event name was fixed",
"2 places were referenced, but not found",
- "10 citations were referenced, but not found",
- "13 sources were referenced, but not found",
+ "14 citations were referenced, but not found",
+ "17 sources were referenced, but not found",
"9 Duplicated Gramps IDs fixed",
"7 empty objects removed",
"1 person objects",
diff --git a/gramps/plugins/textreport/familygroup.py b/gramps/plugins/textreport/familygroup.py
index a42cc8d38..26b8ff242 100644
--- a/gramps/plugins/textreport/familygroup.py
+++ b/gramps/plugins/textreport/familygroup.py
@@ -503,6 +503,8 @@ class FamilyGroup(Report):
self.doc.write_text(index_str + self._("M", "acronym for male"))
elif person.get_gender() == Person.FEMALE:
self.doc.write_text(index_str + self._("F", "acronym for female"))
+ elif person.get_gender() == Person.OTHER:
+ self.doc.write_text(index_str + self._("X", "acronym for other"))
else:
self.doc.write_text(self._("%dU", "acronym for unknown") % index)
self.doc.end_paragraph()
diff --git a/gramps/plugins/textreport/indivcomplete.py b/gramps/plugins/textreport/indivcomplete.py
index 6fe889139..abe256fa6 100644
--- a/gramps/plugins/textreport/indivcomplete.py
+++ b/gramps/plugins/textreport/indivcomplete.py
@@ -942,6 +942,8 @@ class IndivCompleteReport(Report):
self.write_paragraph(self._("Male"))
elif self.person.get_gender() == Person.FEMALE:
self.write_paragraph(self._("Female"))
+ elif self.person.get_gender() == Person.OTHER:
+ self.write_paragraph(self._("Other"))
else:
self.write_paragraph(self._("Unknown"))
self.write_paragraph(father, mark=fmark)
diff --git a/gramps/plugins/textreport/summary.py b/gramps/plugins/textreport/summary.py
index 0f0f56834..74b5175c9 100644
--- a/gramps/plugins/textreport/summary.py
+++ b/gramps/plugins/textreport/summary.py
@@ -112,6 +112,7 @@ class SummaryReport(Report):
missing_bday = 0
males = 0
females = 0
+ others = 0
unknowns = 0
namelist = []
@@ -160,6 +161,8 @@ class SummaryReport(Report):
females += 1
elif person.get_gender() == Person.MALE:
males += 1
+ elif person.get_gender() == Person.OTHER:
+ others += 1
else:
unknowns += 1
@@ -181,6 +184,11 @@ class SummaryReport(Report):
self.doc.write_text(self._("Females: %d") % females)
self.doc.end_paragraph()
+ self.doc.start_paragraph("SR-Normal")
+ self.doc.write_text(self._("Individuals with other gender: %d"
+ ) % others)
+ self.doc.end_paragraph()
+
self.doc.start_paragraph("SR-Normal")
self.doc.write_text(self._("Individuals with unknown gender: %d"
) % unknowns)
diff --git a/gramps/plugins/tool/testcasegenerator.py b/gramps/plugins/tool/testcasegenerator.py
index 103c2db7a..123b8e203 100644
--- a/gramps/plugins/tool/testcasegenerator.py
+++ b/gramps/plugins/tool/testcasegenerator.py
@@ -1364,8 +1364,11 @@ class TestcaseGenerator(tool.BatchTool):
# Gender
if gender is None:
gender = _randint(0, 1)
- if _randint(0, 10) == 1: # Set some persons to unknown gender
- pers.set_gender(Person.UNKNOWN)
+ if _randint(0, 10) == 1: # Set some persons to unknown and other gender
+ if _randint(0, 1) == 0:
+ pers.set_gender(Person.OTHER)
+ else:
+ pers.set_gender(Person.UNKNOWN)
else:
pers.set_gender(gender)
diff --git a/gramps/plugins/tool/verify.py b/gramps/plugins/tool/verify.py
index adcea2bf2..848c6a81f 100644
--- a/gramps/plugins/tool/verify.py
+++ b/gramps/plugins/tool/verify.py
@@ -1057,9 +1057,7 @@ class UnknownGender(PersonRule):
SEVERITY = Rule.WARNING
def broken(self):
""" return boolean indicating whether this rule is violated """
- female = self.obj.get_gender() == Person.FEMALE
- male = self.obj.get_gender() == Person.MALE
- return not (male or female)
+ return self.obj.get_gender() == Person.UNKNOWN
def get_message(self):
""" return the rule's error message """
diff --git a/gramps/plugins/webreport/person.py b/gramps/plugins/webreport/person.py
index ed82d80bc..44dce57bc 100644
--- a/gramps/plugins/webreport/person.py
+++ b/gramps/plugins/webreport/person.py
@@ -481,6 +481,7 @@ class PersonPages(BasePage):
self.gender_map = {
Person.MALE : self._('male'),
Person.FEMALE : self._('female'),
+ Person.OTHER : self._('other'),
Person.UNKNOWN : self._('unknown'),
}
@@ -1151,6 +1152,8 @@ class PersonPages(BasePage):
divclass = "male"
elif sex == Person.FEMALE:
divclass = "female"
+ elif sex == Person.OTHER:
+ divclass = "other"
else:
divclass = "unknown"
diff --git a/gramps/plugins/webreport/statistics.py b/gramps/plugins/webreport/statistics.py
index 250361db6..a3e4eaf35 100644
--- a/gramps/plugins/webreport/statistics.py
+++ b/gramps/plugins/webreport/statistics.py
@@ -87,6 +87,7 @@ class StatisticsPage(BasePage):
addressbookpage, dummy_head, dummy_body, outerwrapper = result
(males,
females,
+ others,
unknown) = self.get_gender(report.database.iter_person_handles())
step()
@@ -125,6 +126,8 @@ class StatisticsPage(BasePage):
"%d" % males, inline=True)
sec1 += Html("br", self._("Females") + self.colon +
"%d" % females, inline=True)
+ sec1 += Html("br", self._("Individuals with other gender") +
+ self.colon + "%d" % others, inline=True)
sec1 += Html("br", self._("Individuals with unknown gender") +
self.colon + "%d" % unknown, inline=True)
outerwrapper += sec1
@@ -173,6 +176,7 @@ class StatisticsPage(BasePage):
(males,
females,
+ others,
unknown) = self.get_gender(self.report.bkref_dict[Person].keys())
origin = " :
" + report.filter.get_name(self.rlocale)
@@ -190,6 +194,8 @@ class StatisticsPage(BasePage):
"%d" % males, inline=True)
sec5 += Html("br", self._("Females") + self.colon +
"%d" % females, inline=True)
+ sec5 += Html("br", self._("Individuals with other gender") +
+ self.colon + "%d" % others, inline=True)
sec5 += Html("br", self._("Individuals with unknown gender") +
self.colon + "%d" % unknown, inline=True)
outerwrapper += sec5
@@ -229,13 +235,14 @@ class StatisticsPage(BasePage):
def get_gender(self, person_list):
"""
- This function return the number of males, females and unknown gender
- from a person list.
+ This function return the number of males, females, others and unknown
+ gender from a person list.
@param: person_list -- The list to process
"""
males = 0
females = 0
+ others = 0
unknown = 0
for person_handle in person_list:
person = self.report.database.get_person_from_handle(person_handle)
@@ -244,6 +251,8 @@ class StatisticsPage(BasePage):
males += 1
elif gender == Person.FEMALE:
females += 1
+ elif gender == Person.OTHER:
+ others += 1
else:
unknown += 1
- return (males, females, unknown)
+ return (males, females, others, unknown)
diff --git a/images/webstuff/Web_Gender_Other.png b/images/webstuff/Web_Gender_Other.png
new file mode 100644
index 000000000..0f48038b5
Binary files /dev/null and b/images/webstuff/Web_Gender_Other.png differ
diff --git a/po/POTFILES.in b/po/POTFILES.in
index dc945c5a1..c7d642da5 100755
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -181,6 +181,7 @@ gramps/gen/filters/rules/person/_hasnickname.py
gramps/gen/filters/rules/person/_hasnote.py
gramps/gen/filters/rules/person/_hasnotematchingsubstringof.py
gramps/gen/filters/rules/person/_hasnoteregexp.py
+gramps/gen/filters/rules/person/_hasothergender.py
gramps/gen/filters/rules/person/_hasrelationship.py
gramps/gen/filters/rules/person/_hassoundexname.py
gramps/gen/filters/rules/person/_hassourcecount.py