Initial commit

This commit is contained in:
Michael Becker 2024-09-03 00:06:19 -04:00
parent b7f191ba57
commit 0ba989aa59
32 changed files with 15790 additions and 0 deletions

20
apply Executable file
View File

@ -0,0 +1,20 @@
#!/bin/sh
# Person Thumbnails in Family Editor
patch /usr/lib/python3/dist-packages/gramps/gui/editors/editfamily.py person-view-age-calculator/gramps/gui/editors/editfamily.py.patch
patch /usr/lib/python3/dist-packages/gramps/gui/glade/editfamily.glade person-view-age-calculator/gramps/gui/glade/editfamily.glade.patch
# Person View Age Calculator
patch /usr/lib/python3/dist-packages/gramps/gui/editors/editperson.py person-view-age-calculator/gramps/gui/editors/editperson.py.patch
patch /usr/lib/python3/dist-packages/gramps/gui/glade/editperson.glade person-view-age-calculator/gramps/gui/glade/editperson.glade.patch
# Hyperlink Person Associations
patch /usr/lib/python3/dist-packages/gramps/gui/editors/editpersonref.py hyperlink-person-associations/gramps/gu/editors/editpersonref.py.patch
# Enhanced TODO Gramplet
patch /usr/lib/python3/dist-packages/gramps/plugins/gramplet/todogramplet.py enhanced-todo-gramplet/gramps/plugins/gramplet/todogramplet.py.patch
# GeoClose, GeoFamClose
patch /usr/lib/python3/dist-packages/gramps/plugins/view/geoclose.py geo-view-select-active-person/gramps/plugins/view/geoclose.py.patch
patch /usr/lib/python3/dist-packages/gramps/plugins/view/geofamclose.py geo-view-select-active-person/gramps/plugins/view/geofamclose.py.patch

View File

@ -0,0 +1,248 @@
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2007-2009 Douglas S. Blank <doug.blank@gmail.com>
# Copyright (C) 2013 Nick Hall
#
# 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.
#
#-------------------------------------------------------------------------
#
# Gtk modules
#
#-------------------------------------------------------------------------
from gi.repository import Gtk
#-------------------------------------------------------------------------
#
# Gramps modules
#
#-------------------------------------------------------------------------
from gramps.gen.plug import Gramplet
from gramps.gui.widgets.styledtexteditor import StyledTextEditor
from gramps.gui.widgets import SimpleButton
from gramps.gen.lib import StyledText, Note, NoteType
from gramps.gen.filters import GenericFilterFactory, rules
from gramps.gen.utils.db import navigation_label
from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext
class ToDoGramplet(Gramplet):
"""
Displays all the To Do notes in the database.
"""
def init(self):
self.note_type = "To Do"
self.show_toolbar = True
self.gui.WIDGET = self.build_gui()
self.gui.get_container_widget().remove(self.gui.textview)
self.gui.get_container_widget().add(self.gui.WIDGET)
self.gui.WIDGET.show()
def build_options(self):
from gramps.gen.plug.menu import StringOption, BooleanOption
self.add_option(StringOption(_("Note type"),
self.note_type))
self.add_option(BooleanOption(_("Show toolbar"),
self.show_toolbar))
def build_gui(self):
"""
Build the GUI interface.
"""
top = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
hbox = Gtk.Box()
self.left = SimpleButton('go-previous', self.left_clicked)
self.left.set_tooltip_text(_('Previous To Do note'))
self.left.set_sensitive(False)
pack_start(self.left, False, False, 0)
self.right = SimpleButton('go-next', self.right_clicked)
self.right.set_tooltip_text(_('Next To Do note'))
self.right.set_sensitive(False)
hbox.pack_start(self.right, False, False, 0)
self.edit = SimpleButton('gtk-edit', self.edit_clicked)
self.edit.set_tooltip_text(_('Edit the selected To Do note'))
self.edit.set_sensitive(False)
hbox.pack_start(self.edit, False, False, 0)
self.new = SimpleButton('document-new', self.new_clicked)
self.new.set_tooltip_text(_('Add a new To Do note'))
hbox.pack_start(self.new, False, False, 0)
self.page = Gtk.Label()
hbox.pack_end(self.page, False, False, 10)
self.hbox = hbox
self.title = Gtk.Label(halign=Gtk.Align.START)
self.title.set_line_wrap(True)
scrolledwindow = Gtk.ScrolledWindow()
scrolledwindow.set_policy(Gtk.PolicyType.AUTOMATIC,
Gtk.PolicyType.AUTOMATIC)
self.texteditor = StyledTextEditor()
self.texteditor.set_editable(False)
self.texteditor.set_wrap_mode(Gtk.WrapMode.WORD)
scrolledwindow.add(self.texteditor)
top.pack_start(hbox, False, False, 0)
top.pack_start(self.title, False, False, 4)
top.pack_start(scrolledwindow, True, True, 0)
top.show_all()
return top
def save_options(self):
self.note_type = self.get_option(_("Note type")).get_value()
self.show_toolbar = self.get_option(_("Show toolbar")).get_value()
def on_load(self):
if len(self.gui.data) == 2:
self.note_type = self.gui.data[0]
self.show_toolbar = bool(self.gui.data[1])
def save_update_options(self, widget=None):
self.note_type = self.get_option(_("Note type")).get_value()
self.show_toolbar = self.get_option(_("Show toolbar")).get_value()
self.gui.data = [self.note_type, self.show_toolbar]
self.update()
def main(self):
self.get_notes()
def get_note_list(self):
"""
Get a list of all To Do notes.
"""
all_notes = self.dbstate.db.get_note_handles()
FilterClass = GenericFilterFactory('Note')
filter = FilterClass()
filter.add_rule(rules.note.HasType([self.note_type]))
note_list = filter.apply(self.dbstate.db, all_notes)
return note_list
def get_notes(self):
"""
Display all the To Do notes.
"""
self.left.set_sensitive(False)
self.right.set_sensitive(False)
self.edit.set_sensitive(False)
self.texteditor.set_text(StyledText())
self.note_list = self.get_note_list()
self.page.set_text('')
self.title.set_text('')
if len(self.note_list) > 0:
self.set_has_data(True)
self.edit.set_sensitive(True)
if len(self.note_list) > 1:
self.right.set_sensitive(True)
self.current = 0
self.display_note()
else:
self.set_has_data(False)
def clear_text(self):
self.left.set_sensitive(False)
self.right.set_sensitive(False)
self.edit.set_sensitive(False)
self.texteditor.set_text(StyledText())
self.page.set_text('')
self.title.set_text('')
self.current = 0
def display_note(self):
"""
Display the current note.
"""
note_handle = self.note_list[self.current]
note = self.dbstate.db.get_note_from_handle(note_handle)
obj = [x for x in self.dbstate.db.find_backlink_handles(note_handle)]
if obj:
name, obj = navigation_label(self.dbstate.db, obj[0][0], obj[0][1])
self.title.set_text(name)
else:
self.title.set_text(_("Unattached"))
self.texteditor.set_text(note.get_styledtext())
self.page.set_text(_('%(current)d of %(total)d') %
{'current': self.current + 1,
'total': len(self.note_list)})
self.hbox.set_visible(self.show_toolbar)
def left_clicked(self, button):
"""
Display the previous note.
"""
if self.current > 0:
self.current -= 1
self.right.set_sensitive(True)
if self.current == 0:
self.left.set_sensitive(False)
self.display_note()
def right_clicked(self, button):
"""
Display the next note.
"""
if self.current < len(self.note_list) - 1:
self.current += 1
self.left.set_sensitive(True)
if self.current == len(self.note_list) - 1:
self.right.set_sensitive(False)
self.display_note()
def get_has_data(self):
"""
Return True if the gramplet has data, else return False.
"""
if self.get_note_list():
return True
return False
def edit_clicked(self, obj):
"""
Edit current To Do note.
"""
from gramps.gui.editors import EditNote
note_handle = self.note_list[self.current]
note = self.dbstate.db.get_note_from_handle(note_handle)
try:
EditNote(self.gui.dbstate, self.gui.uistate, [], note)
except AttributeError:
pass
def new_clicked(self, obj):
"""
Create a new To Do note.
"""
from gramps.gui.editors import EditNote
note = Note()
note.set_type(self.note_type)
try:
EditNote(self.gui.dbstate, self.gui.uistate, [], note)
except AttributeError:
pass
def update_has_data(self):
self.set_has_data(self.get_has_data())
def db_changed(self):
self.connect(self.dbstate.db, 'note-add', self.update)
self.connect(self.dbstate.db, 'note-delete', self.update)
self.connect(self.dbstate.db, 'note-update', self.update)

View File

@ -0,0 +1,215 @@
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2007-2009 Douglas S. Blank <doug.blank@gmail.com>
# Copyright (C) 2013 Nick Hall
#
# 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.
#
#-------------------------------------------------------------------------
#
# Gtk modules
#
#-------------------------------------------------------------------------
from gi.repository import Gtk
#-------------------------------------------------------------------------
#
# Gramps modules
#
#-------------------------------------------------------------------------
from gramps.gen.plug import Gramplet
from gramps.gui.widgets.styledtexteditor import StyledTextEditor
from gramps.gui.widgets import SimpleButton
from gramps.gen.lib import StyledText, Note, NoteType
from gramps.gen.filters import GenericFilterFactory, rules
from gramps.gen.utils.db import navigation_label
from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext
class ToDoGramplet(Gramplet):
"""
Displays all the To Do notes in the database.
"""
def init(self):
self.gui.WIDGET = self.build_gui()
self.gui.get_container_widget().remove(self.gui.textview)
self.gui.get_container_widget().add(self.gui.WIDGET)
self.gui.WIDGET.show()
def build_gui(self):
"""
Build the GUI interface.
"""
top = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
hbox = Gtk.Box()
self.left = SimpleButton('go-previous', self.left_clicked)
self.left.set_tooltip_text(_('Previous To Do note'))
self.left.set_sensitive(False)
hbox.pack_start(self.left, False, False, 0)
self.right = SimpleButton('go-next', self.right_clicked)
self.right.set_tooltip_text(_('Next To Do note'))
self.right.set_sensitive(False)
hbox.pack_start(self.right, False, False, 0)
self.edit = SimpleButton('gtk-edit', self.edit_clicked)
self.edit.set_tooltip_text(_('Edit the selected To Do note'))
self.edit.set_sensitive(False)
hbox.pack_start(self.edit, False, False, 0)
self.new = SimpleButton('document-new', self.new_clicked)
self.new.set_tooltip_text(_('Add a new To Do note'))
hbox.pack_start(self.new, False, False, 0)
self.page = Gtk.Label()
hbox.pack_end(self.page, False, False, 10)
self.title = Gtk.Label(halign=Gtk.Align.START)
self.title.set_line_wrap(True)
scrolledwindow = Gtk.ScrolledWindow()
scrolledwindow.set_policy(Gtk.PolicyType.AUTOMATIC,
Gtk.PolicyType.AUTOMATIC)
self.texteditor = StyledTextEditor()
self.texteditor.set_editable(False)
self.texteditor.set_wrap_mode(Gtk.WrapMode.WORD)
scrolledwindow.add(self.texteditor)
top.pack_start(hbox, False, False, 0)
top.pack_start(self.title, False, False, 4)
top.pack_start(scrolledwindow, True, True, 0)
top.show_all()
return top
def main(self):
self.get_notes()
def get_note_list(self):
"""
Get a list of all To Do notes.
"""
all_notes = self.dbstate.db.get_note_handles()
FilterClass = GenericFilterFactory('Note')
filter = FilterClass()
filter.add_rule(rules.note.HasType(["To Do"]))
note_list = filter.apply(self.dbstate.db, all_notes)
return note_list
def get_notes(self):
"""
Display all the To Do notes.
"""
self.left.set_sensitive(False)
self.right.set_sensitive(False)
self.edit.set_sensitive(False)
self.texteditor.set_text(StyledText())
self.note_list = self.get_note_list()
self.page.set_text('')
self.title.set_text('')
if len(self.note_list) > 0:
self.set_has_data(True)
self.edit.set_sensitive(True)
if len(self.note_list) > 1:
self.right.set_sensitive(True)
self.current = 0
self.display_note()
else:
self.set_has_data(False)
def clear_text(self):
self.left.set_sensitive(False)
self.right.set_sensitive(False)
self.edit.set_sensitive(False)
self.texteditor.set_text(StyledText())
self.page.set_text('')
self.title.set_text('')
self.current = 0
def display_note(self):
"""
Display the current note.
"""
note_handle = self.note_list[self.current]
note = self.dbstate.db.get_note_from_handle(note_handle)
obj = [x for x in self.dbstate.db.find_backlink_handles(note_handle)]
if obj:
name, obj = navigation_label(self.dbstate.db, obj[0][0], obj[0][1])
self.title.set_text(name)
else:
self.title.set_text(_("Unattached"))
self.texteditor.set_text(note.get_styledtext())
self.page.set_text(_('%(current)d of %(total)d') %
{'current': self.current + 1,
'total': len(self.note_list)})
def left_clicked(self, button):
"""
Display the previous note.
"""
if self.current > 0:
self.current -= 1
self.right.set_sensitive(True)
if self.current == 0:
self.left.set_sensitive(False)
self.display_note()
def right_clicked(self, button):
"""
Display the next note.
"""
if self.current < len(self.note_list) - 1:
self.current += 1
self.left.set_sensitive(True)
if self.current == len(self.note_list) - 1:
self.right.set_sensitive(False)
self.display_note()
def get_has_data(self):
"""
Return True if the gramplet has data, else return False.
"""
if self.get_note_list():
return True
return False
def edit_clicked(self, obj):
"""
Edit current To Do note.
"""
from gramps.gui.editors import EditNote
note_handle = self.note_list[self.current]
note = self.dbstate.db.get_note_from_handle(note_handle)
try:
EditNote(self.gui.dbstate, self.gui.uistate, [], note)
except AttributeError:
pass
def new_clicked(self, obj):
"""
Create a new To Do note.
"""
from gramps.gui.editors import EditNote
note = Note()
note.set_type(NoteType.TODO)
try:
EditNote(self.gui.dbstate, self.gui.uistate, [], note)
except AttributeError:
pass
def update_has_data(self):
self.set_has_data(self.get_has_data())
def db_changed(self):
self.connect(self.dbstate.db, 'note-add', self.update)
self.connect(self.dbstate.db, 'note-delete', self.update)
self.connect(self.dbstate.db, 'note-update', self.update)

View File

@ -0,0 +1,50 @@
46a47,49
> self.note_type = "To Do"
> self.show_toolbar = True
>
51a55,63
>
> def build_options(self):
> from gramps.gen.plug.menu import StringOption, BooleanOption
>
> self.add_option(StringOption(_("Note type"),
> self.note_type))
> self.add_option(BooleanOption(_("Show toolbar"),
> self.show_toolbar))
>
62c74
< hbox.pack_start(self.left, False, False, 0)
---
> pack_start(self.left, False, False, 0)
76a89,90
> self.hbox = hbox
>
93a108,124
> def save_options(self):
> self.note_type = self.get_option(_("Note type")).get_value()
> self.show_toolbar = self.get_option(_("Show toolbar")).get_value()
>
>
> def on_load(self):
> if len(self.gui.data) == 2:
> self.note_type = self.gui.data[0]
> self.show_toolbar = bool(self.gui.data[1])
>
> def save_update_options(self, widget=None):
> self.note_type = self.get_option(_("Note type")).get_value()
> self.show_toolbar = self.get_option(_("Show toolbar")).get_value()
> self.gui.data = [self.note_type, self.show_toolbar]
>
> self.update()
>
104c135
< filter.add_rule(rules.note.HasType(["To Do"]))
---
> filter.add_rule(rules.note.HasType([self.note_type]))
154a186,187
> self.hbox.set_visible(self.show_toolbar)
>
203c236
< note.set_type(NoteType.TODO)
---
> note.set_type(self.note_type)

View File

@ -0,0 +1,715 @@
# -*- python -*-
# -*- coding: utf-8 -*-
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2011-2016 Serge Noiraud
#
# 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.
#
"""
Geography for two persons
"""
#-------------------------------------------------------------------------
#
# Python modules
#
#-------------------------------------------------------------------------
from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext
import operator
from gi.repository import Gtk
from math import hypot
from html import escape
#-------------------------------------------------------------------------
#
# set up logging
#
#-------------------------------------------------------------------------
import logging
_LOG = logging.getLogger("GeoGraphy.geoclose")
#-------------------------------------------------------------------------
#
# Gramps Modules
#
#-------------------------------------------------------------------------
from gramps.gen.lib import EventRoleType, EventType
from gramps.gen.config import config
from gramps.gen.datehandler import displayer, get_date
from gramps.gen.display.name import displayer as _nd
from gramps.gen.display.place import displayer as _pd
from gramps.gen.utils.place import conv_lat_lon
from gramps.gui.views.bookmarks import PersonBookmarks
from gramps.plugins.lib.maps import constants
from gramps.plugins.lib.maps.geography import GeoGraphyView
from gramps.gui.selectors import SelectorFactory
from gramps.gen.utils.db import (get_birth_or_fallback, get_death_or_fallback)
from gramps.gui.uimanager import ActionGroup
#-------------------------------------------------------------------------
#
# Constants
#
#-------------------------------------------------------------------------
_UI_DEF = [
'''
<placeholder id="CommonGo">
<section>
<item>
<attribute name="action">win.Back</attribute>
<attribute name="label" translatable="yes">_Back</attribute>
</item>
<item>
<attribute name="action">win.Forward</attribute>
<attribute name="label" translatable="yes">_Forward</attribute>
</item>
</section>
<section>
<item>
<attribute name="action">win.HomePerson</attribute>
<attribute name="label" translatable="yes">_Home</attribute>
</item>
</section>
</placeholder>
''',
'''
<section id='CommonEdit' groups='RW'>
<item>
<attribute name="action">win.PrintView</attribute>
<attribute name="label" translatable="yes">Print...</attribute>
</item>
</section>
''',
'''
<section id="AddEditBook">
<item>
<attribute name="action">win.AddBook</attribute>
<attribute name="label" translatable="yes">_Add Bookmark</attribute>
</item>
<item>
<attribute name="action">win.EditBook</attribute>
<attribute name="label" translatable="no">%s...</attribute>
</item>
</section>
''' % _('Organize Bookmarks'), # Following are the Toolbar items
'''
<placeholder id='CommonNavigation'>
<child groups='RO'>
<object class="GtkToolButton">
<property name="icon-name">go-previous</property>
<property name="action-name">win.Back</property>
<property name="tooltip_text" translatable="yes">'''
'''Go to the previous object in the history</property>
<property name="label" translatable="yes">_Back</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child groups='RO'>
<object class="GtkToolButton">
<property name="icon-name">go-next</property>
<property name="action-name">win.Forward</property>
<property name="tooltip_text" translatable="yes">'''
'''Go to the next object in the history</property>
<property name="label" translatable="yes">_Forward</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child groups='RO'>
<object class="GtkToolButton">
<property name="icon-name">go-home</property>
<property name="action-name">win.HomePerson</property>
<property name="tooltip_text" translatable="yes">'''
'''Go to the home person</property>
<property name="label" translatable="yes">_Home</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child groups='RO'>
<object class="GtkToolButton">
<property name="icon-name">gramps-person</property>
<property name="action-name">win.RefPerson</property>
<property name="tooltip_text" translatable="yes">'''
'''Select the person which is the reference for life ways</property>
<property name="label" translatable="yes">reference _Person</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
</placeholder>
''',
'''
<placeholder id='BarCommonEdit'>
<child groups='RO'>
<object class="GtkToolButton">
<property name="icon-name">document-print</property>
<property name="action-name">win.PrintView</property>
<property name="tooltip_text" translatable="yes">'''
'''Print or save the Map</property>
<property name="label" translatable="yes">Print...</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
</placeholder>
''']
# pylint: disable=no-member
# pylint: disable=unused-argument
#-------------------------------------------------------------------------
#
# GeoView
#
#-------------------------------------------------------------------------
class GeoClose(GeoGraphyView):
"""
The view used to render person map.
"""
CONFIGSETTINGS = (
('geography.path', constants.GEOGRAPHY_PATH),
('geography.zoom', 10),
('geography.zoom_when_center', 12),
('geography.show_cross', True),
('geography.lock', False),
('geography.center-lat', 0.0),
('geography.center-lon', 0.0),
('geography.use-keypad', True),
('geography.map_service', constants.OPENSTREETMAP),
('geography.max_places', 5000),
# specific to geoclose :
('geography.color1', 'blue'),
('geography.color2', 'green'),
('geography.maximum_meeting_zone', 5),
)
def __init__(self, pdata, dbstate, uistate, nav_group=0):
GeoGraphyView.__init__(self, _("Have they been able to meet?"),
pdata, dbstate, uistate,
PersonBookmarks,
nav_group)
self.dbstate = dbstate
self.uistate = uistate
self.place_list = []
self.all_place_list = []
self.place_without_coordinates = []
self.minlat = self.maxlat = self.minlon = self.maxlon = 0.0
self.minyear = 9999
self.maxyear = 0
self.refperson = None
self.refperson_bookmark = None
self.nbplaces = 0
self.nbmarkers = 0
self.sort = []
self.tracks = []
self.additional_uis.append(self.additional_ui())
self.ref_person = None
self.skip_list = []
self.track = []
self.place_list_active = []
self.place_list_ref = []
self.cal = config.get('preferences.calendar-format-report')
self.no_show_places_in_status_bar = False
self.add_item = None
self.newmenu = None
self.config_meeting_slider = None
self.dbstate.connect('database-changed', self.reset_change_db)
def reset_change_db(self, dummy_dbase):
"""
Used to reset the family reference
"""
self.refperson = None
def get_title(self):
"""
Used to set the titlebar in the configuration window.
"""
return _('GeoClose')
def get_stock(self):
"""
Returns the name of the stock icon to use for the display.
This assumes that this icon has already been registered
as a stock icon.
"""
return 'gramps-relation'
def get_viewtype_stock(self):
"""Type of view in category
"""
return 'geo-show-family'
def additional_ui(self):
"""
Specifies the UIManager XML code that defines the menus and buttons
associated with the interface.
"""
return _UI_DEF
def navigation_type(self):
"""
Indicates the navigation type. Navigation type can be the string
name of any of the primary objects.
"""
return 'Person'
def goto_handle(self, handle=None):
"""
Rebuild the tree with the given person handle as the root.
"""
self.place_list_active = []
self.place_list_ref = []
self.all_place_list = []
self.sort = []
self.places_found = []
self.nbmarkers = 0
self.nbplaces = 0
self.place_without_coordinates = []
self.remove_all_gps()
self.remove_all_markers()
self.lifeway_layer.clear_ways()
self.message_layer.clear_messages()
self.message_layer.set_font_attributes(None, None, None)
active = self.get_active()
if active:
indiv1 = self.dbstate.db.get_person_from_handle(active)
color = self._config.get('geography.color2')
self._createmap(indiv1, color, self.place_list_active, False)
if self.refperson:
color = self._config.get('geography.color1')
self.message_layer.add_message(
_("Reference : %(name)s ( %(birth)s - %(death)s )") % {
'name': _nd.display(self.refperson),
'birth': self.birth(self.refperson),
'death': self.death(self.refperson)})
if indiv1:
self.message_layer.add_message(
_("The other : %(name)s ( %(birth)s - %(death)s )") % {
'name': _nd.display(indiv1),
'birth': self.birth(indiv1),
'death': self.death(indiv1)})
else:
self.message_layer.add_message(_("The other person is unknown"))
self._createmap(self.refperson, color, self.place_list_ref, True)
if self.refperson_bookmark is None:
self.refperson_bookmark = self.refperson.get_handle()
self.add_bookmark_from_popup(None, self.refperson_bookmark)
else:
self.message_layer.add_message(
_("You must choose one reference person."))
self.message_layer.add_message(_("Go to the person view and select "
"the people you want to compare. "
"Return to this view and use the"
" history."))
self.possible_meeting(self.place_list_ref, self.place_list_active)
self.uistate.modify_statusbar(self.dbstate)
def birth(self, person):
"""
return "" or the birth date of the person
"""
birth = get_birth_or_fallback(self.dbstate.db, person)
if birth and birth.get_type() != EventType.BIRTH:
sdate = get_date(birth)
if sdate:
bdate = "<i>%s</i>" % escape(sdate)
else:
bdate = ""
elif birth:
bdate = escape(get_date(birth))
else:
bdate = ""
return bdate
def death(self, person):
"""
return "" or the death date of the person
"""
death = get_death_or_fallback(self.dbstate.db, person)
if death and death.get_type() != EventType.DEATH:
sdate = get_date(death)
if sdate:
ddate = "<i>%s</i>" % escape(sdate)
else:
ddate = ""
elif death:
ddate = escape(get_date(death))
else:
ddate = ""
return ddate
def define_actions(self):
"""
Define action for the reference person button.
"""
GeoGraphyView.define_actions(self)
self._add_action('RefPerson', self.select_person)
def select_person(self, *obj):
"""
Open a selection box to choose the ref person.
"""
self.track = []
self.skip_list = []
self.refperson = None
self.refperson_bookmark = None
selectperson = SelectorFactory('Person')
sel = selectperson(self.dbstate, self.uistate, self.track,
_("Select the person which will be our reference."),
skip=self.skip_list)
self.refperson = sel.run()
self.goto_handle(None)
def select_person2(self, *obj):
"""
Open a selection box to choose the secondary person.
"""
selectperson = SelectorFactory('Person')
sel = selectperson(self.dbstate, self.uistate, self.track,
_("Select the person which will be our active."),
skip=self.skip_list)
self.uistate.set_active(sel.run().get_handle(), 'Person')
self.goto_handle(None)
def build_tree(self):
"""
This is called by the parent class when the view becomes visible. Since
all handling of visibility is now in rebuild_trees, see that for more
information.
"""
self.lifeway_layer.clear_ways()
if not self.dbstate.is_open():
return
active = self.get_active()
if active:
person = self.dbstate.db.get_person_from_handle(active)
if person is None:
self.goto_handle(None)
else:
self.goto_handle(handle=person)
else:
self.goto_handle(None)
def draw(self, menu, marks, color, reference):
"""
Create all moves for the people's event.
"""
points = []
mark = None
for mark in marks:
startlat = float(mark[3])
startlon = float(mark[4])
not_stored = True
for idx in range(0, len(points)):
if points[idx][0] == startlat and points[idx][1] == startlon:
not_stored = False
if not_stored:
points.append((startlat, startlon))
self.lifeway_layer.add_way(points, color)
if reference:
self.lifeway_layer.add_way_ref(points, 'orange',
float(self._config.get("geography.maximum_meeting_zone")) / 10)
return False
def possible_meeting(self, place_list_ref, place_list_active):
"""
Try to see if two persons can be to the same place during their life.
If yes, show a marker with the dates foe each person.
"""
radius = float(self._config.get("geography.maximum_meeting_zone")/10.0)
for ref in place_list_ref:
for act in place_list_active:
if (hypot(float(act[3])-float(ref[3]),
float(act[4])-float(ref[4])) <= radius) == True:
# we are in the meeting zone
self.add_marker(None, None, act[3], act[4], act[7], True, 1)
self.all_place_list.append(act)
self.add_marker(None, None, ref[3], ref[4], ref[7], True, 1)
self.all_place_list.append(ref)
def _createmap(self, person, color, place_list, reference):
"""
Create all markers for each people's event in the database which has
a lat/lon.
"""
dbstate = self.dbstate
self.cal = config.get('preferences.calendar-format-report')
self.place_list = place_list
self.place_without_coordinates = []
self.minlat = self.maxlat = self.minlon = self.maxlon = 0.0
self.minyear = 9999
self.maxyear = 0
latitude = ""
longitude = ""
if person is not None:
# For each event, if we have a place, set a marker.
for event_ref in person.get_event_ref_list():
if not event_ref:
continue
event = dbstate.db.get_event_from_handle(event_ref.ref)
role = event_ref.get_role()
try:
date = event.get_date_object().to_calendar(self.cal)
except:
continue
eyear = str("%04d" % date.get_year()) + \
str("%02d" % date.get_month()) + \
str("%02d" % date.get_day())
place_handle = event.get_place_handle()
if place_handle:
place = dbstate.db.get_place_from_handle(place_handle)
if place:
longitude = place.get_longitude()
latitude = place.get_latitude()
latitude, longitude = conv_lat_lon(latitude,
longitude, "D.D8")
descr = _pd.display(dbstate.db, place)
evt = EventType(event.get_type())
descr1 = _("%(eventtype)s : %(name)s") % {
'eventtype': evt,
'name': _nd.display(person)}
# place.get_longitude and place.get_latitude return
# one string. We have coordinates when the two values
# contains non null string.
if longitude and latitude:
self._append_to_places_list(descr, evt,
_nd.display(person),
latitude, longitude,
descr1, eyear,
event.get_type(),
person.gramps_id,
place.gramps_id,
event.gramps_id,
role
)
else:
self._append_to_places_without_coord(
place.gramps_id, descr)
family_list = person.get_family_handle_list()
descr1 = " - "
for family_hdl in family_list:
family = self.dbstate.db.get_family_from_handle(family_hdl)
if family is not None:
fhandle = family_list[0] # first is primary
fam = dbstate.db.get_family_from_handle(fhandle)
handle = fam.get_father_handle()
descr1 = " - "
if handle:
father = dbstate.db.get_person_from_handle(handle)
if father:
descr1 = "%s - " % _nd.display(father)
handle = fam.get_mother_handle()
if handle:
mother = dbstate.db.get_person_from_handle(handle)
if mother:
descr1 = "%s%s" % (descr1, _nd.display(mother))
for event_ref in family.get_event_ref_list():
if event_ref:
event = dbstate.db.get_event_from_handle(
event_ref.ref)
role = event_ref.get_role()
if event.get_place_handle():
place_handle = event.get_place_handle()
if place_handle:
place = dbstate.db.get_place_from_handle(
place_handle)
if place:
longitude = place.get_longitude()
latitude = place.get_latitude()
latitude, longitude = conv_lat_lon(
latitude, longitude, "D.D8")
descr = _pd.display(dbstate.db, place)
evt = EventType(event.get_type())
eyear = str(
"%04d" % event.get_date_object().to_calendar(self.cal).get_year()) + \
str("%02d" % event.get_date_object().to_calendar(self.cal).get_month()) + \
str("%02d" % event.get_date_object().to_calendar(self.cal).get_day())
if longitude and latitude:
self._append_to_places_list(descr,
evt, _nd.display(person),
latitude, longitude,
descr1, eyear,
event.get_type(),
person.gramps_id,
place.gramps_id,
event.gramps_id,
role
)
else:
self._append_to_places_without_coord(place.gramps_id, descr)
sort1 = sorted(self.place_list, key=operator.itemgetter(6))
self.draw(None, sort1, color, reference)
# merge with the last results
merge_list = []
for the_list in self.sort, sort1:
merge_list += the_list
self.sort = sorted(merge_list, key=operator.itemgetter(6))
def bubble_message(self, event, lat, lon, marks):
"""
Create the menu for the selected marker
"""
self.newmenu = Gtk.Menu()
menu = self.newmenu
menu.set_title("person")
events = []
message = ""
oldplace = ""
prevmark = None
for mark in marks:
for plce in self.all_place_list:
if plce[3] == mark[3] and plce[4] == mark[4]:
if plce[10] in events:
continue
else:
events.append(plce[10])
if plce[0] != oldplace:
message = "%s :" % plce[0]
self.add_place_bubble_message(event, lat, lon,
marks, menu,
message, plce)
oldplace = plce[0]
message = ""
evt = self.dbstate.db.get_event_from_gramps_id(plce[10])
# format the date as described in preferences.
date = displayer.display(evt.get_date_object())
if date == "":
date = _("Unknown")
if plce[11] == EventRoleType.PRIMARY:
message = "(%s) %s : %s" % (date, plce[2], plce[1])
elif plce[11] == EventRoleType.FAMILY:
(father_name,
mother_name) = self._get_father_and_mother_name(evt)
message = "(%s) %s : %s - %s" % (date, plce[7],
father_name,
mother_name)
else:
descr = evt.get_description()
if descr == "":
descr = _('No description')
message = "(%s) %s => %s" % (date, plce[11], descr)
prevmark = plce
self.add_item = Gtk.MenuItem(label=message)
add_item = self.add_item
add_item.show()
menu.append(add_item)
self.itemoption = Gtk.Menu()
itemoption = self.itemoption
itemoption.set_title(message)
itemoption.show()
add_item.set_submenu(itemoption)
modify = Gtk.MenuItem(label=_("Edit Event"))
modify.show()
modify.connect("activate", self.edit_event,
event, lat, lon, prevmark)
itemoption.append(modify)
center = Gtk.MenuItem(label=_("Center on this place"))
center.show()
center.connect("activate", self.center_here,
event, lat, lon, prevmark)
itemoption.append(center)
menu.show()
menu.popup(None, None, None,
None, event.button, event.time)
return 0
def add_specific_menu(self, menu, event, lat, lon):
"""
Add specific entry to the navigation menu.
"""
add_item = Gtk.MenuItem()
add_item.show()
menu.append(add_item)
add_item = Gtk.MenuItem(
label=_("Choose and bookmark the new reference person"))
add_item.connect("activate", self.select_person)
add_item.show()
menu.append(add_item)
add_item = Gtk.MenuItem(
label=_("Choose the new active person"))
add_item.connect("activate", self.select_person2)
add_item.show()
menu.append(add_item)
return
def get_default_gramplets(self):
"""
Define the default gramplets for the sidebar and bottombar.
"""
return (("Person Filter",),
())
def specific_options(self, configdialog):
"""
Add specific entry to the preference menu.
Must be done in the associated view.
"""
grid = Gtk.Grid()
grid.set_border_width(12)
grid.set_column_spacing(6)
grid.set_row_spacing(6)
configdialog.add_text(grid,
_('The meeting zone probability radius.\n'
'The colored zone is approximative.\n'
'The meeting zone is only shown for the reference person.\n'
'The value 9 means about 42 miles or 67 kms.\n'
'The value 1 means about 4.6 miles or 7.5 kms.\n'
'The value is in tenth of degree.'),
1, line_wrap=False)
self.config_meeting_slider = configdialog.add_slider(grid,
"",
2, 'geography.maximum_meeting_zone',
(1, 9))
return _('The selection parameters'), grid
def config_connect(self):
"""
used to monitor changes in the ini file
"""
self._config.connect('geography.maximum_meeting_zone',
self.cb_update_meeting_radius)
def cb_update_meeting_radius(self, client, cnxn_id, entry, data):
"""
Called when the radius change
"""
self.goto_handle(handle=None)

View File

@ -0,0 +1,698 @@
# -*- python -*-
# -*- coding: utf-8 -*-
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2011-2016 Serge Noiraud
#
# 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.
#
"""
Geography for two persons
"""
#-------------------------------------------------------------------------
#
# Python modules
#
#-------------------------------------------------------------------------
from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext
import operator
from gi.repository import Gtk
from math import hypot
from html import escape
#-------------------------------------------------------------------------
#
# set up logging
#
#-------------------------------------------------------------------------
import logging
_LOG = logging.getLogger("GeoGraphy.geoclose")
#-------------------------------------------------------------------------
#
# Gramps Modules
#
#-------------------------------------------------------------------------
from gramps.gen.lib import EventRoleType, EventType
from gramps.gen.config import config
from gramps.gen.datehandler import displayer, get_date
from gramps.gen.display.name import displayer as _nd
from gramps.gen.display.place import displayer as _pd
from gramps.gen.utils.place import conv_lat_lon
from gramps.gui.views.bookmarks import PersonBookmarks
from gramps.plugins.lib.maps import constants
from gramps.plugins.lib.maps.geography import GeoGraphyView
from gramps.gui.selectors import SelectorFactory
from gramps.gen.utils.db import (get_birth_or_fallback, get_death_or_fallback)
from gramps.gui.uimanager import ActionGroup
#-------------------------------------------------------------------------
#
# Constants
#
#-------------------------------------------------------------------------
_UI_DEF = [
'''
<placeholder id="CommonGo">
<section>
<item>
<attribute name="action">win.Back</attribute>
<attribute name="label" translatable="yes">_Back</attribute>
</item>
<item>
<attribute name="action">win.Forward</attribute>
<attribute name="label" translatable="yes">_Forward</attribute>
</item>
</section>
<section>
<item>
<attribute name="action">win.HomePerson</attribute>
<attribute name="label" translatable="yes">_Home</attribute>
</item>
</section>
</placeholder>
''',
'''
<section id='CommonEdit' groups='RW'>
<item>
<attribute name="action">win.PrintView</attribute>
<attribute name="label" translatable="yes">Print...</attribute>
</item>
</section>
''',
'''
<section id="AddEditBook">
<item>
<attribute name="action">win.AddBook</attribute>
<attribute name="label" translatable="yes">_Add Bookmark</attribute>
</item>
<item>
<attribute name="action">win.EditBook</attribute>
<attribute name="label" translatable="no">%s...</attribute>
</item>
</section>
''' % _('Organize Bookmarks'), # Following are the Toolbar items
'''
<placeholder id='CommonNavigation'>
<child groups='RO'>
<object class="GtkToolButton">
<property name="icon-name">go-previous</property>
<property name="action-name">win.Back</property>
<property name="tooltip_text" translatable="yes">'''
'''Go to the previous object in the history</property>
<property name="label" translatable="yes">_Back</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child groups='RO'>
<object class="GtkToolButton">
<property name="icon-name">go-next</property>
<property name="action-name">win.Forward</property>
<property name="tooltip_text" translatable="yes">'''
'''Go to the next object in the history</property>
<property name="label" translatable="yes">_Forward</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child groups='RO'>
<object class="GtkToolButton">
<property name="icon-name">go-home</property>
<property name="action-name">win.HomePerson</property>
<property name="tooltip_text" translatable="yes">'''
'''Go to the home person</property>
<property name="label" translatable="yes">_Home</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child groups='RO'>
<object class="GtkToolButton">
<property name="icon-name">gramps-person</property>
<property name="action-name">win.RefPerson</property>
<property name="tooltip_text" translatable="yes">'''
'''Select the person which is the reference for life ways</property>
<property name="label" translatable="yes">reference _Person</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
</placeholder>
''',
'''
<placeholder id='BarCommonEdit'>
<child groups='RO'>
<object class="GtkToolButton">
<property name="icon-name">document-print</property>
<property name="action-name">win.PrintView</property>
<property name="tooltip_text" translatable="yes">'''
'''Print or save the Map</property>
<property name="label" translatable="yes">Print...</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
</placeholder>
''']
# pylint: disable=no-member
# pylint: disable=unused-argument
#-------------------------------------------------------------------------
#
# GeoView
#
#-------------------------------------------------------------------------
class GeoClose(GeoGraphyView):
"""
The view used to render person map.
"""
CONFIGSETTINGS = (
('geography.path', constants.GEOGRAPHY_PATH),
('geography.zoom', 10),
('geography.zoom_when_center', 12),
('geography.show_cross', True),
('geography.lock', False),
('geography.center-lat', 0.0),
('geography.center-lon', 0.0),
('geography.use-keypad', True),
('geography.map_service', constants.OPENSTREETMAP),
('geography.max_places', 5000),
# specific to geoclose :
('geography.color1', 'blue'),
('geography.color2', 'green'),
('geography.maximum_meeting_zone', 5),
)
def __init__(self, pdata, dbstate, uistate, nav_group=0):
GeoGraphyView.__init__(self, _("Have they been able to meet?"),
pdata, dbstate, uistate,
PersonBookmarks,
nav_group)
self.dbstate = dbstate
self.uistate = uistate
self.place_list = []
self.all_place_list = []
self.place_without_coordinates = []
self.minlat = self.maxlat = self.minlon = self.maxlon = 0.0
self.minyear = 9999
self.maxyear = 0
self.refperson = None
self.refperson_bookmark = None
self.nbplaces = 0
self.nbmarkers = 0
self.sort = []
self.tracks = []
self.additional_uis.append(self.additional_ui())
self.ref_person = None
self.skip_list = []
self.track = []
self.place_list_active = []
self.place_list_ref = []
self.cal = config.get('preferences.calendar-format-report')
self.no_show_places_in_status_bar = False
self.add_item = None
self.newmenu = None
self.config_meeting_slider = None
self.dbstate.connect('database-changed', self.reset_change_db)
def reset_change_db(self, dummy_dbase):
"""
Used to reset the family reference
"""
self.refperson = None
def get_title(self):
"""
Used to set the titlebar in the configuration window.
"""
return _('GeoClose')
def get_stock(self):
"""
Returns the name of the stock icon to use for the display.
This assumes that this icon has already been registered
as a stock icon.
"""
return 'gramps-relation'
def get_viewtype_stock(self):
"""Type of view in category
"""
return 'geo-show-family'
def additional_ui(self):
"""
Specifies the UIManager XML code that defines the menus and buttons
associated with the interface.
"""
return _UI_DEF
def navigation_type(self):
"""
Indicates the navigation type. Navigation type can be the string
name of any of the primary objects.
"""
return 'Person'
def goto_handle(self, handle=None):
"""
Rebuild the tree with the given person handle as the root.
"""
self.place_list_active = []
self.place_list_ref = []
self.all_place_list = []
self.sort = []
self.places_found = []
self.nbmarkers = 0
self.nbplaces = 0
self.place_without_coordinates = []
self.remove_all_gps()
self.remove_all_markers()
self.lifeway_layer.clear_ways()
self.message_layer.clear_messages()
self.message_layer.set_font_attributes(None, None, None)
active = self.get_active()
if active:
indiv1 = self.dbstate.db.get_person_from_handle(active)
color = self._config.get('geography.color2')
self._createmap(indiv1, color, self.place_list_active, False)
if self.refperson:
color = self._config.get('geography.color1')
self.message_layer.add_message(
_("Reference : %(name)s ( %(birth)s - %(death)s )") % {
'name': _nd.display(self.refperson),
'birth': self.birth(self.refperson),
'death': self.death(self.refperson)})
if indiv1:
self.message_layer.add_message(
_("The other : %(name)s ( %(birth)s - %(death)s )") % {
'name': _nd.display(indiv1),
'birth': self.birth(indiv1),
'death': self.death(indiv1)})
else:
self.message_layer.add_message(_("The other person is unknown"))
self._createmap(self.refperson, color, self.place_list_ref, True)
if self.refperson_bookmark is None:
self.refperson_bookmark = self.refperson.get_handle()
self.add_bookmark_from_popup(None, self.refperson_bookmark)
else:
self.message_layer.add_message(
_("You must choose one reference person."))
self.message_layer.add_message(_("Go to the person view and select "
"the people you want to compare. "
"Return to this view and use the"
" history."))
self.possible_meeting(self.place_list_ref, self.place_list_active)
self.uistate.modify_statusbar(self.dbstate)
def birth(self, person):
"""
return "" or the birth date of the person
"""
birth = get_birth_or_fallback(self.dbstate.db, person)
if birth and birth.get_type() != EventType.BIRTH:
sdate = get_date(birth)
if sdate:
bdate = "<i>%s</i>" % escape(sdate)
else:
bdate = ""
elif birth:
bdate = escape(get_date(birth))
else:
bdate = ""
return bdate
def death(self, person):
"""
return "" or the death date of the person
"""
death = get_death_or_fallback(self.dbstate.db, person)
if death and death.get_type() != EventType.DEATH:
sdate = get_date(death)
if sdate:
ddate = "<i>%s</i>" % escape(sdate)
else:
ddate = ""
elif death:
ddate = escape(get_date(death))
else:
ddate = ""
return ddate
def define_actions(self):
"""
Define action for the reference person button.
"""
GeoGraphyView.define_actions(self)
self._add_action('RefPerson', self.select_person)
def select_person(self, *obj):
"""
Open a selection box to choose the ref person.
"""
self.track = []
self.skip_list = []
self.refperson = None
self.refperson_bookmark = None
selectperson = SelectorFactory('Person')
sel = selectperson(self.dbstate, self.uistate, self.track,
_("Select the person which will be our reference."),
skip=self.skip_list)
self.refperson = sel.run()
self.goto_handle(None)
def build_tree(self):
"""
This is called by the parent class when the view becomes visible. Since
all handling of visibility is now in rebuild_trees, see that for more
information.
"""
self.lifeway_layer.clear_ways()
if not self.dbstate.is_open():
return
active = self.get_active()
if active:
person = self.dbstate.db.get_person_from_handle(active)
if person is None:
self.goto_handle(None)
else:
self.goto_handle(handle=person)
else:
self.goto_handle(None)
def draw(self, menu, marks, color, reference):
"""
Create all moves for the people's event.
"""
points = []
mark = None
for mark in marks:
startlat = float(mark[3])
startlon = float(mark[4])
not_stored = True
for idx in range(0, len(points)):
if points[idx][0] == startlat and points[idx][1] == startlon:
not_stored = False
if not_stored:
points.append((startlat, startlon))
self.lifeway_layer.add_way(points, color)
if reference:
self.lifeway_layer.add_way_ref(points, 'orange',
float(self._config.get("geography.maximum_meeting_zone")) / 10)
return False
def possible_meeting(self, place_list_ref, place_list_active):
"""
Try to see if two persons can be to the same place during their life.
If yes, show a marker with the dates foe each person.
"""
radius = float(self._config.get("geography.maximum_meeting_zone")/10.0)
for ref in place_list_ref:
for act in place_list_active:
if (hypot(float(act[3])-float(ref[3]),
float(act[4])-float(ref[4])) <= radius) == True:
# we are in the meeting zone
self.add_marker(None, None, act[3], act[4], act[7], True, 1)
self.all_place_list.append(act)
self.add_marker(None, None, ref[3], ref[4], ref[7], True, 1)
self.all_place_list.append(ref)
def _createmap(self, person, color, place_list, reference):
"""
Create all markers for each people's event in the database which has
a lat/lon.
"""
dbstate = self.dbstate
self.cal = config.get('preferences.calendar-format-report')
self.place_list = place_list
self.place_without_coordinates = []
self.minlat = self.maxlat = self.minlon = self.maxlon = 0.0
self.minyear = 9999
self.maxyear = 0
latitude = ""
longitude = ""
if person is not None:
# For each event, if we have a place, set a marker.
for event_ref in person.get_event_ref_list():
if not event_ref:
continue
event = dbstate.db.get_event_from_handle(event_ref.ref)
role = event_ref.get_role()
try:
date = event.get_date_object().to_calendar(self.cal)
except:
continue
eyear = str("%04d" % date.get_year()) + \
str("%02d" % date.get_month()) + \
str("%02d" % date.get_day())
place_handle = event.get_place_handle()
if place_handle:
place = dbstate.db.get_place_from_handle(place_handle)
if place:
longitude = place.get_longitude()
latitude = place.get_latitude()
latitude, longitude = conv_lat_lon(latitude,
longitude, "D.D8")
descr = _pd.display(dbstate.db, place)
evt = EventType(event.get_type())
descr1 = _("%(eventtype)s : %(name)s") % {
'eventtype': evt,
'name': _nd.display(person)}
# place.get_longitude and place.get_latitude return
# one string. We have coordinates when the two values
# contains non null string.
if longitude and latitude:
self._append_to_places_list(descr, evt,
_nd.display(person),
latitude, longitude,
descr1, eyear,
event.get_type(),
person.gramps_id,
place.gramps_id,
event.gramps_id,
role
)
else:
self._append_to_places_without_coord(
place.gramps_id, descr)
family_list = person.get_family_handle_list()
descr1 = " - "
for family_hdl in family_list:
family = self.dbstate.db.get_family_from_handle(family_hdl)
if family is not None:
fhandle = family_list[0] # first is primary
fam = dbstate.db.get_family_from_handle(fhandle)
handle = fam.get_father_handle()
descr1 = " - "
if handle:
father = dbstate.db.get_person_from_handle(handle)
if father:
descr1 = "%s - " % _nd.display(father)
handle = fam.get_mother_handle()
if handle:
mother = dbstate.db.get_person_from_handle(handle)
if mother:
descr1 = "%s%s" % (descr1, _nd.display(mother))
for event_ref in family.get_event_ref_list():
if event_ref:
event = dbstate.db.get_event_from_handle(
event_ref.ref)
role = event_ref.get_role()
if event.get_place_handle():
place_handle = event.get_place_handle()
if place_handle:
place = dbstate.db.get_place_from_handle(
place_handle)
if place:
longitude = place.get_longitude()
latitude = place.get_latitude()
latitude, longitude = conv_lat_lon(
latitude, longitude, "D.D8")
descr = _pd.display(dbstate.db, place)
evt = EventType(event.get_type())
eyear = str(
"%04d" % event.get_date_object().to_calendar(self.cal).get_year()) + \
str("%02d" % event.get_date_object().to_calendar(self.cal).get_month()) + \
str("%02d" % event.get_date_object().to_calendar(self.cal).get_day())
if longitude and latitude:
self._append_to_places_list(descr,
evt, _nd.display(person),
latitude, longitude,
descr1, eyear,
event.get_type(),
person.gramps_id,
place.gramps_id,
event.gramps_id,
role
)
else:
self._append_to_places_without_coord(place.gramps_id, descr)
sort1 = sorted(self.place_list, key=operator.itemgetter(6))
self.draw(None, sort1, color, reference)
# merge with the last results
merge_list = []
for the_list in self.sort, sort1:
merge_list += the_list
self.sort = sorted(merge_list, key=operator.itemgetter(6))
def bubble_message(self, event, lat, lon, marks):
"""
Create the menu for the selected marker
"""
self.newmenu = Gtk.Menu()
menu = self.newmenu
menu.set_title("person")
events = []
message = ""
oldplace = ""
prevmark = None
for mark in marks:
for plce in self.all_place_list:
if plce[3] == mark[3] and plce[4] == mark[4]:
if plce[10] in events:
continue
else:
events.append(plce[10])
if plce[0] != oldplace:
message = "%s :" % plce[0]
self.add_place_bubble_message(event, lat, lon,
marks, menu,
message, plce)
oldplace = plce[0]
message = ""
evt = self.dbstate.db.get_event_from_gramps_id(plce[10])
# format the date as described in preferences.
date = displayer.display(evt.get_date_object())
if date == "":
date = _("Unknown")
if plce[11] == EventRoleType.PRIMARY:
message = "(%s) %s : %s" % (date, plce[2], plce[1])
elif plce[11] == EventRoleType.FAMILY:
(father_name,
mother_name) = self._get_father_and_mother_name(evt)
message = "(%s) %s : %s - %s" % (date, plce[7],
father_name,
mother_name)
else:
descr = evt.get_description()
if descr == "":
descr = _('No description')
message = "(%s) %s => %s" % (date, plce[11], descr)
prevmark = plce
self.add_item = Gtk.MenuItem(label=message)
add_item = self.add_item
add_item.show()
menu.append(add_item)
self.itemoption = Gtk.Menu()
itemoption = self.itemoption
itemoption.set_title(message)
itemoption.show()
add_item.set_submenu(itemoption)
modify = Gtk.MenuItem(label=_("Edit Event"))
modify.show()
modify.connect("activate", self.edit_event,
event, lat, lon, prevmark)
itemoption.append(modify)
center = Gtk.MenuItem(label=_("Center on this place"))
center.show()
center.connect("activate", self.center_here,
event, lat, lon, prevmark)
itemoption.append(center)
menu.show()
menu.popup(None, None, None,
None, event.button, event.time)
return 0
def add_specific_menu(self, menu, event, lat, lon):
"""
Add specific entry to the navigation menu.
"""
add_item = Gtk.MenuItem()
add_item.show()
menu.append(add_item)
add_item = Gtk.MenuItem(
label=_("Choose and bookmark the new reference person"))
add_item.connect("activate", self.select_person)
add_item.show()
menu.append(add_item)
return
def get_default_gramplets(self):
"""
Define the default gramplets for the sidebar and bottombar.
"""
return (("Person Filter",),
())
def specific_options(self, configdialog):
"""
Add specific entry to the preference menu.
Must be done in the associated view.
"""
grid = Gtk.Grid()
grid.set_border_width(12)
grid.set_column_spacing(6)
grid.set_row_spacing(6)
configdialog.add_text(grid,
_('The meeting zone probability radius.\n'
'The colored zone is approximative.\n'
'The meeting zone is only shown for the reference person.\n'
'The value 9 means about 42 miles or 67 kms.\n'
'The value 1 means about 4.6 miles or 7.5 kms.\n'
'The value is in tenth of degree.'),
1, line_wrap=False)
self.config_meeting_slider = configdialog.add_slider(grid,
"",
2, 'geography.maximum_meeting_zone',
(1, 9))
return _('The selection parameters'), grid
def config_connect(self):
"""
used to monitor changes in the ini file
"""
self._config.connect('geography.maximum_meeting_zone',
self.cb_update_meeting_radius)
def cb_update_meeting_radius(self, client, cnxn_id, entry, data):
"""
Called when the radius change
"""
self.goto_handle(handle=None)

View File

@ -0,0 +1,19 @@
397a398,408
> def select_person2(self, *obj):
> """
> Open a selection box to choose the secondary person.
> """
> selectperson = SelectorFactory('Person')
> sel = selectperson(self.dbstate, self.uistate, self.track,
> _("Select the person which will be our active."),
> skip=self.skip_list)
> self.uistate.set_active(sel.run().get_handle(), 'Person')
> self.goto_handle(None)
>
651a663,668
> add_item.show()
> menu.append(add_item)
>
> add_item = Gtk.MenuItem(
> label=_("Choose the new active person"))
> add_item.connect("activate", self.select_person2)

View File

@ -0,0 +1,902 @@
# -*- python -*-
# -*- coding: utf-8 -*-
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2011-2016 Serge Noiraud
#
# 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.
#
"""
Geography for two families
"""
#-------------------------------------------------------------------------
#
# Python modules
#
#-------------------------------------------------------------------------
from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext
import operator
from gi.repository import Gtk
from math import hypot
#-------------------------------------------------------------------------
#
# set up logging
#
#-------------------------------------------------------------------------
import logging
_LOG = logging.getLogger("GeoGraphy.geofamilyclose")
#-------------------------------------------------------------------------
#
# Gramps Modules
#
#-------------------------------------------------------------------------
from gramps.gen.lib import EventRoleType, EventType
from gramps.gen.config import config
from gramps.gen.datehandler import displayer
from gramps.gen.display.name import displayer as _nd
from gramps.gen.display.place import displayer as _pd
from gramps.gen.utils.place import conv_lat_lon
from gramps.gui.views.navigationview import NavigationView
from gramps.gui.views.bookmarks import FamilyBookmarks
from gramps.plugins.lib.maps import constants
from gramps.plugins.lib.maps.geography import GeoGraphyView
from gramps.gui.selectors import SelectorFactory
#-------------------------------------------------------------------------
#
# Constants
#
#-------------------------------------------------------------------------
_UI_DEF = [
'''
<placeholder id="CommonGo">
<section>
<item>
<attribute name="action">win.Back</attribute>
<attribute name="label" translatable="yes">_Back</attribute>
</item>
<item>
<attribute name="action">win.Forward</attribute>
<attribute name="label" translatable="yes">_Forward</attribute>
</item>
</section>
<section>
<item>
<attribute name="action">win.HomePerson</attribute>
<attribute name="label" translatable="yes">_Home</attribute>
</item>
</section>
</placeholder>
''',
'''
<section id='CommonEdit' groups='RW'>
<item>
<attribute name="action">win.PrintView</attribute>
<attribute name="label" translatable="yes">Print...</attribute>
</item>
</section>
''',
'''
<section id="AddEditBook">
<item>
<attribute name="action">win.AddBook</attribute>
<attribute name="label" translatable="yes">_Add Bookmark</attribute>
</item>
<item>
<attribute name="action">win.EditBook</attribute>
<attribute name="label" translatable="no">%s...</attribute>
</item>
</section>
''' % _('Organize Bookmarks'), # Following are the Toolbar items
'''
<placeholder id='CommonNavigation'>
<child groups='RO'>
<object class="GtkToolButton">
<property name="icon-name">go-previous</property>
<property name="action-name">win.Back</property>
<property name="tooltip_text" translatable="yes">'''
'''Go to the previous object in the history</property>
<property name="label" translatable="yes">_Back</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child groups='RO'>
<object class="GtkToolButton">
<property name="icon-name">go-next</property>
<property name="action-name">win.Forward</property>
<property name="tooltip_text" translatable="yes">'''
'''Go to the next object in the history</property>
<property name="label" translatable="yes">_Forward</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child groups='RO'>
<object class="GtkToolButton">
<property name="icon-name">go-home</property>
<property name="action-name">win.HomePerson</property>
<property name="tooltip_text" translatable="yes">'''
'''Go to the home person</property>
<property name="label" translatable="yes">_Home</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child groups='RO'>
<object class="GtkToolButton">
<property name="icon-name">gramps-family</property>
<property name="action-name">win.RefFamily</property>
<property name="tooltip_text" translatable="yes">'''
'''Select the family which is the reference for life ways</property>
<property name="label" translatable="yes">reference _Family</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
</placeholder>
''',
'''
<placeholder id='BarCommonEdit'>
<child groups='RO'>
<object class="GtkToolButton">
<property name="icon-name">document-print</property>
<property name="action-name">win.PrintView</property>
<property name="tooltip_text" translatable="yes">'''
'''Print or save the Map</property>
<property name="label" translatable="yes">Print...</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
</placeholder>
''']
# pylint: disable=no-member
# pylint: disable=unused-variable
# pylint: disable=unused-argument
#-------------------------------------------------------------------------
#
# GeoView
#
#-------------------------------------------------------------------------
class GeoFamClose(GeoGraphyView):
"""
The view used to render family's map.
"""
CONFIGSETTINGS = (
('geography.path', constants.GEOGRAPHY_PATH),
('geography.zoom', 10),
('geography.zoom_when_center', 12),
('geography.show_cross', True),
('geography.lock', False),
('geography.center-lat', 0.0),
('geography.center-lon', 0.0),
('geography.use-keypad', True),
('geography.map_service', constants.OPENSTREETMAP),
('geography.max_places', 5000),
# specific to geoclose :
('geography.color1', 'blue'),
('geography.color2', 'green'),
('geography.maximum_meeting_zone', 5),
)
def __init__(self, pdata, dbstate, uistate, nav_group=0):
GeoGraphyView.__init__(self,
_("Have these two families been able to meet?"),
pdata, dbstate, uistate,
FamilyBookmarks, nav_group)
self.dbstate = dbstate
self.uistate = uistate
self.place_list = []
self.all_place_list = []
self.place_without_coordinates = []
self.minlat = self.maxlat = self.minlon = self.maxlon = 0.0
self.minyear = 9999
self.maxyear = 0
self.reffamily = None
self.reffamily_bookmark = None
self.nbplaces = 0
self.nbmarkers = 0
self.sort = []
self.tracks = []
self.additional_uis.append(self.additional_ui())
self.ref_family = None
self.skip_list = []
self.track = []
self.place_list_active = []
self.place_list_ref = []
self.cal = config.get('preferences.calendar-format-report')
self.no_show_places_in_status_bar = False
self.config_meeting_slider = None
self.dbstate.connect('database-changed', self.reset_change_db)
def reset_change_db(self, dummy_dbase):
"""
Used to reset the family reference
"""
self.reffamily = None
def get_title(self):
"""
Used to set the titlebar in the configuration window.
"""
return _('GeoFamClose')
def get_stock(self):
"""
Returns the name of the stock icon to use for the display.
This assumes that this icon has already been registered
as a stock icon.
"""
return 'geo-show-family'
def get_viewtype_stock(self):
"""Type of view in category
"""
return 'geo-show-family'
def additional_ui(self):
"""
Specifies the UIManager XML code that defines the menus and buttons
associated with the interface.
"""
return _UI_DEF
def navigation_type(self):
"""
Indicates the navigation type. Navigation type can be the string
name of any of the primary objects.
"""
return 'Family'
def family_label(self, family):
"""
Create the family label depending on existence of father and mother
"""
if family is None:
return "Unknown"
father = mother = None
hdl = family.get_father_handle()
if hdl:
father = self.dbstate.db.get_person_from_handle(hdl)
hdl = family.get_mother_handle()
if hdl:
mother = self.dbstate.db.get_person_from_handle(hdl)
if father and mother:
label = _("%(gramps_id)s : %(father)s and %(mother)s") % {
'father' : _nd.display(father),
'mother' : _nd.display(mother),
'gramps_id' : family.gramps_id,
}
elif father:
label = "%(gramps_id)s : %(father)s" % {
'father' : _nd.display(father),
'gramps_id' : family.gramps_id,
}
elif mother:
label = "%(gramps_id)s : %(mother)s" % {
'mother' : _nd.display(mother),
'gramps_id' : family.gramps_id,
}
else:
# No translation for bare gramps_id
label = "%(gramps_id)s :" % {
'gramps_id' : family.gramps_id,
}
return label
def goto_handle(self, handle=None):
"""
Rebuild the tree with the given family handle as reference.
"""
self.place_list_active = []
self.place_list_ref = []
self.all_place_list = []
self.sort = []
self.places_found = []
self.place_without_coordinates = []
self.nbmarkers = 0
self.nbplaces = 0
self.remove_all_gps()
self.remove_all_markers()
self.lifeway_layer.clear_ways()
self.message_layer.clear_messages()
self.message_layer.set_font_attributes(None, None, None)
active = self.get_active()
family = None
if active:
family = self.dbstate.db.get_family_from_handle(active)
color = self._config.get('geography.color2')
self._createmap(family, color, self.place_list_active, False)
if self.reffamily:
color = self._config.get('geography.color1')
self._createmap(self.reffamily, color, self.place_list_ref, True)
self.message_layer.add_message(_("Family reference : %s") %
self.family_label(self.reffamily))
if family:
self.message_layer.add_message(_("The other family : %s") %
self.family_label(family))
else:
self.message_layer.add_message(_("The other family : %s") %
_("Unknown"))
if self.reffamily_bookmark is None:
self.reffamily_bookmark = self.reffamily.get_handle()
self.add_bookmark_from_popup(None, self.reffamily_bookmark)
else:
self.message_layer.add_message(
_("You must choose one reference family."))
self.message_layer.add_message(
_("Go to the family view and select "
"the families you want to compare. "
"Return to this view and use the history."))
if family is not None:
self._possible_family_meeting(self.reffamily, family)
self.uistate.modify_statusbar(self.dbstate)
def define_actions(self):
"""
Define action for the reference family button.
"""
GeoGraphyView.define_actions(self)
self._add_action('RefFamily', self.select_family)
def select_family(self, *obj):
"""
Open a selection box to choose the ref family.
"""
self.track = []
self.skip_list = []
self.ref_family = None
self.reffamily_bookmark = None
select_family = SelectorFactory('Family')
sel = select_family(self.dbstate, self.uistate)
self.reffamily = sel.run()
self.goto_handle(None)
def select_family2(self, *obj):
"""
Open a selection box to choose the secondary family.
"""
select_family = SelectorFactory('Family')
sel = select_family(self.dbstate, self.uistate)
self.uistate.set_active(sel.run().get_handle(), 'Family')
self.goto_handle(None)
def build_tree(self):
"""
This is called by the parent class when the view becomes visible. Since
all handling of visibility is now in rebuild_trees, see that for more
information.
"""
self.lifeway_layer.clear_ways()
if not self.dbstate.is_open():
return
active = self.get_active()
if active:
family = self.dbstate.db.get_family_from_handle(active)
if family is None:
self.goto_handle(None)
else:
self.goto_handle(handle=family)
else:
self.goto_handle(None)
def draw(self, menu, marks, color, reference):
"""
Create all moves for the people's event.
"""
points = []
mark = None
for mark in marks:
startlat = float(mark[3])
startlon = float(mark[4])
not_stored = True
for idx in range(0, len(points)):
if points[idx][0] == startlat and points[idx][1] == startlon:
not_stored = False
if not_stored:
points.append((startlat, startlon))
self.lifeway_layer.add_way(points, color)
if reference:
self.lifeway_layer.add_way_ref(points, 'orange',
float(
self._config.get("geography.maximum_meeting_zone")) / 10)
return False
def _place_list_for_person(self, person):
"""
get place list for one person
"""
place_list = []
for event in self.sort:
if event[1] == _nd.display(person):
place_list.append(event)
return place_list
def possible_meeting(self, ref_person, person):
"""
Try to see if two persons can be to the same place during their life.
If yes, show a marker with the dates for each person.
"""
self.place_list_ref = self._place_list_for_person(ref_person)
self.place_list_active = self._place_list_for_person(person)
radius = float(self._config.get("geography.maximum_meeting_zone")/10.0)
for ref in self.place_list_ref:
for act in self.place_list_active:
if (hypot(float(act[3])-float(ref[3]),
float(act[4])-float(ref[4])) <= radius) == True:
# we are in the meeting zone
self.add_marker(None, None, act[3], act[4], act[7], True, 1)
self.all_place_list.append(act)
self.add_marker(None, None, ref[3], ref[4], ref[7], True, 1)
self.all_place_list.append(ref)
def _expose_persone_to_family(self, ref_person, family):
"""
try to search one or more meeting zone for all persons of one family
with one reference person
"""
dbstate = self.dbstate
try:
person = dbstate.db.get_person_from_handle(
family.get_father_handle())
except:
return
if person is None: # family without father ?
person = dbstate.db.get_person_from_handle(
family.get_mother_handle())
if person is not None:
family_list = person.get_family_handle_list()
if len(family_list) > 0:
fhandle = family_list[0] # first is primary
fam = dbstate.db.get_family_from_handle(fhandle)
father = mother = None
handle = fam.get_father_handle()
if handle:
father = dbstate.db.get_person_from_handle(handle)
if father:
self.possible_meeting(father, ref_person)
handle = fam.get_mother_handle()
if handle:
mother = dbstate.db.get_person_from_handle(handle)
if mother:
self.possible_meeting(mother, ref_person)
child_ref_list = fam.get_child_ref_list()
if child_ref_list:
for child_ref in child_ref_list:
child = dbstate.db.get_person_from_handle(child_ref.ref)
if child:
self.possible_meeting(child, ref_person)
else:
self.possible_meeting(person, ref_person)
def _possible_family_meeting(self, reference, family):
"""
try to expose each person of the reference family to the second family
"""
dbstate = self.dbstate
person = None
try:
person = dbstate.db.get_person_from_handle(
reference.get_father_handle())
except:
return
if person is None: # family without father ?
handle = reference.get_mother_handle()
if handle:
person = dbstate.db.get_person_from_handle(handle)
if person is None:
handle = self.uistate.get_active('Person')
if handle:
person = dbstate.db.get_person_from_handle(handle)
if person is not None:
family_list = person.get_family_handle_list()
if len(family_list) > 0:
fhandle = family_list[0] # first is primary
fam = dbstate.db.get_family_from_handle(fhandle)
father = mother = None
handle = fam.get_father_handle()
if handle:
father = dbstate.db.get_person_from_handle(handle)
if father:
self._expose_persone_to_family(father, family)
handle = fam.get_mother_handle()
if handle:
mother = dbstate.db.get_person_from_handle(handle)
if mother:
self._expose_persone_to_family(mother, family)
child_ref_list = fam.get_child_ref_list()
if child_ref_list:
for child_ref in child_ref_list:
child = dbstate.db.get_person_from_handle(child_ref.ref)
if child:
self._expose_persone_to_family(child, family)
else:
self._expose_persone_to_family(person, family)
def _createmap_for_one_person(self, person, color, place_list, reference):
"""
Create all markers for each people's event in the database which has
a lat/lon.
"""
self.place_list = []
dbstate = self.dbstate
if person is not None:
# For each event, if we have a place, set a marker.
for event_ref in person.get_event_ref_list():
if not event_ref:
continue
event = dbstate.db.get_event_from_handle(event_ref.ref)
role = event_ref.get_role()
try:
date = event.get_date_object().to_calendar(self.cal)
except:
continue
eyear = str("%04d" % date.get_year()) + \
str("%02d" % date.get_month()) + \
str("%02d" % date.get_day())
place_handle = event.get_place_handle()
if place_handle:
place = dbstate.db.get_place_from_handle(place_handle)
if place:
longitude = place.get_longitude()
latitude = place.get_latitude()
latitude, longitude = conv_lat_lon(latitude,
longitude, "D.D8")
descr = _pd.display(dbstate.db, place)
evt = EventType(event.get_type())
descr1 = _("%(eventtype)s : %(name)s") % {
'eventtype': evt,
'name': _nd.display(person)}
# place.get_longitude and place.get_latitude return
# one string. We have coordinates when the two values
# contains non null string.
if longitude and latitude:
self._append_to_places_list(descr, evt,
_nd.display(person),
latitude, longitude,
descr1, eyear,
event.get_type(),
person.gramps_id,
place.gramps_id,
event.gramps_id,
role
)
else:
self._append_to_places_without_coord(
place.gramps_id, descr)
family_list = person.get_family_handle_list()
descr1 = " - "
for family_hdl in family_list:
family = self.dbstate.db.get_family_from_handle(family_hdl)
if family is not None:
fhandle = family_list[0] # first is primary
father = mother = None
fam = dbstate.db.get_family_from_handle(fhandle)
handle = fam.get_father_handle()
if handle:
father = dbstate.db.get_person_from_handle(handle)
if father:
descr1 = "%s - " % _nd.display(father)
handle = fam.get_mother_handle()
if handle:
mother = dbstate.db.get_person_from_handle(handle)
if mother:
descr1 = "%s%s" % (descr1, _nd.display(mother))
for event_ref in family.get_event_ref_list():
if event_ref:
event = dbstate.db.get_event_from_handle(
event_ref.ref)
role = event_ref.get_role()
if event.get_place_handle():
place_handle = event.get_place_handle()
if place_handle:
place = dbstate.db.get_place_from_handle(
place_handle)
if place:
longitude = place.get_longitude()
latitude = place.get_latitude()
latitude, longitude = conv_lat_lon(
latitude, longitude, "D.D8")
descr = _pd.display(dbstate.db, place)
evt = EventType(
event.get_type())
eyear = str(
"%04d" % event.get_date_object().to_calendar(self.cal).get_year()) + \
str("%02d" % event.get_date_object().to_calendar(self.cal).get_month()) + \
str("%02d" % event.get_date_object().to_calendar(self.cal).get_day())
if longitude and latitude:
self._append_to_places_list(descr,
evt, _nd.display(person),
latitude, longitude,
descr1, eyear,
event.get_type(),
person.gramps_id,
place.gramps_id,
event.gramps_id,
role
)
else:
self._append_to_places_without_coord(place.gramps_id, descr)
sort1 = sorted(self.place_list, key=operator.itemgetter(6))
self.draw(None, sort1, color, reference)
# merge with the last results
merge_list = []
for the_list in self.sort, sort1:
merge_list += the_list
self.sort = sorted(merge_list, key=operator.itemgetter(6))
def _createmap_for_one_family(self, family, color, place_list, reference):
"""
Create all markers for one family : all event's places with a lat/lon.
"""
dbstate = self.dbstate
person = None
try:
person = dbstate.db.get_person_from_handle(
family.get_father_handle())
except:
return
family_id = family.gramps_id
if person is None: # family without father ?
handle = family.get_mother_handle()
if handle:
person = dbstate.db.get_person_from_handle(handle)
if person is None:
handle = self.uistate.get_active('Person')
if handle:
person = dbstate.db.get_person_from_handle(handle)
if person is not None:
family_list = person.get_family_handle_list()
if len(family_list) > 0:
fhandle = family_list[0] # first is primary
fam = dbstate.db.get_family_from_handle(fhandle)
father = mother = None
handle = fam.get_father_handle()
if handle:
father = dbstate.db.get_person_from_handle(handle)
if father:
comment = _("Father : %(id)s : %(name)s") % {
'id': father.gramps_id,
'name': _nd.display(father)}
self._createmap_for_one_person(father, color,
place_list, reference)
handle = fam.get_mother_handle()
if handle:
mother = dbstate.db.get_person_from_handle(handle)
if mother:
comment = _("Mother : %(id)s : %(name)s") % {
'id': mother.gramps_id,
'name': _nd.display(mother)}
self._createmap_for_one_person(mother, color,
place_list, reference)
index = 0
child_ref_list = fam.get_child_ref_list()
if child_ref_list:
for child_ref in child_ref_list:
child = dbstate.db.get_person_from_handle(child_ref.ref)
if child:
index += 1
comment = _("Child : %(id)s - %(index)d "
": %(name)s") % {
'id' : child.gramps_id,
'index' : index,
'name' : _nd.display(child)
}
self._createmap_for_one_person(child, color,
place_list,
reference)
else:
comment = _("Person : %(id)s %(name)s has no family.") % {
'id' : person.gramps_id,
'name' : _nd.display(person)
}
self._createmap_for_one_person(person, color,
place_list, reference)
def _createmap(self, family_x, color, place_list, reference):
"""
Create all markers for each family's person in the database which has
a lat/lon.
"""
dbstate = self.dbstate
self.cal = config.get('preferences.calendar-format-report')
self.place_list = place_list
self.place_without_coordinates = []
self.minlat = self.maxlat = self.minlon = self.maxlon = 0.0
#self.minyear = 9999
#self.maxyear = 0
latitude = ""
longitude = ""
self.place_list = []
self.place_without_coordinates = []
self.minlat = self.maxlat = self.minlon = self.maxlon = 0.0
#family = self.dbstate.db.get_family_from_handle(family_x)
family = family_x
if family is None:
handle = self.uistate.get_active('Person')
person = None
if handle:
person = self.dbstate.db.get_family_from_handle(handle)
if not person:
return
family_list = person.get_family_handle_list()
for family_hdl in family_list:
family = self.dbstate.db.get_family_from_handle(family_hdl)
if family is not None:
self._createmap_for_one_family(family, color,
place_list, reference)
else:
self._createmap_for_one_family(family, color, place_list, reference)
#self._create_markers()
def bubble_message(self, event, lat, lon, marks):
"""
Create the menu for the selected marker
"""
self.menu = Gtk.Menu()
menu = self.menu
menu.set_title("family")
events = []
message = ""
oldplace = ""
prevmark = None
for mark in marks:
for plce in self.all_place_list:
if plce[3] == mark[3] and plce[4] == mark[4]:
if plce[10] in events:
continue
else:
events.append(plce[10])
if plce[0] != oldplace:
message = "%s :" % plce[0]
self.add_place_bubble_message(event, lat, lon,
marks, menu,
message, plce)
oldplace = plce[0]
message = ""
evt = self.dbstate.db.get_event_from_gramps_id(plce[10])
# format the date as described in preferences.
date = displayer.display(evt.get_date_object())
if date == "":
date = _("Unknown")
if plce[11] == EventRoleType.PRIMARY:
message = "(%s) %s : %s" % (date, plce[2], plce[1])
elif plce[11] == EventRoleType.FAMILY:
(father_name,
mother_name) = self._get_father_and_mother_name(evt)
message = "(%s) %s : %s - %s" % (date, plce[7],
father_name,
mother_name)
else:
descr = evt.get_description()
if descr == "":
descr = _('No description')
message = "(%s) %s => %s" % (date, plce[11], descr)
prevmark = plce
add_item = Gtk.MenuItem(label=message)
add_item.show()
menu.append(add_item)
self.itemoption = Gtk.Menu()
itemoption = self.itemoption
itemoption.set_title(message)
itemoption.show()
add_item.set_submenu(itemoption)
modify = Gtk.MenuItem(label=_("Edit Event"))
modify.show()
modify.connect("activate", self.edit_event,
event, lat, lon, prevmark)
itemoption.append(modify)
center = Gtk.MenuItem(label=_("Center on this place"))
center.show()
center.connect("activate", self.center_here,
event, lat, lon, prevmark)
itemoption.append(center)
menu.show()
menu.popup(None, None, None,
None, event.button, event.time)
return 0
def add_specific_menu(self, menu, event, lat, lon):
"""
Add specific entry to the navigation menu.
"""
add_item = Gtk.MenuItem()
add_item.show()
menu.append(add_item)
add_item = Gtk.MenuItem(
label=_("Choose and bookmark the new reference family"))
add_item.connect("activate", self.select_family)
add_item.show()
menu.append(add_item)
add_item = Gtk.MenuItem(
label=_("Choose the new active family"))
add_item.connect("activate", self.select_family2)
add_item.show()
menu.append(add_item)
return
def get_default_gramplets(self):
"""
Define the default gramplets for the sidebar and bottombar.
"""
return (("Person Filter",),
())
def specific_options(self, configdialog):
"""
Add specific entry to the preference menu.
Must be done in the associated view.
"""
grid = Gtk.Grid()
grid.set_border_width(12)
grid.set_column_spacing(6)
grid.set_row_spacing(6)
configdialog.add_text(grid,
_('The meeting zone probability radius.\n'
'The colored zone is approximative.\n'
'The meeting zone is only shown for the reference family.\n'
'The value 9 means about 42 miles or 67 kms.\n'
'The value 1 means about 4.6 miles or 7.5 kms.\n'
'The value is in tenth of degree.'),
1, line_wrap=False)
self.config_meeting_slider = configdialog.add_slider(grid,
"",
2, 'geography.maximum_meeting_zone',
(1, 9))
return _('The selection parameters'), grid
def config_connect(self):
"""
used to monitor changes in the ini file
"""
self._config.connect('geography.maximum_meeting_zone',
self.cb_update_meeting_radius)
def cb_update_meeting_radius(self, client, cnxn_id, entry, data):
"""
Called when the radius change
"""
self.goto_handle(handle=None)

View File

@ -0,0 +1,886 @@
# -*- python -*-
# -*- coding: utf-8 -*-
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2011-2016 Serge Noiraud
#
# 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.
#
"""
Geography for two families
"""
#-------------------------------------------------------------------------
#
# Python modules
#
#-------------------------------------------------------------------------
from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext
import operator
from gi.repository import Gtk
from math import hypot
#-------------------------------------------------------------------------
#
# set up logging
#
#-------------------------------------------------------------------------
import logging
_LOG = logging.getLogger("GeoGraphy.geofamilyclose")
#-------------------------------------------------------------------------
#
# Gramps Modules
#
#-------------------------------------------------------------------------
from gramps.gen.lib import EventRoleType, EventType
from gramps.gen.config import config
from gramps.gen.datehandler import displayer
from gramps.gen.display.name import displayer as _nd
from gramps.gen.display.place import displayer as _pd
from gramps.gen.utils.place import conv_lat_lon
from gramps.gui.views.navigationview import NavigationView
from gramps.gui.views.bookmarks import FamilyBookmarks
from gramps.plugins.lib.maps import constants
from gramps.plugins.lib.maps.geography import GeoGraphyView
from gramps.gui.selectors import SelectorFactory
#-------------------------------------------------------------------------
#
# Constants
#
#-------------------------------------------------------------------------
_UI_DEF = [
'''
<placeholder id="CommonGo">
<section>
<item>
<attribute name="action">win.Back</attribute>
<attribute name="label" translatable="yes">_Back</attribute>
</item>
<item>
<attribute name="action">win.Forward</attribute>
<attribute name="label" translatable="yes">_Forward</attribute>
</item>
</section>
<section>
<item>
<attribute name="action">win.HomePerson</attribute>
<attribute name="label" translatable="yes">_Home</attribute>
</item>
</section>
</placeholder>
''',
'''
<section id='CommonEdit' groups='RW'>
<item>
<attribute name="action">win.PrintView</attribute>
<attribute name="label" translatable="yes">Print...</attribute>
</item>
</section>
''',
'''
<section id="AddEditBook">
<item>
<attribute name="action">win.AddBook</attribute>
<attribute name="label" translatable="yes">_Add Bookmark</attribute>
</item>
<item>
<attribute name="action">win.EditBook</attribute>
<attribute name="label" translatable="no">%s...</attribute>
</item>
</section>
''' % _('Organize Bookmarks'), # Following are the Toolbar items
'''
<placeholder id='CommonNavigation'>
<child groups='RO'>
<object class="GtkToolButton">
<property name="icon-name">go-previous</property>
<property name="action-name">win.Back</property>
<property name="tooltip_text" translatable="yes">'''
'''Go to the previous object in the history</property>
<property name="label" translatable="yes">_Back</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child groups='RO'>
<object class="GtkToolButton">
<property name="icon-name">go-next</property>
<property name="action-name">win.Forward</property>
<property name="tooltip_text" translatable="yes">'''
'''Go to the next object in the history</property>
<property name="label" translatable="yes">_Forward</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child groups='RO'>
<object class="GtkToolButton">
<property name="icon-name">go-home</property>
<property name="action-name">win.HomePerson</property>
<property name="tooltip_text" translatable="yes">'''
'''Go to the home person</property>
<property name="label" translatable="yes">_Home</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
<child groups='RO'>
<object class="GtkToolButton">
<property name="icon-name">gramps-family</property>
<property name="action-name">win.RefFamily</property>
<property name="tooltip_text" translatable="yes">'''
'''Select the family which is the reference for life ways</property>
<property name="label" translatable="yes">reference _Family</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
</placeholder>
''',
'''
<placeholder id='BarCommonEdit'>
<child groups='RO'>
<object class="GtkToolButton">
<property name="icon-name">document-print</property>
<property name="action-name">win.PrintView</property>
<property name="tooltip_text" translatable="yes">'''
'''Print or save the Map</property>
<property name="label" translatable="yes">Print...</property>
<property name="use-underline">True</property>
</object>
<packing>
<property name="homogeneous">False</property>
</packing>
</child>
</placeholder>
''']
# pylint: disable=no-member
# pylint: disable=unused-variable
# pylint: disable=unused-argument
#-------------------------------------------------------------------------
#
# GeoView
#
#-------------------------------------------------------------------------
class GeoFamClose(GeoGraphyView):
"""
The view used to render family's map.
"""
CONFIGSETTINGS = (
('geography.path', constants.GEOGRAPHY_PATH),
('geography.zoom', 10),
('geography.zoom_when_center', 12),
('geography.show_cross', True),
('geography.lock', False),
('geography.center-lat', 0.0),
('geography.center-lon', 0.0),
('geography.use-keypad', True),
('geography.map_service', constants.OPENSTREETMAP),
('geography.max_places', 5000),
# specific to geoclose :
('geography.color1', 'blue'),
('geography.color2', 'green'),
('geography.maximum_meeting_zone', 5),
)
def __init__(self, pdata, dbstate, uistate, nav_group=0):
GeoGraphyView.__init__(self,
_("Have these two families been able to meet?"),
pdata, dbstate, uistate,
FamilyBookmarks, nav_group)
self.dbstate = dbstate
self.uistate = uistate
self.place_list = []
self.all_place_list = []
self.place_without_coordinates = []
self.minlat = self.maxlat = self.minlon = self.maxlon = 0.0
self.minyear = 9999
self.maxyear = 0
self.reffamily = None
self.reffamily_bookmark = None
self.nbplaces = 0
self.nbmarkers = 0
self.sort = []
self.tracks = []
self.additional_uis.append(self.additional_ui())
self.ref_family = None
self.skip_list = []
self.track = []
self.place_list_active = []
self.place_list_ref = []
self.cal = config.get('preferences.calendar-format-report')
self.no_show_places_in_status_bar = False
self.config_meeting_slider = None
self.dbstate.connect('database-changed', self.reset_change_db)
def reset_change_db(self, dummy_dbase):
"""
Used to reset the family reference
"""
self.reffamily = None
def get_title(self):
"""
Used to set the titlebar in the configuration window.
"""
return _('GeoFamClose')
def get_stock(self):
"""
Returns the name of the stock icon to use for the display.
This assumes that this icon has already been registered
as a stock icon.
"""
return 'geo-show-family'
def get_viewtype_stock(self):
"""Type of view in category
"""
return 'geo-show-family'
def additional_ui(self):
"""
Specifies the UIManager XML code that defines the menus and buttons
associated with the interface.
"""
return _UI_DEF
def navigation_type(self):
"""
Indicates the navigation type. Navigation type can be the string
name of any of the primary objects.
"""
return 'Family'
def family_label(self, family):
"""
Create the family label depending on existence of father and mother
"""
if family is None:
return "Unknown"
father = mother = None
hdl = family.get_father_handle()
if hdl:
father = self.dbstate.db.get_person_from_handle(hdl)
hdl = family.get_mother_handle()
if hdl:
mother = self.dbstate.db.get_person_from_handle(hdl)
if father and mother:
label = _("%(gramps_id)s : %(father)s and %(mother)s") % {
'father' : _nd.display(father),
'mother' : _nd.display(mother),
'gramps_id' : family.gramps_id,
}
elif father:
label = "%(gramps_id)s : %(father)s" % {
'father' : _nd.display(father),
'gramps_id' : family.gramps_id,
}
elif mother:
label = "%(gramps_id)s : %(mother)s" % {
'mother' : _nd.display(mother),
'gramps_id' : family.gramps_id,
}
else:
# No translation for bare gramps_id
label = "%(gramps_id)s :" % {
'gramps_id' : family.gramps_id,
}
return label
def goto_handle(self, handle=None):
"""
Rebuild the tree with the given family handle as reference.
"""
self.place_list_active = []
self.place_list_ref = []
self.all_place_list = []
self.sort = []
self.places_found = []
self.place_without_coordinates = []
self.nbmarkers = 0
self.nbplaces = 0
self.remove_all_gps()
self.remove_all_markers()
self.lifeway_layer.clear_ways()
self.message_layer.clear_messages()
self.message_layer.set_font_attributes(None, None, None)
active = self.get_active()
family = None
if active:
family = self.dbstate.db.get_family_from_handle(active)
color = self._config.get('geography.color2')
self._createmap(family, color, self.place_list_active, False)
if self.reffamily:
color = self._config.get('geography.color1')
self._createmap(self.reffamily, color, self.place_list_ref, True)
self.message_layer.add_message(_("Family reference : %s") %
self.family_label(self.reffamily))
if family:
self.message_layer.add_message(_("The other family : %s") %
self.family_label(family))
else:
self.message_layer.add_message(_("The other family : %s") %
_("Unknown"))
if self.reffamily_bookmark is None:
self.reffamily_bookmark = self.reffamily.get_handle()
self.add_bookmark_from_popup(None, self.reffamily_bookmark)
else:
self.message_layer.add_message(
_("You must choose one reference family."))
self.message_layer.add_message(
_("Go to the family view and select "
"the families you want to compare. "
"Return to this view and use the history."))
if family is not None:
self._possible_family_meeting(self.reffamily, family)
self.uistate.modify_statusbar(self.dbstate)
def define_actions(self):
"""
Define action for the reference family button.
"""
GeoGraphyView.define_actions(self)
self._add_action('RefFamily', self.select_family)
def select_family(self, *obj):
"""
Open a selection box to choose the ref family.
"""
self.track = []
self.skip_list = []
self.ref_family = None
self.reffamily_bookmark = None
select_family = SelectorFactory('Family')
sel = select_family(self.dbstate, self.uistate)
self.reffamily = sel.run()
self.goto_handle(None)
def build_tree(self):
"""
This is called by the parent class when the view becomes visible. Since
all handling of visibility is now in rebuild_trees, see that for more
information.
"""
self.lifeway_layer.clear_ways()
if not self.dbstate.is_open():
return
active = self.get_active()
if active:
family = self.dbstate.db.get_family_from_handle(active)
if family is None:
self.goto_handle(None)
else:
self.goto_handle(handle=family)
else:
self.goto_handle(None)
def draw(self, menu, marks, color, reference):
"""
Create all moves for the people's event.
"""
points = []
mark = None
for mark in marks:
startlat = float(mark[3])
startlon = float(mark[4])
not_stored = True
for idx in range(0, len(points)):
if points[idx][0] == startlat and points[idx][1] == startlon:
not_stored = False
if not_stored:
points.append((startlat, startlon))
self.lifeway_layer.add_way(points, color)
if reference:
self.lifeway_layer.add_way_ref(points, 'orange',
float(
self._config.get("geography.maximum_meeting_zone")) / 10)
return False
def _place_list_for_person(self, person):
"""
get place list for one person
"""
place_list = []
for event in self.sort:
if event[1] == _nd.display(person):
place_list.append(event)
return place_list
def possible_meeting(self, ref_person, person):
"""
Try to see if two persons can be to the same place during their life.
If yes, show a marker with the dates for each person.
"""
self.place_list_ref = self._place_list_for_person(ref_person)
self.place_list_active = self._place_list_for_person(person)
radius = float(self._config.get("geography.maximum_meeting_zone")/10.0)
for ref in self.place_list_ref:
for act in self.place_list_active:
if (hypot(float(act[3])-float(ref[3]),
float(act[4])-float(ref[4])) <= radius) == True:
# we are in the meeting zone
self.add_marker(None, None, act[3], act[4], act[7], True, 1)
self.all_place_list.append(act)
self.add_marker(None, None, ref[3], ref[4], ref[7], True, 1)
self.all_place_list.append(ref)
def _expose_persone_to_family(self, ref_person, family):
"""
try to search one or more meeting zone for all persons of one family
with one reference person
"""
dbstate = self.dbstate
try:
person = dbstate.db.get_person_from_handle(
family.get_father_handle())
except:
return
if person is None: # family without father ?
person = dbstate.db.get_person_from_handle(
family.get_mother_handle())
if person is not None:
family_list = person.get_family_handle_list()
if len(family_list) > 0:
fhandle = family_list[0] # first is primary
fam = dbstate.db.get_family_from_handle(fhandle)
father = mother = None
handle = fam.get_father_handle()
if handle:
father = dbstate.db.get_person_from_handle(handle)
if father:
self.possible_meeting(father, ref_person)
handle = fam.get_mother_handle()
if handle:
mother = dbstate.db.get_person_from_handle(handle)
if mother:
self.possible_meeting(mother, ref_person)
child_ref_list = fam.get_child_ref_list()
if child_ref_list:
for child_ref in child_ref_list:
child = dbstate.db.get_person_from_handle(child_ref.ref)
if child:
self.possible_meeting(child, ref_person)
else:
self.possible_meeting(person, ref_person)
def _possible_family_meeting(self, reference, family):
"""
try to expose each person of the reference family to the second family
"""
dbstate = self.dbstate
person = None
try:
person = dbstate.db.get_person_from_handle(
reference.get_father_handle())
except:
return
if person is None: # family without father ?
handle = reference.get_mother_handle()
if handle:
person = dbstate.db.get_person_from_handle(handle)
if person is None:
handle = self.uistate.get_active('Person')
if handle:
person = dbstate.db.get_person_from_handle(handle)
if person is not None:
family_list = person.get_family_handle_list()
if len(family_list) > 0:
fhandle = family_list[0] # first is primary
fam = dbstate.db.get_family_from_handle(fhandle)
father = mother = None
handle = fam.get_father_handle()
if handle:
father = dbstate.db.get_person_from_handle(handle)
if father:
self._expose_persone_to_family(father, family)
handle = fam.get_mother_handle()
if handle:
mother = dbstate.db.get_person_from_handle(handle)
if mother:
self._expose_persone_to_family(mother, family)
child_ref_list = fam.get_child_ref_list()
if child_ref_list:
for child_ref in child_ref_list:
child = dbstate.db.get_person_from_handle(child_ref.ref)
if child:
self._expose_persone_to_family(child, family)
else:
self._expose_persone_to_family(person, family)
def _createmap_for_one_person(self, person, color, place_list, reference):
"""
Create all markers for each people's event in the database which has
a lat/lon.
"""
self.place_list = []
dbstate = self.dbstate
if person is not None:
# For each event, if we have a place, set a marker.
for event_ref in person.get_event_ref_list():
if not event_ref:
continue
event = dbstate.db.get_event_from_handle(event_ref.ref)
role = event_ref.get_role()
try:
date = event.get_date_object().to_calendar(self.cal)
except:
continue
eyear = str("%04d" % date.get_year()) + \
str("%02d" % date.get_month()) + \
str("%02d" % date.get_day())
place_handle = event.get_place_handle()
if place_handle:
place = dbstate.db.get_place_from_handle(place_handle)
if place:
longitude = place.get_longitude()
latitude = place.get_latitude()
latitude, longitude = conv_lat_lon(latitude,
longitude, "D.D8")
descr = _pd.display(dbstate.db, place)
evt = EventType(event.get_type())
descr1 = _("%(eventtype)s : %(name)s") % {
'eventtype': evt,
'name': _nd.display(person)}
# place.get_longitude and place.get_latitude return
# one string. We have coordinates when the two values
# contains non null string.
if longitude and latitude:
self._append_to_places_list(descr, evt,
_nd.display(person),
latitude, longitude,
descr1, eyear,
event.get_type(),
person.gramps_id,
place.gramps_id,
event.gramps_id,
role
)
else:
self._append_to_places_without_coord(
place.gramps_id, descr)
family_list = person.get_family_handle_list()
descr1 = " - "
for family_hdl in family_list:
family = self.dbstate.db.get_family_from_handle(family_hdl)
if family is not None:
fhandle = family_list[0] # first is primary
father = mother = None
fam = dbstate.db.get_family_from_handle(fhandle)
handle = fam.get_father_handle()
if handle:
father = dbstate.db.get_person_from_handle(handle)
if father:
descr1 = "%s - " % _nd.display(father)
handle = fam.get_mother_handle()
if handle:
mother = dbstate.db.get_person_from_handle(handle)
if mother:
descr1 = "%s%s" % (descr1, _nd.display(mother))
for event_ref in family.get_event_ref_list():
if event_ref:
event = dbstate.db.get_event_from_handle(
event_ref.ref)
role = event_ref.get_role()
if event.get_place_handle():
place_handle = event.get_place_handle()
if place_handle:
place = dbstate.db.get_place_from_handle(
place_handle)
if place:
longitude = place.get_longitude()
latitude = place.get_latitude()
latitude, longitude = conv_lat_lon(
latitude, longitude, "D.D8")
descr = _pd.display(dbstate.db, place)
evt = EventType(
event.get_type())
eyear = str(
"%04d" % event.get_date_object().to_calendar(self.cal).get_year()) + \
str("%02d" % event.get_date_object().to_calendar(self.cal).get_month()) + \
str("%02d" % event.get_date_object().to_calendar(self.cal).get_day())
if longitude and latitude:
self._append_to_places_list(descr,
evt, _nd.display(person),
latitude, longitude,
descr1, eyear,
event.get_type(),
person.gramps_id,
place.gramps_id,
event.gramps_id,
role
)
else:
self._append_to_places_without_coord(place.gramps_id, descr)
sort1 = sorted(self.place_list, key=operator.itemgetter(6))
self.draw(None, sort1, color, reference)
# merge with the last results
merge_list = []
for the_list in self.sort, sort1:
merge_list += the_list
self.sort = sorted(merge_list, key=operator.itemgetter(6))
def _createmap_for_one_family(self, family, color, place_list, reference):
"""
Create all markers for one family : all event's places with a lat/lon.
"""
dbstate = self.dbstate
person = None
try:
person = dbstate.db.get_person_from_handle(
family.get_father_handle())
except:
return
family_id = family.gramps_id
if person is None: # family without father ?
handle = family.get_mother_handle()
if handle:
person = dbstate.db.get_person_from_handle(handle)
if person is None:
handle = self.uistate.get_active('Person')
if handle:
person = dbstate.db.get_person_from_handle(handle)
if person is not None:
family_list = person.get_family_handle_list()
if len(family_list) > 0:
fhandle = family_list[0] # first is primary
fam = dbstate.db.get_family_from_handle(fhandle)
father = mother = None
handle = fam.get_father_handle()
if handle:
father = dbstate.db.get_person_from_handle(handle)
if father:
comment = _("Father : %(id)s : %(name)s") % {
'id': father.gramps_id,
'name': _nd.display(father)}
self._createmap_for_one_person(father, color,
place_list, reference)
handle = fam.get_mother_handle()
if handle:
mother = dbstate.db.get_person_from_handle(handle)
if mother:
comment = _("Mother : %(id)s : %(name)s") % {
'id': mother.gramps_id,
'name': _nd.display(mother)}
self._createmap_for_one_person(mother, color,
place_list, reference)
index = 0
child_ref_list = fam.get_child_ref_list()
if child_ref_list:
for child_ref in child_ref_list:
child = dbstate.db.get_person_from_handle(child_ref.ref)
if child:
index += 1
comment = _("Child : %(id)s - %(index)d "
": %(name)s") % {
'id' : child.gramps_id,
'index' : index,
'name' : _nd.display(child)
}
self._createmap_for_one_person(child, color,
place_list,
reference)
else:
comment = _("Person : %(id)s %(name)s has no family.") % {
'id' : person.gramps_id,
'name' : _nd.display(person)
}
self._createmap_for_one_person(person, color,
place_list, reference)
def _createmap(self, family_x, color, place_list, reference):
"""
Create all markers for each family's person in the database which has
a lat/lon.
"""
dbstate = self.dbstate
self.cal = config.get('preferences.calendar-format-report')
self.place_list = place_list
self.place_without_coordinates = []
self.minlat = self.maxlat = self.minlon = self.maxlon = 0.0
#self.minyear = 9999
#self.maxyear = 0
latitude = ""
longitude = ""
self.place_list = []
self.place_without_coordinates = []
self.minlat = self.maxlat = self.minlon = self.maxlon = 0.0
#family = self.dbstate.db.get_family_from_handle(family_x)
family = family_x
if family is None:
handle = self.uistate.get_active('Person')
person = None
if handle:
person = self.dbstate.db.get_family_from_handle(handle)
if not person:
return
family_list = person.get_family_handle_list()
for family_hdl in family_list:
family = self.dbstate.db.get_family_from_handle(family_hdl)
if family is not None:
self._createmap_for_one_family(family, color,
place_list, reference)
else:
self._createmap_for_one_family(family, color, place_list, reference)
#self._create_markers()
def bubble_message(self, event, lat, lon, marks):
"""
Create the menu for the selected marker
"""
self.menu = Gtk.Menu()
menu = self.menu
menu.set_title("family")
events = []
message = ""
oldplace = ""
prevmark = None
for mark in marks:
for plce in self.all_place_list:
if plce[3] == mark[3] and plce[4] == mark[4]:
if plce[10] in events:
continue
else:
events.append(plce[10])
if plce[0] != oldplace:
message = "%s :" % plce[0]
self.add_place_bubble_message(event, lat, lon,
marks, menu,
message, plce)
oldplace = plce[0]
message = ""
evt = self.dbstate.db.get_event_from_gramps_id(plce[10])
# format the date as described in preferences.
date = displayer.display(evt.get_date_object())
if date == "":
date = _("Unknown")
if plce[11] == EventRoleType.PRIMARY:
message = "(%s) %s : %s" % (date, plce[2], plce[1])
elif plce[11] == EventRoleType.FAMILY:
(father_name,
mother_name) = self._get_father_and_mother_name(evt)
message = "(%s) %s : %s - %s" % (date, plce[7],
father_name,
mother_name)
else:
descr = evt.get_description()
if descr == "":
descr = _('No description')
message = "(%s) %s => %s" % (date, plce[11], descr)
prevmark = plce
add_item = Gtk.MenuItem(label=message)
add_item.show()
menu.append(add_item)
self.itemoption = Gtk.Menu()
itemoption = self.itemoption
itemoption.set_title(message)
itemoption.show()
add_item.set_submenu(itemoption)
modify = Gtk.MenuItem(label=_("Edit Event"))
modify.show()
modify.connect("activate", self.edit_event,
event, lat, lon, prevmark)
itemoption.append(modify)
center = Gtk.MenuItem(label=_("Center on this place"))
center.show()
center.connect("activate", self.center_here,
event, lat, lon, prevmark)
itemoption.append(center)
menu.show()
menu.popup(None, None, None,
None, event.button, event.time)
return 0
def add_specific_menu(self, menu, event, lat, lon):
"""
Add specific entry to the navigation menu.
"""
add_item = Gtk.MenuItem()
add_item.show()
menu.append(add_item)
add_item = Gtk.MenuItem(
label=_("Choose and bookmark the new reference family"))
add_item.connect("activate", self.select_family)
add_item.show()
menu.append(add_item)
return
def get_default_gramplets(self):
"""
Define the default gramplets for the sidebar and bottombar.
"""
return (("Person Filter",),
())
def specific_options(self, configdialog):
"""
Add specific entry to the preference menu.
Must be done in the associated view.
"""
grid = Gtk.Grid()
grid.set_border_width(12)
grid.set_column_spacing(6)
grid.set_row_spacing(6)
configdialog.add_text(grid,
_('The meeting zone probability radius.\n'
'The colored zone is approximative.\n'
'The meeting zone is only shown for the reference family.\n'
'The value 9 means about 42 miles or 67 kms.\n'
'The value 1 means about 4.6 miles or 7.5 kms.\n'
'The value is in tenth of degree.'),
1, line_wrap=False)
self.config_meeting_slider = configdialog.add_slider(grid,
"",
2, 'geography.maximum_meeting_zone',
(1, 9))
return _('The selection parameters'), grid
def config_connect(self):
"""
used to monitor changes in the ini file
"""
self._config.connect('geography.maximum_meeting_zone',
self.cb_update_meeting_radius)
def cb_update_meeting_radius(self, client, cnxn_id, entry, data):
"""
Called when the radius change
"""
self.goto_handle(handle=None)

View File

@ -0,0 +1,18 @@
390a391,399
> def select_family2(self, *obj):
> """
> Open a selection box to choose the secondary family.
> """
> select_family = SelectorFactory('Family')
> sel = select_family(self.dbstate, self.uistate)
> self.uistate.set_active(sel.run().get_handle(), 'Family')
> self.goto_handle(None)
>
841a851,857
>
> add_item = Gtk.MenuItem(
> label=_("Choose the new active family"))
> add_item.connect("activate", self.select_family2)
> add_item.show()
> menu.append(add_item)
>

View File

@ -0,0 +1,268 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2000-2007 Donald N. Allingham
# 2009 Gary Burton
# Copyright (C) 2011 Tim G L Lyons
#
# 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.
#
"""
The EditPersonRef module provides the EditPersonRef class.
"""
#-------------------------------------------------------------------------
#
# Python modules
#
#-------------------------------------------------------------------------
import pickle
#-------------------------------------------------------------------------
#
# GTK/Gnome modules
#
#-------------------------------------------------------------------------
from gi.repository import Gtk
#-------------------------------------------------------------------------
#
# gramps modules
#
#-------------------------------------------------------------------------
from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.sgettext
from gramps.gen.display.name import displayer as name_displayer
from .editsecondary import EditSecondary
from gramps.gen.lib import NoteType
from ..widgets import MonitoredEntry, PrivacyButton
from ..selectors import SelectorFactory
from .displaytabs import CitationEmbedList, NoteTab
from ..glade import Glade
from ..ddtargets import DdTargets
from gi.repository import Gdk
from gramps.gen.const import URL_MANUAL_SECT1
from ..display import display_url
#-------------------------------------------------------------------------
#
# Constants
#
#-------------------------------------------------------------------------
WIKI_HELP_PAGE = URL_MANUAL_SECT1
WIKI_HELP_SEC = _('manual|Person_Reference_Editor')
#-------------------------------------------------------------------------
#
# EditPersonRef class
#
#-------------------------------------------------------------------------
class EditPersonRef(EditSecondary):
"""
Displays a dialog that allows the user to edit a person reference.
"""
def __init__(self, dbstate, uistate, track, personref, callback):
"""
Displays the dialog box.
personref - The person reference that is to be edited
"""
EditSecondary.__init__(self, dbstate, uistate, track,
personref, callback)
def _local_init(self):
self.top = Glade()
self.set_window(self.top.toplevel,
self.top.get_object("title"),
_('Person Reference Editor'))
self.setup_configs('interface.person-ref', 600, 350)
self.person_label = self.top.get_object('person')
self.person_label.set_use_markup(True)
#allow for drop:
self.person_label.drag_dest_set(Gtk.DestDefaults.MOTION |
Gtk.DestDefaults.DROP,
[DdTargets.PERSON_LINK.target()],
Gdk.DragAction.COPY)
self.person_label.connect('drag_data_received', self.on_drag_persondata_received)
self.person_label.connect('activate_link', self.on_person_label_activate_link)
self._update_dnd_capability()
def _update_dnd_capability(self):
self.label_event_box = self.top.get_object('person_event_box')
# Set the drag action from the label
if self.obj.ref:
self.label_event_box.drag_source_set(
Gdk.ModifierType.BUTTON1_MASK,
[DdTargets.PERSON_LINK.target()], Gdk.DragAction.COPY)
self.label_event_box.drag_source_set_icon_name('gramps-person')
self.label_event_box.connect('drag_data_get', self.drag_data_get)
else:
self.label_event_box.drag_source_unset()
def _setup_fields(self):
if self.obj.ref:
p = self.dbstate.db.get_person_from_handle(self.obj.ref)
self.person_label.set_markup("<a href='gramps://Person/handle/" + p.get_handle() + "'>" + name_displayer.display(p) + "</a>")
# self.person_label.set_text(name_displayer.display(p))
self.street = MonitoredEntry(
self.top.get_object("relationship"),
self.obj.set_relation,
self.obj.get_relation,
self.db.readonly)
self.priv = PrivacyButton(
self.top.get_object("private"),
self.obj,
self.db.readonly)
def _connect_signals(self):
self.define_cancel_button(self.top.get_object('cancel'))
self.define_ok_button(self.top.get_object('ok'),self.save)
self.top.get_object('select').connect('clicked',self._select_person)
self.define_help_button(self.top.get_object('help'),
WIKI_HELP_PAGE, WIKI_HELP_SEC)
def _connect_db_signals(self):
"""
Connect any signals that need to be connected.
Called by the init routine of the base class (_EditPrimary).
"""
self._add_db_signal('person-rebuild', self.close)
self._add_db_signal('person-delete', self.check_for_close)
def check_for_close(self, handles):
"""
Callback method for delete signals.
If there is a delete signal of the primary object we are editing, the
editor (and all child windows spawned) should be closed
"""
if self.obj.ref in handles:
self.close()
def _select_person(self, obj):
SelectPerson = SelectorFactory('Person')
sel = SelectPerson(self.dbstate, self.uistate, self.track)
person = sel.run()
self.update_person(person)
def update_person(self, person):
if person:
self.obj.ref = person.get_handle()
self.person_label.set_markup("<a href='gramps://Person/handle/" + person.get_handle() + "'>" + name_displayer.display(person) + "</a>")
# self.person_label.set_text(name_displayer.display(person))
self._update_dnd_capability()
def find_parent_with_attr(self, attr="dbstate"):
"""
"""
# Find a parent with attr:
obj = self
while obj:
if hasattr(obj, attr):
break
obj = obj.get_parent()
return obj
def on_person_label_activate_link(self, widget, uri):
"""
Handle the standard gtk interface for activate_link.
"""
# this is stupid
if uri.startswith("gramps://"):
# if in a window:
win_obj = self.find_parent_with_attr(attr="dbstate")
if win_obj:
# Edit the object:
obj_class, prop, value = uri[9:].split("/")
from ..editors import EditObject
EditObject(win_obj.dbstate,
win_obj.uistate,
win_obj.track,
obj_class, prop, value)
return
display_url(uri)
def on_drag_persondata_received(self, widget, context, x, y, sel_data,
info, time):
"""
Handle the standard gtk interface for drag_data_received.
"""
if sel_data and sel_data.get_data():
(drag_type, idval, handle, val) = pickle.loads(sel_data.get_data())
person = self.db.get_person_from_handle(handle)
self.update_person(person)
def drag_data_get(self, widget, context, sel_data, info, time):
# get the selected object, returning if not is defined
if info == DdTargets.PERSON_LINK.app_id:
data = (DdTargets.PERSON_LINK.drag_type, id(self), self.obj.ref, 0)
sel_data.set(DdTargets.PERSON_LINK.atom_drag_type, 8, pickle.dumps(data))
def _create_tabbed_pages(self):
"""
Create the notebook tabs and inserts them into the main
window.
"""
notebook = Gtk.Notebook()
self.srcref_list = CitationEmbedList(self.dbstate, self.uistate,
self.track,
self.obj.get_citation_list())
self._add_tab(notebook, self.srcref_list)
self.track_ref_for_deletion("srcref_list")
self.note_tab = NoteTab(self.dbstate, self.uistate, self.track,
self.obj.get_note_list(),
notetype=NoteType.ASSOCIATION)
self._add_tab(notebook, self.note_tab)
self.track_ref_for_deletion("note_tab")
self._setup_notebook_tabs(notebook)
notebook.show_all()
self.top.get_object('vbox').pack_start(notebook, True, True, 0)
def build_menu_names(self, obj):
return (_('Person Reference'),_('Person Reference Editor'))
def save(self,*obj):
"""
Called when the OK button is pressed. Gets data from the
form and updates the data structure.
"""
if self.obj.ref:
if self.callback:
self.callback(self.obj)
self.callback = None
self.close()
else:
from ..dialog import ErrorDialog
ErrorDialog(
_('No person selected'),
_('You must either select a person or Cancel the edit'),
parent=self.uistate.window)

View File

@ -0,0 +1,232 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2000-2007 Donald N. Allingham
# 2009 Gary Burton
# Copyright (C) 2011 Tim G L Lyons
#
# 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.
#
"""
The EditPersonRef module provides the EditPersonRef class.
"""
#-------------------------------------------------------------------------
#
# Python modules
#
#-------------------------------------------------------------------------
import pickle
#-------------------------------------------------------------------------
#
# GTK/Gnome modules
#
#-------------------------------------------------------------------------
from gi.repository import Gtk
#-------------------------------------------------------------------------
#
# gramps modules
#
#-------------------------------------------------------------------------
from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.sgettext
from gramps.gen.display.name import displayer as name_displayer
from .editsecondary import EditSecondary
from gramps.gen.lib import NoteType
from ..widgets import MonitoredEntry, PrivacyButton
from ..selectors import SelectorFactory
from .displaytabs import CitationEmbedList, NoteTab
from ..glade import Glade
from ..ddtargets import DdTargets
from gi.repository import Gdk
from gramps.gen.const import URL_MANUAL_SECT1
#-------------------------------------------------------------------------
#
# Constants
#
#-------------------------------------------------------------------------
WIKI_HELP_PAGE = URL_MANUAL_SECT1
WIKI_HELP_SEC = _('manual|Person_Reference_Editor')
#-------------------------------------------------------------------------
#
# EditPersonRef class
#
#-------------------------------------------------------------------------
class EditPersonRef(EditSecondary):
"""
Displays a dialog that allows the user to edit a person reference.
"""
def __init__(self, dbstate, uistate, track, personref, callback):
"""
Displays the dialog box.
personref - The person reference that is to be edited
"""
EditSecondary.__init__(self, dbstate, uistate, track,
personref, callback)
def _local_init(self):
self.top = Glade()
self.set_window(self.top.toplevel,
self.top.get_object("title"),
_('Person Reference Editor'))
self.setup_configs('interface.person-ref', 600, 350)
self.person_label = self.top.get_object('person')
#allow for drop:
self.person_label.drag_dest_set(Gtk.DestDefaults.MOTION |
Gtk.DestDefaults.DROP,
[DdTargets.PERSON_LINK.target()],
Gdk.DragAction.COPY)
self.person_label.connect('drag_data_received', self.on_drag_persondata_received)
self._update_dnd_capability()
def _update_dnd_capability(self):
self.label_event_box = self.top.get_object('person_event_box')
# Set the drag action from the label
if self.obj.ref:
self.label_event_box.drag_source_set(
Gdk.ModifierType.BUTTON1_MASK,
[DdTargets.PERSON_LINK.target()], Gdk.DragAction.COPY)
self.label_event_box.drag_source_set_icon_name('gramps-person')
self.label_event_box.connect('drag_data_get', self.drag_data_get)
else:
self.label_event_box.drag_source_unset()
def _setup_fields(self):
if self.obj.ref:
p = self.dbstate.db.get_person_from_handle(self.obj.ref)
self.person_label.set_text(name_displayer.display(p))
self.street = MonitoredEntry(
self.top.get_object("relationship"),
self.obj.set_relation,
self.obj.get_relation,
self.db.readonly)
self.priv = PrivacyButton(
self.top.get_object("private"),
self.obj,
self.db.readonly)
def _connect_signals(self):
self.define_cancel_button(self.top.get_object('cancel'))
self.define_ok_button(self.top.get_object('ok'),self.save)
self.top.get_object('select').connect('clicked',self._select_person)
self.define_help_button(self.top.get_object('help'),
WIKI_HELP_PAGE, WIKI_HELP_SEC)
def _connect_db_signals(self):
"""
Connect any signals that need to be connected.
Called by the init routine of the base class (_EditPrimary).
"""
self._add_db_signal('person-rebuild', self.close)
self._add_db_signal('person-delete', self.check_for_close)
def check_for_close(self, handles):
"""
Callback method for delete signals.
If there is a delete signal of the primary object we are editing, the
editor (and all child windows spawned) should be closed
"""
if self.obj.ref in handles:
self.close()
def _select_person(self, obj):
SelectPerson = SelectorFactory('Person')
sel = SelectPerson(self.dbstate, self.uistate, self.track)
person = sel.run()
self.update_person(person)
def update_person(self, person):
if person:
self.obj.ref = person.get_handle()
self.person_label.set_text(name_displayer.display(person))
self._update_dnd_capability()
def on_drag_persondata_received(self, widget, context, x, y, sel_data,
info, time):
"""
Handle the standard gtk interface for drag_data_received.
"""
if sel_data and sel_data.get_data():
(drag_type, idval, handle, val) = pickle.loads(sel_data.get_data())
person = self.db.get_person_from_handle(handle)
self.update_person(person)
def drag_data_get(self, widget, context, sel_data, info, time):
# get the selected object, returning if not is defined
if info == DdTargets.PERSON_LINK.app_id:
data = (DdTargets.PERSON_LINK.drag_type, id(self), self.obj.ref, 0)
sel_data.set(DdTargets.PERSON_LINK.atom_drag_type, 8, pickle.dumps(data))
def _create_tabbed_pages(self):
"""
Create the notebook tabs and inserts them into the main
window.
"""
notebook = Gtk.Notebook()
self.srcref_list = CitationEmbedList(self.dbstate, self.uistate,
self.track,
self.obj.get_citation_list())
self._add_tab(notebook, self.srcref_list)
self.track_ref_for_deletion("srcref_list")
self.note_tab = NoteTab(self.dbstate, self.uistate, self.track,
self.obj.get_note_list(),
notetype=NoteType.ASSOCIATION)
self._add_tab(notebook, self.note_tab)
self.track_ref_for_deletion("note_tab")
self._setup_notebook_tabs(notebook)
notebook.show_all()
self.top.get_object('vbox').pack_start(notebook, True, True, 0)
def build_menu_names(self, obj):
return (_('Person Reference'),_('Person Reference Editor'))
def save(self,*obj):
"""
Called when the OK button is pressed. Gets data from the
form and updates the data structure.
"""
if self.obj.ref:
if self.callback:
self.callback(self.obj)
self.callback = None
self.close()
else:
from ..dialog import ErrorDialog
ErrorDialog(
_('No person selected'),
_('You must either select a person or Cancel the edit'),
parent=self.uistate.window)

View File

@ -0,0 +1,48 @@
58a59
> from ..display import display_url
96a98
> self.person_label.set_use_markup(True)
103a106
> self.person_label.connect('activate_link', self.on_person_label_activate_link)
122c125,126
< self.person_label.set_text(name_displayer.display(p))
---
> self.person_label.set_markup("<a href='gramps://Person/handle/" + p.get_handle() + "'>" + name_displayer.display(p) + "</a>")
> # self.person_label.set_text(name_displayer.display(p))
169c173,174
< self.person_label.set_text(name_displayer.display(person))
---
> self.person_label.set_markup("<a href='gramps://Person/handle/" + person.get_handle() + "'>" + name_displayer.display(person) + "</a>")
> # self.person_label.set_text(name_displayer.display(person))
170a176,206
>
> def find_parent_with_attr(self, attr="dbstate"):
> """
> """
> # Find a parent with attr:
> obj = self
> while obj:
> if hasattr(obj, attr):
> break
> obj = obj.get_parent()
> return obj
>
> def on_person_label_activate_link(self, widget, uri):
> """
> Handle the standard gtk interface for activate_link.
> """
> # this is stupid
> if uri.startswith("gramps://"):
> # if in a window:
> win_obj = self.find_parent_with_attr(attr="dbstate")
> if win_obj:
> # Edit the object:
> obj_class, prop, value = uri[9:].split("/")
> from ..editors import EditObject
> EditObject(win_obj.dbstate,
> win_obj.uistate,
> win_obj.track,
> obj_class, prop, value)
> return
>
> display_url(uri)

View File

@ -0,0 +1,3 @@
# Media Reference Place Chooser
This patch adds a Place chooser to the media reference editor. The Place chooser stores the GRAMPS handle to the Place object as an attribute.

View File

@ -0,0 +1,580 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2000-2006 Donald N. Allingham
# 2008-2009 Stephane Charette <stephanecharette@gmail.com>
# 2009 Gary Burton
# 2011 Robert Cheramy <robert@cheramy.net>
# Copyright (C) 2011 Tim G L Lyons
# Copyright (C) 2013 Nick Hall
#
# 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
#
#-------------------------------------------------------------------------
import os
#-------------------------------------------------------------------------
#
# GTK/Gnome modules
#
#-------------------------------------------------------------------------
from gi.repository import GdkPixbuf
from gi.repository import Gdk
#-------------------------------------------------------------------------
#
# gramps modules
#
#-------------------------------------------------------------------------
from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.sgettext
from ..utils import open_file_with_default_application
from gramps.gen.const import THUMBSCALE
from gramps.gen.mime import get_description, get_type
from gramps.gen.utils.thumbnails import get_thumbnail_image, find_mime_type_pixbuf
from gramps.gen.utils.file import (media_path_full, find_file, create_checksum)
from gramps.gen.lib import NoteType, Attribute
from gramps.gen.db import DbTxn
from .objectentries import PlaceEntry
from ..glade import Glade
from .displaytabs import (CitationEmbedList, MediaAttrEmbedList, MediaBackRefList,
NoteTab)
from ..widgets import (MonitoredSpinButton, MonitoredEntry, PrivacyButton,
MonitoredDate, MonitoredTagList, SelectionWidget, Region)
from .editreference import RefTab, EditReference
from .addmedia import AddMedia
from gramps.gen.const import URL_MANUAL_SECT2
#-------------------------------------------------------------------------
#
# Constants
#
#-------------------------------------------------------------------------
WIKI_HELP_PAGE = URL_MANUAL_SECT2
WIKI_HELP_SEC = _('manual|Media_Reference_Editor_dialog')
#-------------------------------------------------------------------------
#
# EditMediaRef
#
#-------------------------------------------------------------------------
class EditMediaRef(EditReference):
def __init__(self, state, uistate, track, media, media_ref, update):
EditReference.__init__(self, state, uistate, track, media,
media_ref, update)
if not self.source.get_handle():
#show the addmedia dialog immediately, with track of parent.
AddMedia(state, self.uistate, self.track, self.source,
self._update_addmedia)
def _local_init(self):
self.top = Glade()
self.set_window(self.top.toplevel,
self.top.get_object('title'),
_('Media Reference Editor'))
self.setup_configs('interface.media-ref', 600, 450)
self.define_warn_box(self.top.get_object("warn_box"))
self.top.get_object("label427").set_text(_("Y coordinate|Y"))
self.top.get_object("label428").set_text(_("Y coordinate|Y"))
tblref = self.top.get_object('table50')
self.notebook_ref = self.top.get_object('notebook_ref')
self.track_ref_for_deletion("notebook_ref")
self.expander = self.top.get_object('expander1')
#recreate start page as GrampsTab
self.notebook_ref.remove_page(0)
self.reftab = RefTab(self.dbstate, self.uistate, self.track,
_('General'), tblref)
self.track_ref_for_deletion("reftab")
tblref = self.top.get_object('table2')
self.notebook_shared = self.top.get_object('notebook_shared')
#recreate start page as GrampsTab
self.notebook_shared.remove_page(0)
self.track_ref_for_deletion("notebook_shared")
self.primtab = RefTab(self.dbstate, self.uistate, self.track,
_('_General'), tblref)
self.track_ref_for_deletion("primtab")
self.rect_pixbuf = None
def setup_filepath(self):
self.select = self.top.get_object('file_select')
self.track_ref_for_deletion("select")
self.file_path = self.top.get_object("path")
self.track_ref_for_deletion("file_path")
self.file_path.set_text(self.source.get_path())
self.select.connect('clicked', self.select_file)
def determine_mime(self):
descr = get_description(self.source.get_mime_type())
if descr:
self.mimetext.set_text(descr)
path = self.file_path.get_text()
path_full = media_path_full(self.db, path)
if path != self.source.get_path() and path_full != self.source.get_path():
#redetermine mime
mime = get_type(find_file(path_full))
self.source.set_mime_type(mime)
descr = get_description(mime)
if descr:
self.mimetext.set_text(descr)
else:
self.mimetext.set_text(_('Unknown'))
#if mime type not set, is note
if not self.source.get_mime_type():
self.mimetext.set_text(_('Note'))
def draw_preview(self):
"""
Draw the two preview images. This method can be called on eg change of
the path.
"""
mtype = self.source.get_mime_type()
if mtype:
fullpath = media_path_full(self.db, self.source.get_path())
pb = get_thumbnail_image(fullpath, mtype)
self.pixmap.set_from_pixbuf(pb)
self.selection.load_image(fullpath)
else:
pb = find_mime_type_pixbuf('text/plain')
self.pixmap.set_from_pixbuf(pb)
self.selection.load_image('')
def _setup_fields(self):
ebox_shared = self.top.get_object('eventbox')
ebox_shared.connect('button-press-event', self.button_press_event)
self.pixmap = self.top.get_object("pixmap")
self.mimetext = self.top.get_object("type")
self.track_ref_for_deletion("mimetext")
coord = self.source_ref.get_rectangle()
#upgrade path: set invalid (from eg old db) to none
if coord is not None and coord in (
(None,)*4,
(0, 0, 100, 100),
(coord[0], coord[1])*2
):
coord = None
if coord is not None:
self.rectangle = coord
else:
self.rectangle = (0, 0, 100, 100)
self.selection = SelectionWidget()
self.selection.set_multiple_selection(False)
self.selection.connect("region-modified", self.region_modified)
self.selection.connect("region-created", self.region_modified)
self.expander.connect("activate", self.selection.expander)
frame = self.top.get_object("frame9")
frame.add(self.selection)
self.track_ref_for_deletion("selection")
self.selection.show()
self.setup_filepath()
self.determine_mime()
corners = ["corner1_x", "corner1_y", "corner2_x", "corner2_y"]
if coord and isinstance(coord, tuple):
for index, corner in enumerate(corners):
self.top.get_object(corner).set_value(coord[index])
else:
for corner, value in zip(corners, [0, 0, 100, 100]):
self.top.get_object(corner).set_value(value)
if self.dbstate.db.readonly:
for corner in corners:
self.top.get_object(corner).set_sensitive(False)
self.corner1_x_spinbutton = MonitoredSpinButton(
self.top.get_object("corner1_x"),
self.set_corner1_x,
self.get_corner1_x,
self.db.readonly)
self.track_ref_for_deletion("corner1_x_spinbutton")
self.corner1_y_spinbutton = MonitoredSpinButton(
self.top.get_object("corner1_y"),
self.set_corner1_y,
self.get_corner1_y,
self.db.readonly)
self.track_ref_for_deletion("corner1_y_spinbutton")
self.corner2_x_spinbutton = MonitoredSpinButton(
self.top.get_object("corner2_x"),
self.set_corner2_x,
self.get_corner2_x,
self.db.readonly)
self.track_ref_for_deletion("corner2_x_spinbutton")
self.corner2_y_spinbutton = MonitoredSpinButton(
self.top.get_object("corner2_y"),
self.set_corner2_y,
self.get_corner2_y,
self.db.readonly)
self.track_ref_for_deletion("corner2_y_spinbutton")
self.descr_window = MonitoredEntry(
self.top.get_object("description"),
self.source.set_description,
self.source.get_description,
self.db.readonly)
self.ref_privacy = PrivacyButton(
self.top.get_object("private"),
self.source_ref,
self.db.readonly)
self.gid = MonitoredEntry(
self.top.get_object("gid"),
self.source.set_gramps_id,
self.source.get_gramps_id,
self.db.readonly)
self.privacy = PrivacyButton(
self.top.get_object("privacy"),
self.source,
self.db.readonly)
self.path_obj = MonitoredEntry(
self.top.get_object("path"),
self.source.set_path,
self.source.get_path,
self.db.readonly)
self.date_field = MonitoredDate(
self.top.get_object("date_entry"),
self.top.get_object("date_edit"),
self.source.get_date_object(),
self.uistate, self.track,
self.db.readonly)
self.place = PlaceEntry(self.dbstate, self.uistate, self.track,
self.top.get_object("place"),
self.top.get_object("place_event_box"),
self.set_place_handle,
self.get_place_handle,
self.top.get_object("add_del_place"), self.top.get_object("select_place"))
self.tags = MonitoredTagList(
self.top.get_object("tag_label"),
self.top.get_object("tag_button"),
self.source.set_tag_list,
self.source.get_tag_list,
self.db,
self.uistate, self.track,
self.db.readonly)
def _post_init(self):
"""
Initialization that must happen after the window is shown.
"""
self.draw_preview()
self.update_region()
def set_corner1_x(self, value):
"""
Callback for the signal handling of the spinbutton for the first
corner x coordinate of the subsection.
Updates the subsection thumbnail using the given value
@param value: the first corner x coordinate of the subsection in int
"""
self.rectangle = (value,) + self.rectangle[1:]
self.update_region()
def set_corner1_y(self, value):
"""
Callback for the signal handling of the spinbutton for the first
corner y coordinate of the subsection.
Updates the subsection thumbnail using the given value
@param value: the first corner y coordinate of the subsection in int
"""
self.rectangle = self.rectangle[:1] + (value,) + self.rectangle[2:]
self.update_region()
def set_corner2_x(self, value):
"""
Callback for the signal handling of the spinbutton for the second
corner x coordinate of the subsection.
Updates the subsection thumbnail using the given value
@param value: the second corner x coordinate of the subsection in int
"""
self.rectangle = self.rectangle[:2] + (value,) + self.rectangle[3:]
self.update_region()
def set_corner2_y(self, value):
"""
Callback for the signal handling of the spinbutton for the second
corner y coordinate of the subsection.
Updates the subsection thumbnail using the given value
@param value: the second corner y coordinate of the subsection in int
"""
self.rectangle = self.rectangle[:3] + (value,)
self.update_region()
def get_corner1_x(self):
"""
Callback for the signal handling of the spinbutton for the first corner
x coordinate of the subsection.
@returns: the first corner x coordinate of the subsection or 0 if
there is no selection
"""
return self.rectangle[0]
def get_corner1_y(self):
"""
Callback for the signal handling of the spinbutton for the first corner
y coordinate of the subsection.
@returns: the first corner y coordinate of the subsection or 0 if
there is no selection
"""
return self.rectangle[1]
def get_corner2_x(self):
"""
Callback for the signal handling of the spinbutton for the second
corner x coordinate of the subsection.
@returns: the second corner x coordinate of the subsection or 100 if
there is no selection
"""
return self.rectangle[2]
def get_corner2_y(self):
"""
Callback for the signal handling of the spinbutton for the second
corner x coordinate of the subsection.
@returns: the second corner x coordinate of the subsection or 100 if
there is no selection
"""
return self.rectangle[3]
def update_region(self):
"""
Updates the thumbnail of the specified subsection.
"""
if not self.selection.is_image_loaded():
return
real = self.selection.proportional_to_real_rect(self.rectangle)
region = Region(real[0], real[1], real[2], real[3])
self.selection.set_regions([region])
self.selection.select(region) # update the selection box shown
self.selection.refresh()
def region_modified(self, widget):
"""
Update new values when the selection is changed.
"""
real = self.selection.get_selection()
coords = self.selection.real_to_proportional_rect(real)
self.corner1_x_spinbutton.set_value(coords[0])
self.corner1_y_spinbutton.set_value(coords[1])
self.corner2_x_spinbutton.set_value(coords[2])
self.corner2_y_spinbutton.set_value(coords[3])
def build_menu_names(self, person):
"""
Provide the information needed by the base class to define the
window management menu entries.
"""
if self.source:
submenu_label = _('Media: %s') % self.source.get_gramps_id()
else:
submenu_label = _('New Media')
return (_('Media Reference Editor'),submenu_label)
def button_press_event(self, obj, event):
if (event.type == Gdk.EventType.DOUBLE_BUTTON_PRESS
and event.button == 1):
photo_path = media_path_full(self.db, self.source.get_path())
open_file_with_default_application(photo_path, self.uistate)
def _update_addmedia(self, obj):
"""
Called when the add media dialog has been called.
This allows us to update the main form in response to
any changes: Redraw relevant fields: description, mimetype and path
"""
for obj in (self.descr_window, self.path_obj):
obj.update()
self.determine_mime()
self.update_checksum()
self.draw_preview()
def update_checksum(self):
self.uistate.set_busy_cursor(True)
media_path = media_path_full(self.dbstate.db, self.source.get_path())
self.source.set_checksum(create_checksum(os.path.normpath(media_path)))
self.uistate.set_busy_cursor(False)
def select_file(self, val):
self.determine_mime()
path = self.file_path.get_text()
self.source.set_path(path)
AddMedia(self.dbstate, self.uistate, self.track, self.source,
self._update_addmedia)
def _connect_signals(self):
self.define_cancel_button(self.top.get_object('button84'))
self.define_ok_button(self.top.get_object('button82'),self.save)
# TODO help button (rename glade button name)
self.define_help_button(self.top.get_object('button104'),
WIKI_HELP_PAGE, WIKI_HELP_SEC)
def _connect_db_signals(self):
"""
Connect any signals that need to be connected.
Called by the init routine of the base class (_EditPrimary).
"""
self._add_db_signal('media-rebuild', self.close)
self._add_db_signal('media-delete', self.check_for_close)
def _create_tabbed_pages(self):
"""
Create the notebook tabs and inserts them into the main
window.
"""
notebook_ref = self.top.get_object('notebook_ref')
notebook_src = self.top.get_object('notebook_shared')
self._add_tab(notebook_src, self.primtab)
self._add_tab(notebook_ref, self.reftab)
self.srcref_list = CitationEmbedList(self.dbstate,
self.uistate,
self.track,
self.source_ref.get_citation_list())
self._add_tab(notebook_ref, self.srcref_list)
self.track_ref_for_deletion("srcref_list")
self.attr_list = MediaAttrEmbedList(self.dbstate,self.uistate,self.track,
self.source_ref.get_attribute_list())
self._add_tab(notebook_ref, self.attr_list)
self.track_ref_for_deletion("attr_list")
self.backref_list = MediaBackRefList(self.dbstate,self.uistate,self.track,
self.db.find_backlink_handles(self.source.handle),
self.enable_warnbox
)
self._add_tab(notebook_src, self.backref_list)
self.track_ref_for_deletion("backref_list")
self.note_ref_tab = NoteTab(self.dbstate, self.uistate, self.track,
self.source_ref.get_note_list(),
notetype=NoteType.MEDIAREF)
self._add_tab(notebook_ref, self.note_ref_tab)
self.track_ref_for_deletion("note_ref_tab")
self.src_srcref_list = CitationEmbedList(self.dbstate,
self.uistate,
self.track,
self.source.get_citation_list())
self._add_tab(notebook_src, self.src_srcref_list)
self.track_ref_for_deletion("src_srcref_list")
self.src_attr_list = MediaAttrEmbedList(self.dbstate,self.uistate,self.track,
self.source.get_attribute_list())
self._add_tab(notebook_src, self.src_attr_list)
self.track_ref_for_deletion("src_attr_list")
self.src_note_ref_tab = NoteTab(self.dbstate, self.uistate, self.track,
self.source.get_note_list(),
notetype=NoteType.MEDIA)
self._add_tab(notebook_src, self.src_note_ref_tab)
self.track_ref_for_deletion("src_note_ref_tab")
self._setup_notebook_tabs(notebook_src)
self._setup_notebook_tabs(notebook_ref)
def get_place_handle(self):
for attr in self.source.get_attribute_list():
if attr.get_type() == "Place":
return attr.get_value()
return None
def set_place_handle(self, value):
for attr in self.source.get_attribute_list():
if attr.get_type() == "Place":
attr.set_value(value)
return
attr = Attribute()
attr.set_type("Place")
attr.set_value(value)
self.source.get_attribute_list().append(attr)
def save(self,*obj):
#first save primary object
if self.source.handle:
with DbTxn(_("Edit Media Object (%s)") %
self.source.get_description(), self.db) as trans:
self.db.commit_media(self.source, trans)
else:
if self.check_for_duplicate_id('Media'):
return
with DbTxn(_("Add Media Object (%s)") %
self.source.get_description(), self.db) as trans:
self.db.add_media(self.source, trans)
#save reference object in memory
coord = (
self.top.get_object("corner1_x").get_value_as_int(),
self.top.get_object("corner1_y").get_value_as_int(),
self.top.get_object("corner2_x").get_value_as_int(),
self.top.get_object("corner2_y").get_value_as_int(),
)
#do not set unset or invalid coord
if coord is not None and coord in (
(None,)*4,
(0, 0, 100, 100),
(coord[0], coord[1])*2
):
coord = None
self.source_ref.set_rectangle(coord)
#call callback if given
if self.update:
self.update(self.source_ref,self.source)
self.update = None
self.close()

View File

@ -0,0 +1,554 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2000-2006 Donald N. Allingham
# 2008-2009 Stephane Charette <stephanecharette@gmail.com>
# 2009 Gary Burton
# 2011 Robert Cheramy <robert@cheramy.net>
# Copyright (C) 2011 Tim G L Lyons
# Copyright (C) 2013 Nick Hall
#
# 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
#
#-------------------------------------------------------------------------
import os
#-------------------------------------------------------------------------
#
# GTK/Gnome modules
#
#-------------------------------------------------------------------------
from gi.repository import GdkPixbuf
from gi.repository import Gdk
#-------------------------------------------------------------------------
#
# gramps modules
#
#-------------------------------------------------------------------------
from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.sgettext
from ..utils import open_file_with_default_application
from gramps.gen.const import THUMBSCALE
from gramps.gen.mime import get_description, get_type
from gramps.gen.utils.thumbnails import get_thumbnail_image, find_mime_type_pixbuf
from gramps.gen.utils.file import (media_path_full, find_file, create_checksum)
from gramps.gen.lib import NoteType
from gramps.gen.db import DbTxn
from ..glade import Glade
from .displaytabs import (CitationEmbedList, MediaAttrEmbedList, MediaBackRefList,
NoteTab)
from ..widgets import (MonitoredSpinButton, MonitoredEntry, PrivacyButton,
MonitoredDate, MonitoredTagList, SelectionWidget, Region)
from .editreference import RefTab, EditReference
from .addmedia import AddMedia
from gramps.gen.const import URL_MANUAL_SECT2
#-------------------------------------------------------------------------
#
# Constants
#
#-------------------------------------------------------------------------
WIKI_HELP_PAGE = URL_MANUAL_SECT2
WIKI_HELP_SEC = _('manual|Media_Reference_Editor_dialog')
#-------------------------------------------------------------------------
#
# EditMediaRef
#
#-------------------------------------------------------------------------
class EditMediaRef(EditReference):
def __init__(self, state, uistate, track, media, media_ref, update):
EditReference.__init__(self, state, uistate, track, media,
media_ref, update)
if not self.source.get_handle():
#show the addmedia dialog immediately, with track of parent.
AddMedia(state, self.uistate, self.track, self.source,
self._update_addmedia)
def _local_init(self):
self.top = Glade()
self.set_window(self.top.toplevel,
self.top.get_object('title'),
_('Media Reference Editor'))
self.setup_configs('interface.media-ref', 600, 450)
self.define_warn_box(self.top.get_object("warn_box"))
self.top.get_object("label427").set_text(_("Y coordinate|Y"))
self.top.get_object("label428").set_text(_("Y coordinate|Y"))
tblref = self.top.get_object('table50')
self.notebook_ref = self.top.get_object('notebook_ref')
self.track_ref_for_deletion("notebook_ref")
self.expander = self.top.get_object('expander1')
#recreate start page as GrampsTab
self.notebook_ref.remove_page(0)
self.reftab = RefTab(self.dbstate, self.uistate, self.track,
_('General'), tblref)
self.track_ref_for_deletion("reftab")
tblref = self.top.get_object('table2')
self.notebook_shared = self.top.get_object('notebook_shared')
#recreate start page as GrampsTab
self.notebook_shared.remove_page(0)
self.track_ref_for_deletion("notebook_shared")
self.primtab = RefTab(self.dbstate, self.uistate, self.track,
_('_General'), tblref)
self.track_ref_for_deletion("primtab")
self.rect_pixbuf = None
def setup_filepath(self):
self.select = self.top.get_object('file_select')
self.track_ref_for_deletion("select")
self.file_path = self.top.get_object("path")
self.track_ref_for_deletion("file_path")
self.file_path.set_text(self.source.get_path())
self.select.connect('clicked', self.select_file)
def determine_mime(self):
descr = get_description(self.source.get_mime_type())
if descr:
self.mimetext.set_text(descr)
path = self.file_path.get_text()
path_full = media_path_full(self.db, path)
if path != self.source.get_path() and path_full != self.source.get_path():
#redetermine mime
mime = get_type(find_file(path_full))
self.source.set_mime_type(mime)
descr = get_description(mime)
if descr:
self.mimetext.set_text(descr)
else:
self.mimetext.set_text(_('Unknown'))
#if mime type not set, is note
if not self.source.get_mime_type():
self.mimetext.set_text(_('Note'))
def draw_preview(self):
"""
Draw the two preview images. This method can be called on eg change of
the path.
"""
mtype = self.source.get_mime_type()
if mtype:
fullpath = media_path_full(self.db, self.source.get_path())
pb = get_thumbnail_image(fullpath, mtype)
self.pixmap.set_from_pixbuf(pb)
self.selection.load_image(fullpath)
else:
pb = find_mime_type_pixbuf('text/plain')
self.pixmap.set_from_pixbuf(pb)
self.selection.load_image('')
def _setup_fields(self):
ebox_shared = self.top.get_object('eventbox')
ebox_shared.connect('button-press-event', self.button_press_event)
self.pixmap = self.top.get_object("pixmap")
self.mimetext = self.top.get_object("type")
self.track_ref_for_deletion("mimetext")
coord = self.source_ref.get_rectangle()
#upgrade path: set invalid (from eg old db) to none
if coord is not None and coord in (
(None,)*4,
(0, 0, 100, 100),
(coord[0], coord[1])*2
):
coord = None
if coord is not None:
self.rectangle = coord
else:
self.rectangle = (0, 0, 100, 100)
self.selection = SelectionWidget()
self.selection.set_multiple_selection(False)
self.selection.connect("region-modified", self.region_modified)
self.selection.connect("region-created", self.region_modified)
self.expander.connect("activate", self.selection.expander)
frame = self.top.get_object("frame9")
frame.add(self.selection)
self.track_ref_for_deletion("selection")
self.selection.show()
self.setup_filepath()
self.determine_mime()
corners = ["corner1_x", "corner1_y", "corner2_x", "corner2_y"]
if coord and isinstance(coord, tuple):
for index, corner in enumerate(corners):
self.top.get_object(corner).set_value(coord[index])
else:
for corner, value in zip(corners, [0, 0, 100, 100]):
self.top.get_object(corner).set_value(value)
if self.dbstate.db.readonly:
for corner in corners:
self.top.get_object(corner).set_sensitive(False)
self.corner1_x_spinbutton = MonitoredSpinButton(
self.top.get_object("corner1_x"),
self.set_corner1_x,
self.get_corner1_x,
self.db.readonly)
self.track_ref_for_deletion("corner1_x_spinbutton")
self.corner1_y_spinbutton = MonitoredSpinButton(
self.top.get_object("corner1_y"),
self.set_corner1_y,
self.get_corner1_y,
self.db.readonly)
self.track_ref_for_deletion("corner1_y_spinbutton")
self.corner2_x_spinbutton = MonitoredSpinButton(
self.top.get_object("corner2_x"),
self.set_corner2_x,
self.get_corner2_x,
self.db.readonly)
self.track_ref_for_deletion("corner2_x_spinbutton")
self.corner2_y_spinbutton = MonitoredSpinButton(
self.top.get_object("corner2_y"),
self.set_corner2_y,
self.get_corner2_y,
self.db.readonly)
self.track_ref_for_deletion("corner2_y_spinbutton")
self.descr_window = MonitoredEntry(
self.top.get_object("description"),
self.source.set_description,
self.source.get_description,
self.db.readonly)
self.ref_privacy = PrivacyButton(
self.top.get_object("private"),
self.source_ref,
self.db.readonly)
self.gid = MonitoredEntry(
self.top.get_object("gid"),
self.source.set_gramps_id,
self.source.get_gramps_id,
self.db.readonly)
self.privacy = PrivacyButton(
self.top.get_object("privacy"),
self.source,
self.db.readonly)
self.path_obj = MonitoredEntry(
self.top.get_object("path"),
self.source.set_path,
self.source.get_path,
self.db.readonly)
self.date_field = MonitoredDate(
self.top.get_object("date_entry"),
self.top.get_object("date_edit"),
self.source.get_date_object(),
self.uistate, self.track,
self.db.readonly)
self.tags = MonitoredTagList(
self.top.get_object("tag_label"),
self.top.get_object("tag_button"),
self.source.set_tag_list,
self.source.get_tag_list,
self.db,
self.uistate, self.track,
self.db.readonly)
def _post_init(self):
"""
Initialization that must happen after the window is shown.
"""
self.draw_preview()
self.update_region()
def set_corner1_x(self, value):
"""
Callback for the signal handling of the spinbutton for the first
corner x coordinate of the subsection.
Updates the subsection thumbnail using the given value
@param value: the first corner x coordinate of the subsection in int
"""
self.rectangle = (value,) + self.rectangle[1:]
self.update_region()
def set_corner1_y(self, value):
"""
Callback for the signal handling of the spinbutton for the first
corner y coordinate of the subsection.
Updates the subsection thumbnail using the given value
@param value: the first corner y coordinate of the subsection in int
"""
self.rectangle = self.rectangle[:1] + (value,) + self.rectangle[2:]
self.update_region()
def set_corner2_x(self, value):
"""
Callback for the signal handling of the spinbutton for the second
corner x coordinate of the subsection.
Updates the subsection thumbnail using the given value
@param value: the second corner x coordinate of the subsection in int
"""
self.rectangle = self.rectangle[:2] + (value,) + self.rectangle[3:]
self.update_region()
def set_corner2_y(self, value):
"""
Callback for the signal handling of the spinbutton for the second
corner y coordinate of the subsection.
Updates the subsection thumbnail using the given value
@param value: the second corner y coordinate of the subsection in int
"""
self.rectangle = self.rectangle[:3] + (value,)
self.update_region()
def get_corner1_x(self):
"""
Callback for the signal handling of the spinbutton for the first corner
x coordinate of the subsection.
@returns: the first corner x coordinate of the subsection or 0 if
there is no selection
"""
return self.rectangle[0]
def get_corner1_y(self):
"""
Callback for the signal handling of the spinbutton for the first corner
y coordinate of the subsection.
@returns: the first corner y coordinate of the subsection or 0 if
there is no selection
"""
return self.rectangle[1]
def get_corner2_x(self):
"""
Callback for the signal handling of the spinbutton for the second
corner x coordinate of the subsection.
@returns: the second corner x coordinate of the subsection or 100 if
there is no selection
"""
return self.rectangle[2]
def get_corner2_y(self):
"""
Callback for the signal handling of the spinbutton for the second
corner x coordinate of the subsection.
@returns: the second corner x coordinate of the subsection or 100 if
there is no selection
"""
return self.rectangle[3]
def update_region(self):
"""
Updates the thumbnail of the specified subsection.
"""
if not self.selection.is_image_loaded():
return
real = self.selection.proportional_to_real_rect(self.rectangle)
region = Region(real[0], real[1], real[2], real[3])
self.selection.set_regions([region])
self.selection.select(region) # update the selection box shown
self.selection.refresh()
def region_modified(self, widget):
"""
Update new values when the selection is changed.
"""
real = self.selection.get_selection()
coords = self.selection.real_to_proportional_rect(real)
self.corner1_x_spinbutton.set_value(coords[0])
self.corner1_y_spinbutton.set_value(coords[1])
self.corner2_x_spinbutton.set_value(coords[2])
self.corner2_y_spinbutton.set_value(coords[3])
def build_menu_names(self, person):
"""
Provide the information needed by the base class to define the
window management menu entries.
"""
if self.source:
submenu_label = _('Media: %s') % self.source.get_gramps_id()
else:
submenu_label = _('New Media')
return (_('Media Reference Editor'),submenu_label)
def button_press_event(self, obj, event):
if (event.type == Gdk.EventType.DOUBLE_BUTTON_PRESS
and event.button == 1):
photo_path = media_path_full(self.db, self.source.get_path())
open_file_with_default_application(photo_path, self.uistate)
def _update_addmedia(self, obj):
"""
Called when the add media dialog has been called.
This allows us to update the main form in response to
any changes: Redraw relevant fields: description, mimetype and path
"""
for obj in (self.descr_window, self.path_obj):
obj.update()
self.determine_mime()
self.update_checksum()
self.draw_preview()
def update_checksum(self):
self.uistate.set_busy_cursor(True)
media_path = media_path_full(self.dbstate.db, self.source.get_path())
self.source.set_checksum(create_checksum(os.path.normpath(media_path)))
self.uistate.set_busy_cursor(False)
def select_file(self, val):
self.determine_mime()
path = self.file_path.get_text()
self.source.set_path(path)
AddMedia(self.dbstate, self.uistate, self.track, self.source,
self._update_addmedia)
def _connect_signals(self):
self.define_cancel_button(self.top.get_object('button84'))
self.define_ok_button(self.top.get_object('button82'),self.save)
# TODO help button (rename glade button name)
self.define_help_button(self.top.get_object('button104'),
WIKI_HELP_PAGE, WIKI_HELP_SEC)
def _connect_db_signals(self):
"""
Connect any signals that need to be connected.
Called by the init routine of the base class (_EditPrimary).
"""
self._add_db_signal('media-rebuild', self.close)
self._add_db_signal('media-delete', self.check_for_close)
def _create_tabbed_pages(self):
"""
Create the notebook tabs and inserts them into the main
window.
"""
notebook_ref = self.top.get_object('notebook_ref')
notebook_src = self.top.get_object('notebook_shared')
self._add_tab(notebook_src, self.primtab)
self._add_tab(notebook_ref, self.reftab)
self.srcref_list = CitationEmbedList(self.dbstate,
self.uistate,
self.track,
self.source_ref.get_citation_list())
self._add_tab(notebook_ref, self.srcref_list)
self.track_ref_for_deletion("srcref_list")
self.attr_list = MediaAttrEmbedList(self.dbstate,self.uistate,self.track,
self.source_ref.get_attribute_list())
self._add_tab(notebook_ref, self.attr_list)
self.track_ref_for_deletion("attr_list")
self.backref_list = MediaBackRefList(self.dbstate,self.uistate,self.track,
self.db.find_backlink_handles(self.source.handle),
self.enable_warnbox
)
self._add_tab(notebook_src, self.backref_list)
self.track_ref_for_deletion("backref_list")
self.note_ref_tab = NoteTab(self.dbstate, self.uistate, self.track,
self.source_ref.get_note_list(),
notetype=NoteType.MEDIAREF)
self._add_tab(notebook_ref, self.note_ref_tab)
self.track_ref_for_deletion("note_ref_tab")
self.src_srcref_list = CitationEmbedList(self.dbstate,
self.uistate,
self.track,
self.source.get_citation_list())
self._add_tab(notebook_src, self.src_srcref_list)
self.track_ref_for_deletion("src_srcref_list")
self.src_attr_list = MediaAttrEmbedList(self.dbstate,self.uistate,self.track,
self.source.get_attribute_list())
self._add_tab(notebook_src, self.src_attr_list)
self.track_ref_for_deletion("src_attr_list")
self.src_note_ref_tab = NoteTab(self.dbstate, self.uistate, self.track,
self.source.get_note_list(),
notetype=NoteType.MEDIA)
self._add_tab(notebook_src, self.src_note_ref_tab)
self.track_ref_for_deletion("src_note_ref_tab")
self._setup_notebook_tabs(notebook_src)
self._setup_notebook_tabs(notebook_ref)
def save(self,*obj):
#first save primary object
if self.source.handle:
with DbTxn(_("Edit Media Object (%s)") %
self.source.get_description(), self.db) as trans:
self.db.commit_media(self.source, trans)
else:
if self.check_for_duplicate_id('Media'):
return
with DbTxn(_("Add Media Object (%s)") %
self.source.get_description(), self.db) as trans:
self.db.add_media(self.source, trans)
#save reference object in memory
coord = (
self.top.get_object("corner1_x").get_value_as_int(),
self.top.get_object("corner1_y").get_value_as_int(),
self.top.get_object("corner2_x").get_value_as_int(),
self.top.get_object("corner2_y").get_value_as_int(),
)
#do not set unset or invalid coord
if coord is not None and coord in (
(None,)*4,
(0, 0, 100, 100),
(coord[0], coord[1])*2
):
coord = None
self.source_ref.set_rectangle(coord)
#call callback if given
if self.update:
self.update(self.source_ref,self.source)
self.update = None
self.close()

View File

@ -0,0 +1,33 @@
53c53
< from gramps.gen.lib import NoteType
---
> from gramps.gen.lib import NoteType, Attribute
54a55
> from .objectentries import PlaceEntry
275a277,284
>
> self.place = PlaceEntry(self.dbstate, self.uistate, self.track,
> self.top.get_object("place"),
> self.top.get_object("place_event_box"),
> self.set_place_handle,
> self.get_place_handle,
> self.top.get_object("add_del_place"), self.top.get_object("select_place"))
>
515a525,541
>
> def get_place_handle(self):
> for attr in self.source.get_attribute_list():
> if attr.get_type() == "Place":
> return attr.get_value()
> return None
>
> def set_place_handle(self, value):
> for attr in self.source.get_attribute_list():
> if attr.get_type() == "Place":
> attr.set_value(value)
> return
>
> attr = Attribute()
> attr.set_type("Place")
> attr.set_value(value)
> self.source.get_attribute_list().append(attr)

View File

@ -0,0 +1,957 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.18.3 -->
<interface>
<requires lib="gtk+" version="3.10"/>
<requires lib="grampswidgets" version="0.0"/>
<object class="GtkAdjustment" id="adjustment1">
<property name="upper">100</property>
<property name="step_increment">1</property>
<property name="page_increment">10</property>
</object>
<object class="GtkAdjustment" id="adjustment2">
<property name="upper">100</property>
<property name="step_increment">1</property>
<property name="page_increment">10</property>
</object>
<object class="GtkAdjustment" id="adjustment3">
<property name="upper">100</property>
<property name="step_increment">1</property>
<property name="page_increment">10</property>
</object>
<object class="GtkAdjustment" id="adjustment4">
<property name="upper">100</property>
<property name="step_increment">1</property>
<property name="page_increment">10</property>
</object>
<object class="GtkDialog" id="editmediaref">
<property name="can_focus">False</property>
<property name="default_width">600</property>
<property name="default_height">450</property>
<property name="type_hint">dialog</property>
<child internal-child="vbox">
<object class="GtkBox" id="dialog-vbox20">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">8</property>
<child internal-child="action_area">
<object class="GtkButtonBox" id="dialog-action_area20">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="layout_style">end</property>
<child>
<object class="GtkButton" id="button84">
<property name="label" translatable="yes">_Cancel</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="can_default">True</property>
<property name="receives_default">True</property>
<property name="use_underline">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="button82">
<property name="label" translatable="yes">_OK</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="can_default">True</property>
<property name="has_default">True</property>
<property name="receives_default">True</property>
<property name="use_underline">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkButton" id="button104">
<property name="label" translatable="yes">_Help</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="can_default">True</property>
<property name="receives_default">True</property>
<property name="use_underline">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">2</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack_type">end</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkBox" id="vbox22">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="border_width">6</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
<object class="GtkNotebook" id="notebook_ref">
<property name="visible">True</property>
<property name="can_focus">True</property>
<child>
<object class="GtkGrid" id="table50">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="border_width">12</property>
<property name="row_spacing">6</property>
<property name="column_spacing">12</property>
<child>
<object class="GtkLabel" id="label425">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">end</property>
<property name="label" translatable="yes">_Corner 2: X</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">corner2_x</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">4</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label428">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">end</property>
<property name="label" translatable="yes">Y coordinate|Y</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">corner2_y</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">5</property>
</packing>
</child>
<child>
<object class="GtkSpinButton" id="corner2_y">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="tooltip_text" translatable="yes">If media is an image, select the specific part of the image you want to reference.
You can use the mouse on the picture to select a region, or use these spinbuttons to set the top left, and bottom right corner of the referenced region. Point (0,0) is the top left corner of the picture, and (100,100) the bottom right corner.</property>
<property name="invisible_char">●</property>
<property name="adjustment">adjustment4</property>
<property name="climb_rate">1</property>
<property name="numeric">True</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="top_attach">5</property>
</packing>
</child>
<child>
<object class="GtkSpinButton" id="corner2_x">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="tooltip_text" translatable="yes">If media is an image, select the specific part of the image you want to reference.
You can use the mouse on the picture to select a region, or use these spinbuttons to set the top left, and bottom right corner of the referenced region. Point (0,0) is the top left corner of the picture, and (100,100) the bottom right corner.</property>
<property name="invisible_char">●</property>
<property name="adjustment">adjustment3</property>
<property name="climb_rate">1</property>
<property name="numeric">True</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="top_attach">4</property>
</packing>
</child>
<child>
<object class="GtkFrame" id="frame9">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="tooltip_text" translatable="yes">Referenced region of the image media object.
Select a region with clicking and holding the mouse button on the top left corner of the region you want, dragging the mouse to the bottom right corner of the region, and then releasing the mouse button.</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="label_xalign">0</property>
<child>
<placeholder/>
</child>
<child type="label">
<object class="GtkLabel" id="label707">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Preview</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
<property name="height">6</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label426">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">end</property>
<property name="label" translatable="yes">_Corner 1: X</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">corner1_x</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">2</property>
</packing>
</child>
<child>
<object class="GtkSpinButton" id="corner1_x">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="tooltip_text" translatable="yes">If media is an image, select the specific part of the image you want to reference.
You can use the mouse on the picture to select a region, or use these spinbuttons to set the top left, and bottom right corner of the referenced region. Point (0,0) is the top left corner of the picture, and (100,100) the bottom right corner.
</property>
<property name="invisible_char">●</property>
<property name="shadow_type">none</property>
<property name="adjustment">adjustment2</property>
<property name="climb_rate">1</property>
<property name="numeric">True</property>
<property name="update_policy">if-valid</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="top_attach">2</property>
</packing>
</child>
<child>
<object class="GtkSpinButton" id="corner1_y">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="tooltip_text" translatable="yes">If media is an image, select the specific part of the image you want to reference.
You can use the mouse on the picture to select a region, or use these spinbuttons to set the top left, and bottom right corner of the referenced region. Point (0,0) is the top left corner of the picture, and (100,100) the bottom right corner.</property>
<property name="invisible_char">●</property>
<property name="adjustment">adjustment1</property>
<property name="climb_rate">1</property>
<property name="numeric">True</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="top_attach">3</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label427">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">end</property>
<property name="label" translatable="yes">Y coordinate|Y</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">corner1_y</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">3</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">4</property>
</packing>
</child>
<child>
<object class="GtkBox" id="hbox1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkToggleButton" id="private">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="relief">none</property>
<child>
<object class="GtkImage" id="image2686">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">dialog-password</property>
<property name="icon_size">1</property>
<child internal-child="accessible">
<object class="AtkObject" id="image2686-atkobject">
<property name="AtkObject::accessible-description" translatable="yes">Privacy</property>
</object>
</child>
</object>
</child>
<child internal-child="accessible">
<object class="AtkObject" id="private-atkobject">
<property name="AtkObject::accessible-name" translatable="yes">Private</property>
</object>
</child>
<accelerator key="p" signal="activate" modifiers="GDK_CONTROL_MASK"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="pack_type">end</property>
<property name="position">0</property>
</packing>
</child>
</object>
<packing>
<property name="left_attach">2</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="dummy">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="vexpand">True</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
</object>
</child>
<child type="tab">
<object class="GtkLabel" id="label424">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">General</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
<packing>
<property name="tab_fill">False</property>
</packing>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="padding">10</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkExpander" id="expander1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<child>
<object class="GtkNotebook" id="notebook_shared">
<property name="visible">True</property>
<property name="can_focus">True</property>
<child>
<object class="GtkGrid" id="table2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="border_width">12</property>
<property name="row_spacing">6</property>
<property name="column_spacing">12</property>
<child>
<object class="GtkLabel" id="label129">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="label" translatable="yes">_Path:</property>
<property name="use_underline">True</property>
<property name="justify">center</property>
<property name="mnemonic_widget">path</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">4</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label132">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="label" translatable="yes">_ID:</property>
<property name="use_underline">True</property>
<property name="justify">center</property>
<property name="mnemonic_widget">gid</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label126">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="label" translatable="yes">_Title:</property>
<property name="use_underline">True</property>
<property name="justify">center</property>
<property name="mnemonic_widget">description</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="UndoableEntry" id="description">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="tooltip_text" translatable="yes">Descriptive title for this media object.</property>
<property name="hexpand">True</property>
<property name="invisible_char">●</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkBox" id="warn_box">
<property name="can_focus">False</property>
<property name="border_width">6</property>
<property name="spacing">12</property>
<child>
<object class="GtkImage" id="image2705">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="pixel_size">48</property>
<property name="icon_name">dialog-warning</property>
<property name="icon_size">6</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label659">
<property name="width_request">400</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="margin_top">3</property>
<property name="margin_bottom">3</property>
<property name="label" translatable="yes">&lt;b&gt;Note:&lt;/b&gt; Any changes in the shared media object information will be reflected in the media object itself.</property>
<property name="use_markup">True</property>
<property name="use_underline">True</property>
<property name="wrap">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">7</property>
<property name="width">3</property>
</packing>
</child>
<child>
<object class="GtkFrame" id="frame6">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label_xalign">0</property>
<child>
<object class="GtkEventBox" id="eventbox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="has_tooltip">True</property>
<property name="tooltip_markup">Double click image to view in an external viewer</property>
<property name="tooltip_text" translatable="yes">Double click image to view in an external viewer</property>
<child>
<object class="GtkImage" id="pixmap">
<property name="width_request">100</property>
<property name="height_request">100</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
</child>
</object>
</child>
<child type="label">
<object class="GtkLabel" id="label175">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Preview</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
<property name="height">5</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label660">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="label" translatable="yes">Type:</property>
<property name="mnemonic_widget">type</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">6</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="type">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="tooltip_text" translatable="yes">Type of media object as indicated by the computer, eg Image, Video, ...</property>
<property name="halign">start</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="top_attach">6</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label422">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="label" translatable="yes">_Date:</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">date_entry</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">2</property>
</packing>
</child>
<child>
<object class="ValidatableMaskedEntry" id="date_entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hexpand">True</property>
<property name="invisible_char">•</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="top_attach">2</property>
</packing>
</child>
<child>
<object class="GtkButton" id="date_edit">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="has_tooltip">True</property>
<property name="tooltip_text" translatable="yes">Invoke date editor</property>
<property name="relief">none</property>
<child>
<object class="GtkImage" id="image2264">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">gramps-date</property>
<child internal-child="accessible">
<object class="AtkObject" id="image2264-atkobject">
<property name="AtkObject::accessible-description" translatable="yes">Date</property>
</object>
</child>
</object>
</child>
<accessibility>
<relation type="labelled-by" target="label422"/>
</accessibility>
<child internal-child="accessible">
<object class="AtkObject" id="date_edit-atkobject">
<property name="AtkObject::accessible-name" translatable="yes">Date</property>
</object>
</child>
<accelerator key="d" signal="activate" modifiers="GDK_CONTROL_MASK"/>
</object>
<packing>
<property name="left_attach">3</property>
<property name="top_attach">2</property>
</packing>
</child>
<child>
<object class="GtkToggleButton" id="privacy">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="relief">none</property>
<child>
<object class="GtkImage" id="image2710">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">dialog-password</property>
<property name="icon_size">1</property>
<child internal-child="accessible">
<object class="AtkObject" id="image2710-atkobject">
<property name="AtkObject::accessible-description" translatable="yes">Privacy</property>
</object>
</child>
</object>
</child>
<child internal-child="accessible">
<object class="AtkObject" id="privacy-atkobject">
<property name="AtkObject::accessible-name" translatable="yes">Private</property>
</object>
</child>
</object>
<packing>
<property name="left_attach">3</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="UndoableEntry" id="gid">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hexpand">True</property>
<property name="invisible_char">•</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="file_select">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="has_tooltip">True</property>
<property name="tooltip_text" translatable="yes">Select a file</property>
<property name="relief">none</property>
<child>
<object class="GtkImage" id="image2673">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">document-open</property>
<property name="icon_size">1</property>
<child internal-child="accessible">
<object class="AtkObject" id="image2673-atkobject">
<property name="AtkObject::accessible-description" translatable="yes">Folder</property>
</object>
</child>
</object>
</child>
<accessibility>
<relation type="labelled-by" target="label129"/>
</accessibility>
<child internal-child="accessible">
<object class="AtkObject" id="file_select-atkobject">
<property name="AtkObject::accessible-name" translatable="yes">Path</property>
</object>
</child>
</object>
<packing>
<property name="left_attach">3</property>
<property name="top_attach">4</property>
</packing>
</child>
<child>
<object class="UndoableEntry" id="path">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hexpand">True</property>
<property name="invisible_char">•</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="top_attach">4</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="label" translatable="yes">_Tags:</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">tag_button</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">5</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="tag_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="top_attach">5</property>
</packing>
</child>
<child>
<object class="GtkButton" id="tag_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<accessibility>
<relation type="labelled-by" target="label1"/>
</accessibility>
<child internal-child="accessible">
<object class="AtkObject" id="tag_button-atkobject">
<property name="AtkObject::accessible-name" translatable="yes">Tags</property>
</object>
</child>
</object>
<packing>
<property name="left-attach">3</property>
<property name="top-attach">5</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label157">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="halign">start</property>
<property name="margin-top">3</property>
<property name="margin-bottom">3</property>
<property name="label" translatable="yes">_Place:</property>
<property name="use-underline">True</property>
<property name="justify">center</property>
<property name="mnemonic-widget">select_place</property>
</object>
<packing>
<property name="left-attach">1</property>
<property name="top-attach">3</property>
</packing>
</child>
<child>
<object class="GtkButton" id="add_del_place">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="relief">none</property>
<child>
<object class="GtkImage" id="image2699">
<property name="visible">True</property>
<property name="can-focus">False</property>
</object>
</child>
<accelerator key="a" signal="activate" modifiers="GDK_CONTROL_MASK"/>
</object>
<packing>
<property name="left-attach">3</property>
<property name="top-attach">3</property>
</packing>
</child>
<child>
<object class="GtkBox" id="hbox130">
<property name="visible">True</property>
<property name="can-focus">False</property>
<child>
<object class="GtkEventBox" id="place_event_box">
<property name="can-focus">False</property>
<property name="visible-window">False</property>
<child>
<object class="GtkLabel" id="place">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="halign">start</property>
<property name="hexpand">True</property>
<property name="ellipsize">end</property>
</object>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="select_place">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="relief">none</property>
<child>
<object class="GtkImage" id="image2700">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="icon-name">gtk-index</property>
<child internal-child="accessible">
<object class="AtkObject" id="image2700-atkobject">
<property name="AtkObject::accessible-description" translatable="yes">Selector</property>
</object>
</child>
</object>
</child>
<accessibility>
<relation type="labelled-by" target="place"/>
<property name="visible">True</property>
<property name="can-focus">False</property>
</object>
</child>
<accelerator key="a" signal="activate" modifiers="GDK_CONTROL_MASK"/>
</object>
<packing>
<property name="left-attach">3</property>
<property name="top-attach">3</property>
</packing>
</child>
<child>
<object class="GtkBox" id="hbox130">
<property name="visible">True</property>
<property name="can-focus">False</property>
<child>
<object class="GtkEventBox" id="place_event_box">
<property name="can-focus">False</property>
<property name="visible-window">False</property>
<child>
<object class="GtkLabel" id="place">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="halign">start</property>
<property name="hexpand">True</property>
<property name="ellipsize">end</property>
</object>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="select_place">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="receives-default">True</property>
<property name="relief">none</property>
<child>
<object class="GtkImage" id="image2700">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="icon-name">gtk-index</property>
<child internal-child="accessible">
<object class="AtkObject" id="image2700-atkobject">
<property name="AtkObject::accessible-description" translatable="yes">Selector</property>
</object>
</child>
</object>
</child>
<accessibility>
<relation type="labelled-by" target="place"/>
</accessibility>
<child internal-child="accessible">
<object class="AtkObject" id="select_place-atkobject">
<property name="AtkObject::accessible-name" translatable="yes">Place</property>
</object>
</child>
<accelerator key="s" signal="activate" modifiers="GDK_CONTROL_MASK"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="left-attach">2</property>
<property name="top-attach">3</property>
</packing>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="tab_fill">False</property>
</packing>
</child>
<child type="tab">
<object class="GtkLabel" id="label617">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">General</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
<packing>
<property name="tab_fill">False</property>
</packing>
</child>
</object>
</child>
<child type="label">
<object class="GtkLabel" id="label616">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Shared Information</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
<action-widgets>
<action-widget response="-6">button84</action-widget>
<action-widget response="-5">button82</action-widget>
<action-widget response="-11">button104</action-widget>
</action-widgets>
</object>
</interface>

View File

@ -0,0 +1,799 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.18.3 -->
<interface>
<requires lib="gtk+" version="3.10"/>
<requires lib="grampswidgets" version="0.0"/>
<object class="GtkAdjustment" id="adjustment1">
<property name="upper">100</property>
<property name="step_increment">1</property>
<property name="page_increment">10</property>
</object>
<object class="GtkAdjustment" id="adjustment2">
<property name="upper">100</property>
<property name="step_increment">1</property>
<property name="page_increment">10</property>
</object>
<object class="GtkAdjustment" id="adjustment3">
<property name="upper">100</property>
<property name="step_increment">1</property>
<property name="page_increment">10</property>
</object>
<object class="GtkAdjustment" id="adjustment4">
<property name="upper">100</property>
<property name="step_increment">1</property>
<property name="page_increment">10</property>
</object>
<object class="GtkDialog" id="editmediaref">
<property name="can_focus">False</property>
<property name="default_width">600</property>
<property name="default_height">450</property>
<property name="type_hint">dialog</property>
<child internal-child="vbox">
<object class="GtkBox" id="dialog-vbox20">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<property name="spacing">8</property>
<child internal-child="action_area">
<object class="GtkButtonBox" id="dialog-action_area20">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="layout_style">end</property>
<child>
<object class="GtkButton" id="button84">
<property name="label" translatable="yes">_Cancel</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="can_default">True</property>
<property name="receives_default">True</property>
<property name="use_underline">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="button82">
<property name="label" translatable="yes">_OK</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="can_default">True</property>
<property name="has_default">True</property>
<property name="receives_default">True</property>
<property name="use_underline">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkButton" id="button104">
<property name="label" translatable="yes">_Help</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="can_default">True</property>
<property name="receives_default">True</property>
<property name="use_underline">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">2</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack_type">end</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkBox" id="vbox22">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="border_width">6</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<child>
<object class="GtkNotebook" id="notebook_ref">
<property name="visible">True</property>
<property name="can_focus">True</property>
<child>
<object class="GtkGrid" id="table50">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="border_width">12</property>
<property name="row_spacing">6</property>
<property name="column_spacing">12</property>
<child>
<object class="GtkLabel" id="label425">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">end</property>
<property name="label" translatable="yes">_Corner 2: X</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">corner2_x</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">4</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label428">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">end</property>
<property name="label" translatable="yes">Y coordinate|Y</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">corner2_y</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">5</property>
</packing>
</child>
<child>
<object class="GtkSpinButton" id="corner2_y">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="tooltip_text" translatable="yes">If media is an image, select the specific part of the image you want to reference.
You can use the mouse on the picture to select a region, or use these spinbuttons to set the top left, and bottom right corner of the referenced region. Point (0,0) is the top left corner of the picture, and (100,100) the bottom right corner.</property>
<property name="invisible_char">●</property>
<property name="adjustment">adjustment4</property>
<property name="climb_rate">1</property>
<property name="numeric">True</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="top_attach">5</property>
</packing>
</child>
<child>
<object class="GtkSpinButton" id="corner2_x">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="tooltip_text" translatable="yes">If media is an image, select the specific part of the image you want to reference.
You can use the mouse on the picture to select a region, or use these spinbuttons to set the top left, and bottom right corner of the referenced region. Point (0,0) is the top left corner of the picture, and (100,100) the bottom right corner.</property>
<property name="invisible_char">●</property>
<property name="adjustment">adjustment3</property>
<property name="climb_rate">1</property>
<property name="numeric">True</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="top_attach">4</property>
</packing>
</child>
<child>
<object class="GtkFrame" id="frame9">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="tooltip_text" translatable="yes">Referenced region of the image media object.
Select a region with clicking and holding the mouse button on the top left corner of the region you want, dragging the mouse to the bottom right corner of the region, and then releasing the mouse button.</property>
<property name="hexpand">True</property>
<property name="vexpand">True</property>
<property name="label_xalign">0</property>
<child>
<placeholder/>
</child>
<child type="label">
<object class="GtkLabel" id="label707">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Preview</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
<property name="height">6</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label426">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">end</property>
<property name="label" translatable="yes">_Corner 1: X</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">corner1_x</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">2</property>
</packing>
</child>
<child>
<object class="GtkSpinButton" id="corner1_x">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="tooltip_text" translatable="yes">If media is an image, select the specific part of the image you want to reference.
You can use the mouse on the picture to select a region, or use these spinbuttons to set the top left, and bottom right corner of the referenced region. Point (0,0) is the top left corner of the picture, and (100,100) the bottom right corner.
</property>
<property name="invisible_char">●</property>
<property name="shadow_type">none</property>
<property name="adjustment">adjustment2</property>
<property name="climb_rate">1</property>
<property name="numeric">True</property>
<property name="update_policy">if-valid</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="top_attach">2</property>
</packing>
</child>
<child>
<object class="GtkSpinButton" id="corner1_y">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="tooltip_text" translatable="yes">If media is an image, select the specific part of the image you want to reference.
You can use the mouse on the picture to select a region, or use these spinbuttons to set the top left, and bottom right corner of the referenced region. Point (0,0) is the top left corner of the picture, and (100,100) the bottom right corner.</property>
<property name="invisible_char">●</property>
<property name="adjustment">adjustment1</property>
<property name="climb_rate">1</property>
<property name="numeric">True</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="top_attach">3</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label427">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">end</property>
<property name="label" translatable="yes">Y coordinate|Y</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">corner1_y</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">3</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">4</property>
</packing>
</child>
<child>
<object class="GtkBox" id="hbox1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkToggleButton" id="private">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="relief">none</property>
<child>
<object class="GtkImage" id="image2686">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">dialog-password</property>
<property name="icon_size">1</property>
<child internal-child="accessible">
<object class="AtkObject" id="image2686-atkobject">
<property name="AtkObject::accessible-description" translatable="yes">Privacy</property>
</object>
</child>
</object>
</child>
<child internal-child="accessible">
<object class="AtkObject" id="private-atkobject">
<property name="AtkObject::accessible-name" translatable="yes">Private</property>
</object>
</child>
<accelerator key="p" signal="activate" modifiers="GDK_CONTROL_MASK"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="pack_type">end</property>
<property name="position">0</property>
</packing>
</child>
</object>
<packing>
<property name="left_attach">2</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="dummy">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="vexpand">True</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
</object>
</child>
<child type="tab">
<object class="GtkLabel" id="label424">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">General</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
<packing>
<property name="tab_fill">False</property>
</packing>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="padding">10</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkExpander" id="expander1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<child>
<object class="GtkNotebook" id="notebook_shared">
<property name="visible">True</property>
<property name="can_focus">True</property>
<child>
<object class="GtkGrid" id="table2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="border_width">12</property>
<property name="row_spacing">6</property>
<property name="column_spacing">12</property>
<child>
<object class="GtkLabel" id="label129">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="label" translatable="yes">_Path:</property>
<property name="use_underline">True</property>
<property name="justify">center</property>
<property name="mnemonic_widget">path</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">3</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label132">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="label" translatable="yes">_ID:</property>
<property name="use_underline">True</property>
<property name="justify">center</property>
<property name="mnemonic_widget">gid</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label126">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="label" translatable="yes">_Title:</property>
<property name="use_underline">True</property>
<property name="justify">center</property>
<property name="mnemonic_widget">description</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="UndoableEntry" id="description">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="tooltip_text" translatable="yes">Descriptive title for this media object.</property>
<property name="hexpand">True</property>
<property name="invisible_char">●</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkBox" id="warn_box">
<property name="can_focus">False</property>
<property name="border_width">6</property>
<property name="spacing">12</property>
<child>
<object class="GtkImage" id="image2705">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="pixel_size">48</property>
<property name="icon_name">dialog-warning</property>
<property name="icon_size">6</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label659">
<property name="width_request">400</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="margin_top">3</property>
<property name="margin_bottom">3</property>
<property name="label" translatable="yes">&lt;b&gt;Note:&lt;/b&gt; Any changes in the shared media object information will be reflected in the media object itself.</property>
<property name="use_markup">True</property>
<property name="use_underline">True</property>
<property name="wrap">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">6</property>
<property name="width">3</property>
</packing>
</child>
<child>
<object class="GtkFrame" id="frame6">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label_xalign">0</property>
<child>
<object class="GtkEventBox" id="eventbox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="has_tooltip">True</property>
<property name="tooltip_markup">Double click image to view in an external viewer</property>
<property name="tooltip_text" translatable="yes">Double click image to view in an external viewer</property>
<child>
<object class="GtkImage" id="pixmap">
<property name="width_request">100</property>
<property name="height_request">100</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
</child>
</object>
</child>
<child type="label">
<object class="GtkLabel" id="label175">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Preview</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
<property name="height">5</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label660">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="label" translatable="yes">Type:</property>
<property name="mnemonic_widget">type</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">5</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="type">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="tooltip_text" translatable="yes">Type of media object as indicated by the computer, eg Image, Video, ...</property>
<property name="halign">start</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="top_attach">5</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label422">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="label" translatable="yes">_Date:</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">date_entry</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">2</property>
</packing>
</child>
<child>
<object class="ValidatableMaskedEntry" id="date_entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hexpand">True</property>
<property name="invisible_char">•</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="top_attach">2</property>
</packing>
</child>
<child>
<object class="GtkButton" id="date_edit">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="has_tooltip">True</property>
<property name="tooltip_text" translatable="yes">Invoke date editor</property>
<property name="relief">none</property>
<child>
<object class="GtkImage" id="image2264">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">gramps-date</property>
<child internal-child="accessible">
<object class="AtkObject" id="image2264-atkobject">
<property name="AtkObject::accessible-description" translatable="yes">Date</property>
</object>
</child>
</object>
</child>
<accessibility>
<relation type="labelled-by" target="label422"/>
</accessibility>
<child internal-child="accessible">
<object class="AtkObject" id="date_edit-atkobject">
<property name="AtkObject::accessible-name" translatable="yes">Date</property>
</object>
</child>
<accelerator key="d" signal="activate" modifiers="GDK_CONTROL_MASK"/>
</object>
<packing>
<property name="left_attach">3</property>
<property name="top_attach">2</property>
</packing>
</child>
<child>
<object class="GtkToggleButton" id="privacy">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="relief">none</property>
<child>
<object class="GtkImage" id="image2710">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">dialog-password</property>
<property name="icon_size">1</property>
<child internal-child="accessible">
<object class="AtkObject" id="image2710-atkobject">
<property name="AtkObject::accessible-description" translatable="yes">Privacy</property>
</object>
</child>
</object>
</child>
<child internal-child="accessible">
<object class="AtkObject" id="privacy-atkobject">
<property name="AtkObject::accessible-name" translatable="yes">Private</property>
</object>
</child>
</object>
<packing>
<property name="left_attach">3</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="UndoableEntry" id="gid">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hexpand">True</property>
<property name="invisible_char">•</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="file_select">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="has_tooltip">True</property>
<property name="tooltip_text" translatable="yes">Select a file</property>
<property name="relief">none</property>
<child>
<object class="GtkImage" id="image2673">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">document-open</property>
<property name="icon_size">1</property>
<child internal-child="accessible">
<object class="AtkObject" id="image2673-atkobject">
<property name="AtkObject::accessible-description" translatable="yes">Folder</property>
</object>
</child>
</object>
</child>
<accessibility>
<relation type="labelled-by" target="label129"/>
</accessibility>
<child internal-child="accessible">
<object class="AtkObject" id="file_select-atkobject">
<property name="AtkObject::accessible-name" translatable="yes">Path</property>
</object>
</child>
</object>
<packing>
<property name="left_attach">3</property>
<property name="top_attach">3</property>
</packing>
</child>
<child>
<object class="UndoableEntry" id="path">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hexpand">True</property>
<property name="invisible_char">•</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="top_attach">3</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="label" translatable="yes">_Tags:</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">tag_button</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">4</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="tag_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="top_attach">4</property>
</packing>
</child>
<child>
<object class="GtkButton" id="tag_button">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<accessibility>
<relation type="labelled-by" target="label1"/>
</accessibility>
<child internal-child="accessible">
<object class="AtkObject" id="tag_button-atkobject">
<property name="AtkObject::accessible-name" translatable="yes">Tags</property>
</object>
</child>
</object>
<packing>
<property name="left_attach">3</property>
<property name="top_attach">4</property>
</packing>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="tab_fill">False</property>
</packing>
</child>
<child type="tab">
<object class="GtkLabel" id="label617">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">General</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
<packing>
<property name="tab_fill">False</property>
</packing>
</child>
</object>
</child>
<child type="label">
<object class="GtkLabel" id="label616">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Shared Information</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
<action-widgets>
<action-widget response="-6">button84</action-widget>
<action-widget response="-5">button82</action-widget>
<action-widget response="-11">button104</action-widget>
</action-widgets>
</object>
</interface>

View File

@ -0,0 +1,197 @@
386c386
< <property name="top_attach">3</property>
---
> <property name="top_attach">4</property>
473c473
< <property name="top_attach">6</property>
---
> <property name="top_attach">7</property>
526c526
< <property name="top_attach">5</property>
---
> <property name="top_attach">6</property>
538c538
< <property name="top_attach">5</property>
---
> <property name="top_attach">6</property>
676c676
< <property name="top_attach">3</property>
---
> <property name="top_attach">4</property>
688c688
< <property name="top_attach">3</property>
---
> <property name="top_attach">4</property>
702c702
< <property name="top_attach">4</property>
---
> <property name="top_attach">5</property>
713c713
< <property name="top_attach">4</property>
---
> <property name="top_attach">5</property>
731,732c731,887
< <property name="left_attach">3</property>
< <property name="top_attach">4</property>
---
> <property name="left-attach">3</property>
> <property name="top-attach">5</property>
> </packing>
> </child>
> <child>
> <object class="GtkLabel" id="label157">
> <property name="visible">True</property>
> <property name="can-focus">False</property>
> <property name="halign">start</property>
> <property name="margin-top">3</property>
> <property name="margin-bottom">3</property>
> <property name="label" translatable="yes">_Place:</property>
> <property name="use-underline">True</property>
> <property name="justify">center</property>
> <property name="mnemonic-widget">select_place</property>
> </object>
> <packing>
> <property name="left-attach">1</property>
> <property name="top-attach">3</property>
> </packing>
> </child>
> <child>
> <object class="GtkButton" id="add_del_place">
> <property name="visible">True</property>
> <property name="can-focus">True</property>
> <property name="receives-default">True</property>
> <property name="relief">none</property>
> <child>
> <object class="GtkImage" id="image2699">
> <property name="visible">True</property>
> <property name="can-focus">False</property>
> </object>
> </child>
> <accelerator key="a" signal="activate" modifiers="GDK_CONTROL_MASK"/>
> </object>
> <packing>
> <property name="left-attach">3</property>
> <property name="top-attach">3</property>
> </packing>
> </child>
> <child>
> <object class="GtkBox" id="hbox130">
> <property name="visible">True</property>
> <property name="can-focus">False</property>
> <child>
> <object class="GtkEventBox" id="place_event_box">
> <property name="can-focus">False</property>
> <property name="visible-window">False</property>
> <child>
> <object class="GtkLabel" id="place">
> <property name="visible">True</property>
> <property name="can-focus">False</property>
> <property name="halign">start</property>
> <property name="hexpand">True</property>
> <property name="ellipsize">end</property>
> </object>
> </child>
> </object>
> <packing>
> <property name="expand">True</property>
> <property name="fill">True</property>
> <property name="position">0</property>
> </packing>
> </child>
> <child>
> <object class="GtkButton" id="select_place">
> <property name="visible">True</property>
> <property name="can-focus">True</property>
> <property name="receives-default">True</property>
> <property name="relief">none</property>
> <child>
> <object class="GtkImage" id="image2700">
> <property name="visible">True</property>
> <property name="can-focus">False</property>
> <property name="icon-name">gtk-index</property>
> <child internal-child="accessible">
> <object class="AtkObject" id="image2700-atkobject">
> <property name="AtkObject::accessible-description" translatable="yes">Selector</property>
> </object>
> </child>
> </object>
> </child>
> <accessibility>
> <relation type="labelled-by" target="place"/>
> <property name="visible">True</property>
> <property name="can-focus">False</property>
> </object>
> </child>
> <accelerator key="a" signal="activate" modifiers="GDK_CONTROL_MASK"/>
> </object>
> <packing>
> <property name="left-attach">3</property>
> <property name="top-attach">3</property>
> </packing>
> </child>
> <child>
> <object class="GtkBox" id="hbox130">
> <property name="visible">True</property>
> <property name="can-focus">False</property>
> <child>
> <object class="GtkEventBox" id="place_event_box">
> <property name="can-focus">False</property>
> <property name="visible-window">False</property>
> <child>
> <object class="GtkLabel" id="place">
> <property name="visible">True</property>
> <property name="can-focus">False</property>
> <property name="halign">start</property>
> <property name="hexpand">True</property>
> <property name="ellipsize">end</property>
> </object>
> </child>
> </object>
> <packing>
> <property name="expand">True</property>
> <property name="fill">True</property>
> <property name="position">0</property>
> </packing>
> </child>
> <child>
> <object class="GtkButton" id="select_place">
> <property name="visible">True</property>
> <property name="can-focus">True</property>
> <property name="receives-default">True</property>
> <property name="relief">none</property>
> <child>
> <object class="GtkImage" id="image2700">
> <property name="visible">True</property>
> <property name="can-focus">False</property>
> <property name="icon-name">gtk-index</property>
> <child internal-child="accessible">
> <object class="AtkObject" id="image2700-atkobject">
> <property name="AtkObject::accessible-description" translatable="yes">Selector</property>
> </object>
> </child>
> </object>
> </child>
> <accessibility>
> <relation type="labelled-by" target="place"/>
> </accessibility>
> <child internal-child="accessible">
> <object class="AtkObject" id="select_place-atkobject">
> <property name="AtkObject::accessible-name" translatable="yes">Place</property>
> </object>
> </child>
> <accelerator key="s" signal="activate" modifiers="GDK_CONTROL_MASK"/>
> </object>
> <packing>
> <property name="expand">False</property>
> <property name="fill">False</property>
> <property name="position">1</property>
> </packing>
> </child>
> </object>
> <packing>
> <property name="left-attach">2</property>
> <property name="top-attach">3</property>
733a889,891
> </child>
> <child>
> <placeholder/>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,58 @@
84a85,87
> from gramps.gen.utils.file import media_path_full
> from gramps.gui.widgets import Photo
>
591a595,597
>
> self.mimg = self.top.get_object('mimg')
> self.fimg = self.top.get_object('fimg')
806c812
< self.load_parent(handle, self.fname, self.fbirth, self.fbirth_label,
---
> self.load_parent(handle, self.fname, self.fimg, self.fbirth, self.fbirth_label,
816c822
< self.load_parent(handle, self.mname, self.mbirth, self.mbirth_label,
---
> self.load_parent(handle, self.mname, self.mimg, self.mbirth, self.mbirth_label,
978c984
< def load_parent(self, handle, name_obj, birth_obj, birth_label, death_obj,
---
> def load_parent(self, handle, name_obj, img_obj, birth_obj, birth_label, death_obj,
1008a1015,1018
>
> if img_obj:
> load_person_image(self, person, img_obj)
>
1283a1294,1325
> def destroy_cb(widget, data):
> """
> Callback for gtk_container_foreach
> """
> widget.destroy()
>
> def load_person_image(self, person, photo_container):
> """
> Load the primary image if it exists.
> """
> photo = Photo(True)
> photo.show()
>
> photo_container.foreach(destroy_cb, None)
> photo_container.add(photo)
>
> media_list = person.get_media_list()
> if media_list:
> media_ref = media_list[0]
> object_handle = media_ref.get_reference_handle()
> obj = self.dbstate.db.get_media_from_handle(object_handle)
> full_path = media_path_full(self.dbstate.db, obj.get_path())
> mime_type = obj.get_mime_type()
> if mime_type and mime_type.startswith("image"):
> photo.set_image(full_path, mime_type, media_ref.get_rectangle())
> photo.set_uistate(self.uistate, object_handle)
> else:
> photo.set_image(None)
> photo.set_uistate(None, None)
> else:
> photo.set_image(None)
> photo.set_uistate(None, None)

View File

@ -0,0 +1,860 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.18.3 -->
<interface>
<requires lib="gtk+" version="3.10"/>
<requires lib="grampswidgets" version="0.0"/>
<object class="GtkDialog" id="editfamily">
<property name="can_focus">False</property>
<property name="type_hint">dialog</property>
<child internal-child="vbox">
<object class="GtkBox" id="dialog-vbox17">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child internal-child="action_area">
<object class="GtkButtonBox" id="dialog-action_area17">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="layout_style">end</property>
<child>
<object class="GtkButton" id="cancel">
<property name="label" translatable="yes">_Cancel</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="can_default">True</property>
<property name="receives_default">True</property>
<property name="has_tooltip">True</property>
<property name="tooltip_markup">Abandon changes and close window</property>
<property name="tooltip_text" translatable="yes">Abandon changes and close window</property>
<property name="use_underline">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="ok">
<property name="label" translatable="yes">_OK</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="can_default">True</property>
<property name="has_default">True</property>
<property name="receives_default">True</property>
<property name="has_tooltip">True</property>
<property name="tooltip_markup">Accept changes and close window</property>
<property name="tooltip_text" translatable="yes">Accept changes and close window</property>
<property name="use_underline">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkButton" id="button119">
<property name="label" translatable="yes">_Help</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="can_default">True</property>
<property name="receives_default">True</property>
<property name="use_underline">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="pack_type">end</property>
<property name="position">2</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack_type">end</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkEventBox" id="eventboxtop">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="visible_window">False</property>
<child>
<object class="GtkBox" id="vbox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="border_width">6</property>
<property name="orientation">vertical</property>
<property name="spacing">4</property>
<child>
<object class="GtkBox" id="hbox121">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkEventBox" id="ftable_event_box">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="visible_window">False</property>
<child>
<object class="GtkGrid" id="ftable">
<property name="width_request">132</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="border_width">6</property>
<property name="row_spacing">6</property>
<property name="column_spacing">12</property>
<child>
<object class="GtkLabel" id="label577">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="margin_left">6</property>
<property name="label" translatable="yes">Name:</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label578">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="margin_left">6</property>
<property name="label" translatable="yes">Birth:</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">2</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label579">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="margin_left">6</property>
<property name="label" translatable="yes">Death:</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">3</property>
</packing>
</child>
<child>
<object class="GtkBox" id="hbox146">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkLabel" id="label589">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="label" translatable="yes">Father/partner1</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="fbutton_index">
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="relief">none</property>
<child>
<object class="GtkImage" id="image2671">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">gtk-index</property>
<child internal-child="accessible">
<object class="AtkObject" id="image2671-atkobject">
<property name="AtkObject::accessible-description" translatable="yes">Selector</property>
</object>
</child>
</object>
</child>
<child internal-child="accessible">
<object class="AtkObject" id="fbutton_index-atkobject">
<property name="AtkObject::accessible-name" translatable="yes">Father</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="padding">2</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkButton" id="fbutton_add">
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="relief">none</property>
<child>
<object class="GtkImage" id="image2697">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">list-add</property>
<child internal-child="accessible">
<object class="AtkObject" id="image2697-atkobject">
<property name="AtkObject::accessible-description" translatable="yes">Add</property>
</object>
</child>
</object>
</child>
<child internal-child="accessible">
<object class="AtkObject" id="fbutton_add-atkobject">
<property name="AtkObject::accessible-name" translatable="yes">Add</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkButton" id="fbutton_del">
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="relief">none</property>
<child>
<object class="GtkImage" id="image2724">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">list-remove</property>
<child internal-child="accessible">
<object class="AtkObject" id="image2724-atkobject">
<property name="AtkObject::accessible-description" translatable="yes">Remove</property>
</object>
</child>
</object>
</child>
<child internal-child="accessible">
<object class="AtkObject" id="fbutton_del-atkobject">
<property name="AtkObject::accessible-name" translatable="yes">Remove</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">3</property>
</packing>
</child>
<child>
<object class="GtkButton" id="fbutton_edit">
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="relief">none</property>
<child>
<object class="GtkImage" id="image2725">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">gtk-edit</property>
<child internal-child="accessible">
<object class="AtkObject" id="image2725-atkobject">
<property name="AtkObject::accessible-description" translatable="yes">Edition</property>
</object>
</child>
</object>
</child>
<child internal-child="accessible">
<object class="AtkObject" id="fbutton_edit-atkobject">
<property name="AtkObject::accessible-name" translatable="yes">Edit</property>
</object>
</child>
<accelerator key="f" signal="activate" modifiers="GDK_CONTROL_MASK"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">4</property>
</packing>
</child>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
<property name="width">2</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="fbirth">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="hexpand">True</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="top_attach">2</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="fdeath">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="hexpand">True</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="top_attach">3</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="fname">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="hexpand">True</property>
<property name="ellipsize">end</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkBox" id="fimg">
<property name="visible">True</property>
<property name="can-focus">False</property>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">0</property>
<property name="height">4</property>
</packing>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<placeholder/>
</child>
<child>
<object class="GtkEventBox" id="mtable_event_box">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="visible_window">False</property>
<child>
<object class="GtkGrid" id="mtable">
<property name="width_request">132</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="border_width">6</property>
<property name="row_spacing">6</property>
<property name="column_spacing">12</property>
<child>
<object class="GtkLabel" id="label565">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="margin_left">6</property>
<property name="label" translatable="yes">Name:</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label567">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="margin_left">6</property>
<property name="label" translatable="yes">Birth:</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">2</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label568">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="margin_left">6</property>
<property name="label" translatable="yes">Death:</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">3</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="mdeath">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="hexpand">True</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="top_attach">3</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="mbirth">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="hexpand">True</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="top_attach">2</property>
</packing>
</child>
<child>
<object class="GtkBox" id="hbox147">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkLabel" id="label574">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="label" translatable="yes">Mother/partner2</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="mbutton_index">
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="relief">none</property>
<child>
<object class="GtkImage" id="image2670">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">gtk-index</property>
<child internal-child="accessible">
<object class="AtkObject" id="image2670-atkobject">
<property name="AtkObject::accessible-description" translatable="yes">Selector</property>
</object>
</child>
</object>
</child>
<child internal-child="accessible">
<object class="AtkObject" id="mbutton_index-atkobject">
<property name="AtkObject::accessible-name" translatable="yes">Mother</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkButton" id="mbutton_add">
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="relief">none</property>
<child>
<object class="GtkImage" id="image2698">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">list-add</property>
<child internal-child="accessible">
<object class="AtkObject" id="image2698-atkobject">
<property name="AtkObject::accessible-description" translatable="yes">Add</property>
</object>
</child>
</object>
</child>
<child internal-child="accessible">
<object class="AtkObject" id="mbutton_add-atkobject">
<property name="AtkObject::accessible-name" translatable="yes">Add</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkToggleButton" id="private">
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="has_tooltip">True</property>
<property name="tooltip_markup">Indicates if the record is private</property>
<property name="tooltip_text" translatable="yes">Indicates if the record is private</property>
<property name="relief">none</property>
<child>
<object class="GtkImage" id="image2672">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">dialog-password</property>
<child internal-child="accessible">
<object class="AtkObject" id="image2672-atkobject">
<property name="AtkObject::accessible-name" translatable="yes">Privacy</property>
</object>
</child>
</object>
</child>
<accelerator key="p" signal="activate" modifiers="GDK_CONTROL_MASK"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="pack_type">end</property>
<property name="position">3</property>
</packing>
</child>
<child>
<object class="GtkButton" id="mbutton_del">
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="relief">none</property>
<child>
<object class="GtkImage" id="image2726">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">list-remove</property>
<child internal-child="accessible">
<object class="AtkObject" id="image2726-atkobject">
<property name="AtkObject::accessible-description" translatable="yes">Remove</property>
</object>
</child>
</object>
</child>
<child internal-child="accessible">
<object class="AtkObject" id="mbutton_del-atkobject">
<property name="AtkObject::accessible-name" translatable="yes">Remove</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">4</property>
</packing>
</child>
<child>
<object class="GtkButton" id="mbutton_edit">
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="relief">none</property>
<child>
<object class="GtkImage" id="image2727">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">gtk-edit</property>
<child internal-child="accessible">
<object class="AtkObject" id="image2727-atkobject">
<property name="AtkObject::accessible-description" translatable="yes">Edition</property>
</object>
</child>
</object>
</child>
<child internal-child="accessible">
<object class="AtkObject" id="mbutton_edit-atkobject">
<property name="AtkObject::accessible-name" translatable="yes">Edit</property>
</object>
</child>
<accelerator key="m" signal="activate" modifiers="GDK_CONTROL_MASK"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">5</property>
</packing>
</child>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">0</property>
<property name="width">2</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="mname">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="hexpand">True</property>
<property name="ellipsize">end</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkBox" id="mimg">
<property name="visible">True</property>
<property name="can-focus">False</property>
</object>
<packing>
<property name="left-attach">0</property>
<property name="top-attach">0</property>
<property name="height">4</property>
</packing>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkGrid" id="info">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="border_width">6</property>
<property name="row_spacing">6</property>
<property name="column_spacing">12</property>
<child>
<object class="GtkLabel" id="label542">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="label" translatable="yes">Relationship Information</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
<property name="width">4</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label229">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="margin_left">6</property>
<property name="label" translatable="yes">_ID:</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">gid</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="UndoableEntry" id="gid">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="tooltip_text" translatable="yes">A unique ID for the family</property>
<property name="hexpand">True</property>
<property name="invisible_char">●</property>
<property name="width_chars">6</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label202">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="label" translatable="yes">_Type:</property>
<property name="use_underline">True</property>
<property name="justify">center</property>
<property name="mnemonic_widget">marriage_type</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkComboBox" id="marriage_type">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="tooltip_text" translatable="yes">The relationship type, eg 'Married' or 'Unmarried'. Use Events for more details.</property>
<property name="hexpand">True</property>
<property name="has_entry">True</property>
<child internal-child="entry">
<object class="GtkEntry" id="marriage_type-entry">
<property name="can_focus">True</property>
<property name="overwrite_mode">True</property>
</object>
</child>
</object>
<packing>
<property name="left_attach">3</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="margin_left">6</property>
<property name="label" translatable="yes">_Tags:</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">tag_button</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">2</property>
</packing>
</child>
<child>
<object class="GtkBox" id="hbox1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkLabel" id="tag_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="tag_button">
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="tooltip_text" translatable="yes">Edit the tag list</property>
<child>
<placeholder/>
</child>
<accessibility>
<relation type="labelled-by" target="label1"/>
</accessibility>
<child internal-child="accessible">
<object class="AtkObject" id="tag_button-atkobject">
<property name="AtkObject::accessible-name" translatable="yes">Tags</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">2</property>
<property name="width">3</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
<action-widgets>
<action-widget response="-6">cancel</action-widget>
<action-widget response="-5">ok</action-widget>
<action-widget response="-11">button119</action-widget>
</action-widgets>
</object>
</interface>

View File

@ -0,0 +1,814 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.18.3 -->
<interface>
<requires lib="gtk+" version="3.10"/>
<requires lib="grampswidgets" version="0.0"/>
<object class="GtkDialog" id="editfamily">
<property name="can_focus">False</property>
<property name="type_hint">dialog</property>
<child internal-child="vbox">
<object class="GtkBox" id="dialog-vbox17">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child internal-child="action_area">
<object class="GtkButtonBox" id="dialog-action_area17">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="layout_style">end</property>
<child>
<object class="GtkButton" id="cancel">
<property name="label" translatable="yes">_Cancel</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="can_default">True</property>
<property name="receives_default">True</property>
<property name="has_tooltip">True</property>
<property name="tooltip_markup">Abandon changes and close window</property>
<property name="tooltip_text" translatable="yes">Abandon changes and close window</property>
<property name="use_underline">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="ok">
<property name="label" translatable="yes">_OK</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="can_default">True</property>
<property name="has_default">True</property>
<property name="receives_default">True</property>
<property name="has_tooltip">True</property>
<property name="tooltip_markup">Accept changes and close window</property>
<property name="tooltip_text" translatable="yes">Accept changes and close window</property>
<property name="use_underline">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkButton" id="button119">
<property name="label" translatable="yes">_Help</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="can_default">True</property>
<property name="receives_default">True</property>
<property name="use_underline">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="pack_type">end</property>
<property name="position">2</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="pack_type">end</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkEventBox" id="eventboxtop">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="visible_window">False</property>
<child>
<object class="GtkBox" id="vbox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="border_width">6</property>
<property name="orientation">vertical</property>
<property name="spacing">4</property>
<child>
<object class="GtkBox" id="hbox121">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkEventBox" id="ftable_event_box">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="visible_window">False</property>
<child>
<object class="GtkGrid" id="ftable">
<property name="width_request">132</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="border_width">6</property>
<property name="row_spacing">6</property>
<property name="column_spacing">12</property>
<child>
<object class="GtkLabel" id="label577">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="margin_left">6</property>
<property name="label" translatable="yes">Name:</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label578">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="margin_left">6</property>
<property name="label" translatable="yes">Birth:</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">2</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label579">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="margin_left">6</property>
<property name="label" translatable="yes">Death:</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">3</property>
</packing>
</child>
<child>
<object class="GtkBox" id="hbox146">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkLabel" id="label589">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="label" translatable="yes">Father/partner1</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="fbutton_index">
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="relief">none</property>
<child>
<object class="GtkImage" id="image2671">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">gtk-index</property>
<child internal-child="accessible">
<object class="AtkObject" id="image2671-atkobject">
<property name="AtkObject::accessible-description" translatable="yes">Selector</property>
</object>
</child>
</object>
</child>
<child internal-child="accessible">
<object class="AtkObject" id="fbutton_index-atkobject">
<property name="AtkObject::accessible-name" translatable="yes">Father</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="padding">2</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkButton" id="fbutton_add">
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="relief">none</property>
<child>
<object class="GtkImage" id="image2697">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">list-add</property>
<child internal-child="accessible">
<object class="AtkObject" id="image2697-atkobject">
<property name="AtkObject::accessible-description" translatable="yes">Add</property>
</object>
</child>
</object>
</child>
<child internal-child="accessible">
<object class="AtkObject" id="fbutton_add-atkobject">
<property name="AtkObject::accessible-name" translatable="yes">Add</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkButton" id="fbutton_del">
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="relief">none</property>
<child>
<object class="GtkImage" id="image2724">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">list-remove</property>
<child internal-child="accessible">
<object class="AtkObject" id="image2724-atkobject">
<property name="AtkObject::accessible-description" translatable="yes">Remove</property>
</object>
</child>
</object>
</child>
<child internal-child="accessible">
<object class="AtkObject" id="fbutton_del-atkobject">
<property name="AtkObject::accessible-name" translatable="yes">Remove</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">3</property>
</packing>
</child>
<child>
<object class="GtkButton" id="fbutton_edit">
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="relief">none</property>
<child>
<object class="GtkImage" id="image2725">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">gtk-edit</property>
<child internal-child="accessible">
<object class="AtkObject" id="image2725-atkobject">
<property name="AtkObject::accessible-description" translatable="yes">Edition</property>
</object>
</child>
</object>
</child>
<child internal-child="accessible">
<object class="AtkObject" id="fbutton_edit-atkobject">
<property name="AtkObject::accessible-name" translatable="yes">Edit</property>
</object>
</child>
<accelerator key="f" signal="activate" modifiers="GDK_CONTROL_MASK"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">4</property>
</packing>
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
<property name="width">2</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="fbirth">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="hexpand">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">2</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="fdeath">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="hexpand">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">3</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="fname">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="hexpand">True</property>
<property name="ellipsize">end</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">1</property>
</packing>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<placeholder/>
</child>
<child>
<object class="GtkEventBox" id="mtable_event_box">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="visible_window">False</property>
<child>
<object class="GtkGrid" id="mtable">
<property name="width_request">132</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="border_width">6</property>
<property name="row_spacing">6</property>
<property name="column_spacing">12</property>
<child>
<object class="GtkLabel" id="label565">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="margin_left">6</property>
<property name="label" translatable="yes">Name:</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label567">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="margin_left">6</property>
<property name="label" translatable="yes">Birth:</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">2</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label568">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="margin_left">6</property>
<property name="label" translatable="yes">Death:</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">3</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="mdeath">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="hexpand">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">3</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="mbirth">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="hexpand">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">2</property>
</packing>
</child>
<child>
<object class="GtkBox" id="hbox147">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkLabel" id="label574">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="label" translatable="yes">Mother/partner2</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="mbutton_index">
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="relief">none</property>
<child>
<object class="GtkImage" id="image2670">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">gtk-index</property>
<child internal-child="accessible">
<object class="AtkObject" id="image2670-atkobject">
<property name="AtkObject::accessible-description" translatable="yes">Selector</property>
</object>
</child>
</object>
</child>
<child internal-child="accessible">
<object class="AtkObject" id="mbutton_index-atkobject">
<property name="AtkObject::accessible-name" translatable="yes">Mother</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkButton" id="mbutton_add">
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="relief">none</property>
<child>
<object class="GtkImage" id="image2698">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">list-add</property>
<child internal-child="accessible">
<object class="AtkObject" id="image2698-atkobject">
<property name="AtkObject::accessible-description" translatable="yes">Add</property>
</object>
</child>
</object>
</child>
<child internal-child="accessible">
<object class="AtkObject" id="mbutton_add-atkobject">
<property name="AtkObject::accessible-name" translatable="yes">Add</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkToggleButton" id="private">
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="has_tooltip">True</property>
<property name="tooltip_markup">Indicates if the record is private</property>
<property name="tooltip_text" translatable="yes">Indicates if the record is private</property>
<property name="relief">none</property>
<child>
<object class="GtkImage" id="image2672">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">dialog-password</property>
<child internal-child="accessible">
<object class="AtkObject" id="image2672-atkobject">
<property name="AtkObject::accessible-name" translatable="yes">Privacy</property>
</object>
</child>
</object>
</child>
<accelerator key="p" signal="activate" modifiers="GDK_CONTROL_MASK"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="pack_type">end</property>
<property name="position">3</property>
</packing>
</child>
<child>
<object class="GtkButton" id="mbutton_del">
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="relief">none</property>
<child>
<object class="GtkImage" id="image2726">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">list-remove</property>
<child internal-child="accessible">
<object class="AtkObject" id="image2726-atkobject">
<property name="AtkObject::accessible-description" translatable="yes">Remove</property>
</object>
</child>
</object>
</child>
<child internal-child="accessible">
<object class="AtkObject" id="mbutton_del-atkobject">
<property name="AtkObject::accessible-name" translatable="yes">Remove</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">4</property>
</packing>
</child>
<child>
<object class="GtkButton" id="mbutton_edit">
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="relief">none</property>
<child>
<object class="GtkImage" id="image2727">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">gtk-edit</property>
<child internal-child="accessible">
<object class="AtkObject" id="image2727-atkobject">
<property name="AtkObject::accessible-description" translatable="yes">Edition</property>
</object>
</child>
</object>
</child>
<child internal-child="accessible">
<object class="AtkObject" id="mbutton_edit-atkobject">
<property name="AtkObject::accessible-name" translatable="yes">Edit</property>
</object>
</child>
<accelerator key="m" signal="activate" modifiers="GDK_CONTROL_MASK"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">5</property>
</packing>
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
<property name="width">2</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="mname">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="hexpand">True</property>
<property name="ellipsize">end</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">1</property>
</packing>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkGrid" id="info">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="border_width">6</property>
<property name="row_spacing">6</property>
<property name="column_spacing">12</property>
<child>
<object class="GtkLabel" id="label542">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="label" translatable="yes">Relationship Information</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
<property name="width">4</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label229">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="margin_left">6</property>
<property name="label" translatable="yes">_ID:</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">gid</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="UndoableEntry" id="gid">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="tooltip_text" translatable="yes">A unique ID for the family</property>
<property name="hexpand">True</property>
<property name="invisible_char">●</property>
<property name="width_chars">6</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label202">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="label" translatable="yes">_Type:</property>
<property name="use_underline">True</property>
<property name="justify">center</property>
<property name="mnemonic_widget">marriage_type</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkComboBox" id="marriage_type">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="tooltip_text" translatable="yes">The relationship type, eg 'Married' or 'Unmarried'. Use Events for more details.</property>
<property name="hexpand">True</property>
<property name="has_entry">True</property>
<child internal-child="entry">
<object class="GtkEntry" id="marriage_type-entry">
<property name="can_focus">True</property>
<property name="overwrite_mode">True</property>
</object>
</child>
</object>
<packing>
<property name="left_attach">3</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="margin_left">6</property>
<property name="label" translatable="yes">_Tags:</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">tag_button</property>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">2</property>
</packing>
</child>
<child>
<object class="GtkBox" id="hbox1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkLabel" id="tag_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hexpand">True</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="tag_button">
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="tooltip_text" translatable="yes">Edit the tag list</property>
<child>
<placeholder/>
</child>
<accessibility>
<relation type="labelled-by" target="label1"/>
</accessibility>
<child internal-child="accessible">
<object class="AtkObject" id="tag_button-atkobject">
<property name="AtkObject::accessible-name" translatable="yes">Tags</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="left_attach">1</property>
<property name="top_attach">2</property>
<property name="width">3</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
<action-widgets>
<action-widget response="-6">cancel</action-widget>
<action-widget response="-5">ok</action-widget>
<action-widget response="-11">button119</action-widget>
</action-widgets>
</object>
</interface>

View File

@ -0,0 +1,104 @@
121c121
< <property name="left_attach">0</property>
---
> <property name="left_attach">1</property>
134c134
< <property name="left_attach">0</property>
---
> <property name="left_attach">1</property>
147c147
< <property name="left_attach">0</property>
---
> <property name="left_attach">1</property>
299c299
< <property name="left_attach">0</property>
---
> <property name="left_attach">1</property>
312c312
< <property name="left_attach">1</property>
---
> <property name="left_attach">2</property>
324c324
< <property name="left_attach">1</property>
---
> <property name="left_attach">2</property>
337c337
< <property name="left_attach">1</property>
---
> <property name="left_attach">2</property>
340a341,363
> <child>
> <object class="GtkBox" id="fimg">
> <property name="visible">True</property>
> <property name="can-focus">False</property>
> </object>
> <packing>
> <property name="left-attach">0</property>
> <property name="top-attach">0</property>
> <property name="height">4</property>
> </packing>
> </child>
> <child>
> <placeholder/>
> </child>
> <child>
> <placeholder/>
> </child>
> <child>
> <placeholder/>
> </child>
> <child>
> <placeholder/>
> </child>
375c398
< <property name="left_attach">0</property>
---
> <property name="left_attach">1</property>
388c411
< <property name="left_attach">0</property>
---
> <property name="left_attach">1</property>
401c424
< <property name="left_attach">0</property>
---
> <property name="left_attach">1</property>
413c436
< <property name="left_attach">1</property>
---
> <property name="left_attach">2</property>
425c448
< <property name="left_attach">1</property>
---
> <property name="left_attach">2</property>
607c630
< <property name="left_attach">0</property>
---
> <property name="left_attach">1</property>
621c644
< <property name="left_attach">1</property>
---
> <property name="left_attach">2</property>
623a647,669
> </child>
> <child>
> <object class="GtkBox" id="mimg">
> <property name="visible">True</property>
> <property name="can-focus">False</property>
> </object>
> <packing>
> <property name="left-attach">0</property>
> <property name="top-attach">0</property>
> <property name="height">4</property>
> </packing>
> </child>
> <child>
> <placeholder/>
> </child>
> <child>
> <placeholder/>
> </child>
> <child>
> <placeholder/>
> </child>
> <child>
> <placeholder/>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,24 @@
80a81,84
> from gramps.gen.lib.date import Date, Today
> from gramps.gen.datehandler import displayer as date_displayer
> from datetime import date
>
441a446,463
>
> # BEGIN: Added by Michael J Becker 2020-09-23 02:25:48 -0500 >>> _setup_fields(self)
> self.age_label = self.top.get_object("age_label")
> self.age_label.set_label("Age: %s" % self.get_age())
>
> def get_age(self):
> """
> Get the age of the person formatted as a string, if possible.
> """
> age_precision = config.get('preferences.age-display-precision')
> thedate = Today()
> if thedate and self.get_start_date():
> return (thedate - self.get_start_date()).format(precision=age_precision)
> else:
> return ""
>
> # END: Added by Michael J Becker 2020-09-23 02:25:48 -0500 <<< get_start_date(self)
>

View File

@ -0,0 +1,823 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.18.3 -->
<interface>
<requires lib="gtk+" version="3.10"/>
<requires lib="grampswidgets" version="0.0"/>
<object class="GtkImage" id="image1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">gtk-edit</property>
<child internal-child="accessible">
<object class="AtkObject" id="image1-atkobject">
<property name="AtkObject::accessible-description" translatable="yes">Edit</property>
</object>
</child>
</object>
<object class="GtkImage" id="image2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">list-add</property>
<child internal-child="accessible">
<object class="AtkObject" id="image2-atkobject">
<property name="AtkObject::accessible-description" translatable="yes">Add</property>
</object>
</child>
</object>
<object class="GtkDialog" id="editperson">
<property name="can_focus">False</property>
<property name="has_focus">True</property>
<property name="type_hint">dialog</property>
<signal name="delete-event" handler="on_delete_event" swapped="no"/>
<child internal-child="vbox">
<object class="GtkBox" id="vbox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="vexpand">True</property>
<property name="orientation">vertical</property>
<child internal-child="action_area">
<object class="GtkButtonBox" id="hbuttonbox1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="valign">start</property>
<property name="layout_style">end</property>
<child>
<object class="GtkButton" id="button15">
<property name="label" translatable="yes">_Cancel</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="can_default">True</property>
<property name="receives_default">False</property>
<property name="tooltip_text" translatable="yes">Abandon changes and close window</property>
<property name="use_underline">True</property>
<property name="image_position">bottom</property>
<signal name="clicked" handler="destroy_passed_object" object="editperson" swapped="yes"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="ok">
<property name="label" translatable="yes">_OK</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="can_default">True</property>
<property name="receives_default">False</property>
<property name="tooltip_text" translatable="yes">Accept changes and close window</property>
<property name="use_underline">True</property>
<signal name="clicked" handler="on_apply_person_clicked" object="editperson" swapped="yes"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkButton" id="button134">
<property name="label" translatable="yes">_Help</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="can_default">True</property>
<property name="receives_default">False</property>
<property name="use_underline">True</property>
<signal name="clicked" handler="on_help_person_clicked" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">2</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="pack_type">end</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkEventBox" id="eventboxtop">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="valign">start</property>
<property name="visible_window">False</property>
<child>
<object class="GtkBox" id="vbox1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="valign">start</property>
<property name="border_width">3</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkGrid" id="table3">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="valign">start</property>
<property name="row_spacing">4</property>
<property name="column_spacing">3</property>
<child>
<object class="GtkLabel" id="label21">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="margin_left">3</property>
<property name="margin_right">3</property>
<property name="margin_top">3</property>
<property name="margin_bottom">3</property>
<property name="label" translatable="yes">_Given:</property>
<property name="use_underline">True</property>
<property name="justify">center</property>
<property name="mnemonic_widget">given_name</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="top_attach">3</property>
</packing>
</child>
<child>
<object class="UndoableEntry" id="given_name">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="can_default">True</property>
<property name="has_default">True</property>
<property name="tooltip_text" translatable="yes">The person's given names</property>
<property name="invisible_char">●</property>
<signal name="focus-out-event" handler="on_given_focus_out" swapped="no"/>
</object>
<packing>
<property name="left_attach">3</property>
<property name="top_attach">3</property>
<property name="width">4</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label444">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="label" translatable="yes">C_all:</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">call</property>
</object>
<packing>
<property name="left_attach">6</property>
<property name="top_attach">2</property>
</packing>
</child>
<child>
<object class="ValidatableMaskedEntry" id="call">
<property name="width_request">75</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="tooltip_text" translatable="yes">Part of the Given name that is the normally used name. If background is red, call name is not part of Given name and will not be printed underlined in some reports.</property>
<property name="invisible_char">●</property>
</object>
<packing>
<property name="left_attach">7</property>
<property name="top_attach">2</property>
<property name="width">2</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="titlelabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="margin_left">3</property>
<property name="margin_right">3</property>
<property name="margin_top">3</property>
<property name="margin_bottom">3</property>
<property name="label" translatable="yes">T_itle:</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">title</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="top_attach">2</property>
</packing>
</child>
<child>
<object class="UndoableEntry" id="title">
<property name="width_request">100</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="tooltip_text" translatable="yes">A title used to refer to the person, such as 'Dr.' or 'Rev.'</property>
<property name="hexpand">True</property>
<property name="invisible_char">●</property>
</object>
<packing>
<property name="left_attach">3</property>
<property name="top_attach">2</property>
</packing>
</child>
<child>
<object class="UndoableEntry" id="suffix">
<property name="width_request">75</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="tooltip_text" translatable="yes">An optional suffix to the name, such as "Jr." or "III"</property>
<property name="invisible_char">●</property>
<child internal-child="accessible">
<object class="AtkObject" id="suffix-atkobject">
<property name="AtkObject::accessible-name" translatable="yes">Suffix</property>
</object>
</child>
</object>
<packing>
<property name="left_attach">7</property>
<property name="top_attach">3</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label6">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="margin_left">3</property>
<property name="margin_right">3</property>
<property name="label" translatable="yes">_Nick:</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">nickname</property>
</object>
<packing>
<property name="left_attach">4</property>
<property name="top_attach">2</property>
</packing>
</child>
<child>
<object class="UndoableEntry" id="nickname">
<property name="width_request">100</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="tooltip_text" translatable="yes">A descriptive name given in place of or in addition to the official given name.</property>
<property name="hexpand">True</property>
<property name="invisible_char">●</property>
</object>
<packing>
<property name="left_attach">5</property>
<property name="top_attach">2</property>
</packing>
</child>
<child>
<object class="GtkFrame" id="frame5">
<property name="width_request">114</property>
<property name="height_request">114</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label_xalign">2.2351741291171123e-10</property>
<child>
<object class="GtkEventBox" id="eventbox1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkImage" id="personPix">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="valign">start</property>
</object>
</child>
</object>
</child>
<child type="label">
<object class="GtkLabel" id="label270">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Image</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
</child>
<child internal-child="accessible">
<object class="AtkObject" id="frame5-atkobject">
<property name="AtkObject::accessible-description" translatable="yes">Image</property>
</object>
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
<property name="width">2</property>
<property name="height">4</property>
</packing>
</child>
<child>
<object class="GtkComboBox" id="ntype">
<property name="width_request">100</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="tooltip_text" translatable="yes">An identification of what type of Name this is, eg. Birth Name, Married Name.</property>
<property name="has_entry">True</property>
<child internal-child="entry">
<object class="GtkEntry" id="ntype-entry">
<property name="can_focus">True</property>
<property name="overwrite_mode">True</property>
</object>
</child>
</object>
<packing>
<property name="left_attach">7</property>
<property name="top_attach">1</property>
<property name="width">2</property>
</packing>
</child>
<child>
<object class="GtkBox" id="hboxmultsurnames">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="tooltip_text" translatable="yes">Click on a table cell to edit.</property>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="left_attach">2</property>
<property name="top_attach">5</property>
<property name="width">6</property>
</packing>
</child>
<child>
<object class="GtkButton" id="multsurnamebtn">
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="tooltip_text" translatable="yes">Use Multiple Surnames
Indicate that the surname consists of different parts. Every surname has its own prefix and a possible connector to the next surname. Eg., the surname Ramón y Cajal can be stored as Ramón, which is inherited from the father, the connector y, and Cajal, which is inherited from the mother.</property>
<property name="image">image2</property>
<property name="use_underline">True</property>
<child internal-child="accessible">
<object class="AtkObject" id="multsurnamebtn-atkobject">
<property name="AtkObject::accessible-name" translatable="yes">Add</property>
</object>
</child>
<accelerator key="a" signal="activate" modifiers="GDK_CONTROL_MASK"/>
</object>
<packing>
<property name="left_attach">8</property>
<property name="top_attach">4</property>
</packing>
</child>
<child>
<object class="GtkBox" id="hbox1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkLabel" id="label3">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="margin_top">3</property>
<property name="margin_bottom">3</property>
<property name="label" translatable="yes">General</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkToggleButton" id="private">
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="tooltip_text" translatable="yes">Set person as private data</property>
<property name="halign">end</property>
<property name="relief">none</property>
<child>
<object class="GtkImage" id="image3">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="pixel_size">16</property>
<property name="icon_name">dialog-password</property>
<child internal-child="accessible">
<object class="AtkObject" id="image3-atkobject">
<property name="AtkObject::accessible-description" translatable="yes">Privacy</property>
</object>
</child>
</object>
</child>
<child internal-child="accessible">
<object class="AtkObject" id="private-atkobject">
<property name="AtkObject::accessible-name" translatable="yes">Private</property>
</object>
</child>
<accelerator key="p" signal="activate" modifiers="GDK_CONTROL_MASK"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="pack_type">end</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">6</property>
<property name="width">9</property>
</packing>
</child>
<child>
<object class="GtkBox" id="hbox4">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel" id="surnamelabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="margin_left">6</property>
<property name="margin_right">6</property>
<property name="margin_top">3</property>
<property name="margin_bottom">3</property>
<property name="label" translatable="yes">_Surname:</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">surname</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="padding">3</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="UndoableEntry" id="prefix">
<property name="width_request">70</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="tooltip_text" translatable="yes">An optional prefix for the family that is not used in sorting, such as "de" or "van".</property>
<property name="invisible_char">●</property>
<child internal-child="accessible">
<object class="AtkObject" id="prefix-atkobject">
<property name="AtkObject::accessible-name" translatable="yes">Prefix</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="UndoableEntry" id="surname">
<property name="width_request">150</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="tooltip_text" translatable="yes">Part of a person's name indicating the family to which the person belongs</property>
<property name="hexpand">True</property>
<property name="invisible_char">●</property>
<accessibility>
<relation type="labelled-by" target="surnamelabel"/>
</accessibility>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">4</property>
<property name="width">6</property>
</packing>
</child>
<child>
<object class="GtkButton" id="editnamebtn">
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="tooltip_text" translatable="yes">Go to Name Editor to add more information about this name</property>
<property name="image">image1</property>
<signal name="clicked" handler="on_edit_name_clicked" swapped="no"/>
<child internal-child="accessible">
<object class="AtkObject" id="editnamebtn-atkobject">
<property name="AtkObject::accessible-name" translatable="yes">Edit</property>
</object>
</child>
<accelerator key="e" signal="activate" modifiers="GDK_CONTROL_MASK"/>
</object>
<packing>
<property name="left_attach">8</property>
<property name="top_attach">3</property>
</packing>
</child>
<child>
<object class="GtkBox" id="hbox5">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel" id="originlabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="label" translatable="yes">O_rigin:</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">cmborigin</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkComboBox" id="cmborigin">
<property name="width_request">75</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="tooltip_text" translatable="yes">The origin of this family name for this family, eg 'Inherited' or 'Patronymic'.</property>
<property name="has_entry">True</property>
<child internal-child="entry">
<object class="GtkEntry" id="cmborigin-entry">
<property name="can_focus">True</property>
<property name="overwrite_mode">True</property>
</object>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="left_attach">6</property>
<property name="top_attach">4</property>
<property name="width">2</property>
</packing>
</child>
<child>
<object class="GtkBox" id="hbox6">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel" id="label436">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="margin_left">6</property>
<property name="margin_right">6</property>
<property name="label" translatable="yes">G_ender:</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">gender</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkComboBox" id="gender">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkCellRendererText" id="cellrenderertext2"/>
<attributes>
<attribute name="text">0</attribute>
</attributes>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label437">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="label" translatable="yes">_ID:</property>
<property name="use_underline">True</property>
<property name="justify">right</property>
<property name="mnemonic_widget">gid</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="UndoableEntry" id="gid">
<property name="width_request">75</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="tooltip_text" translatable="yes">A unique ID for the person.</property>
<property name="invisible_char">●</property>
<property name="width_chars">6</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">3</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="margin_left">6</property>
<property name="margin_right">6</property>
<property name="label" translatable="yes">_Tags:</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">tag_button</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">4</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="age_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="margin_left">6</property>
<property name="margin_right">6</property>
<property name="label" translatable="yes">Age:</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">4</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="tag_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">5</property>
</packing>
</child>
<child>
<object class="GtkButton" id="tag_button">
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="halign">end</property>
<accessibility>
<relation type="labelled-by" target="label1"/>
</accessibility>
<child internal-child="accessible">
<object class="AtkObject" id="tag_button-atkobject">
<property name="AtkObject::accessible-name" translatable="yes">Tags</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="pack_type">end</property>
<property name="position">6</property>
</packing>
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">7</property>
<property name="width">9</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="margin_top">3</property>
<property name="margin_bottom">3</property>
<property name="label" translatable="yes">Preferred Name</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
<packing>
<property name="left_attach">2</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label269">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="margin_left">3</property>
<property name="margin_right">3</property>
<property name="margin_top">3</property>
<property name="margin_bottom">3</property>
<property name="label" translatable="yes">_Type:</property>
<property name="use_underline">True</property>
<property name="justify">center</property>
<property name="mnemonic_widget">ntype</property>
</object>
<packing>
<property name="left_attach">6</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="full_name">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="margin_left">3</property>
<property name="margin_right">3</property>
<property name="margin_top">3</property>
<property name="margin_bottom">3</property>
<property name="hexpand">True</property>
<property name="use_markup">True</property>
<property name="ellipsize">end</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="top_attach">1</property>
<property name="width">4</property>
</packing>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="padding">2</property>
<property name="position">0</property>
</packing>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
<action-widgets>
<action-widget response="-6">button15</action-widget>
<action-widget response="-5">ok</action-widget>
<action-widget response="-11">button134</action-widget>
</action-widgets>
</object>
</interface>

View File

@ -0,0 +1,808 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.18.3 -->
<interface>
<requires lib="gtk+" version="3.10"/>
<requires lib="grampswidgets" version="0.0"/>
<object class="GtkImage" id="image1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">gtk-edit</property>
<child internal-child="accessible">
<object class="AtkObject" id="image1-atkobject">
<property name="AtkObject::accessible-description" translatable="yes">Edit</property>
</object>
</child>
</object>
<object class="GtkImage" id="image2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="icon_name">list-add</property>
<child internal-child="accessible">
<object class="AtkObject" id="image2-atkobject">
<property name="AtkObject::accessible-description" translatable="yes">Add</property>
</object>
</child>
</object>
<object class="GtkDialog" id="editperson">
<property name="can_focus">False</property>
<property name="has_focus">True</property>
<property name="type_hint">dialog</property>
<signal name="delete-event" handler="on_delete_event" swapped="no"/>
<child internal-child="vbox">
<object class="GtkBox" id="vbox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="vexpand">True</property>
<property name="orientation">vertical</property>
<child internal-child="action_area">
<object class="GtkButtonBox" id="hbuttonbox1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="valign">start</property>
<property name="layout_style">end</property>
<child>
<object class="GtkButton" id="button15">
<property name="label" translatable="yes">_Cancel</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="can_default">True</property>
<property name="receives_default">False</property>
<property name="tooltip_text" translatable="yes">Abandon changes and close window</property>
<property name="use_underline">True</property>
<property name="image_position">bottom</property>
<signal name="clicked" handler="destroy_passed_object" object="editperson" swapped="yes"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="ok">
<property name="label" translatable="yes">_OK</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="can_default">True</property>
<property name="receives_default">False</property>
<property name="tooltip_text" translatable="yes">Accept changes and close window</property>
<property name="use_underline">True</property>
<signal name="clicked" handler="on_apply_person_clicked" object="editperson" swapped="yes"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkButton" id="button134">
<property name="label" translatable="yes">_Help</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="can_default">True</property>
<property name="receives_default">False</property>
<property name="use_underline">True</property>
<signal name="clicked" handler="on_help_person_clicked" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">2</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="pack_type">end</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkEventBox" id="eventboxtop">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="valign">start</property>
<property name="visible_window">False</property>
<child>
<object class="GtkBox" id="vbox1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="valign">start</property>
<property name="border_width">3</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkGrid" id="table3">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="valign">start</property>
<property name="row_spacing">4</property>
<property name="column_spacing">3</property>
<child>
<object class="GtkLabel" id="label21">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="margin_left">3</property>
<property name="margin_right">3</property>
<property name="margin_top">3</property>
<property name="margin_bottom">3</property>
<property name="label" translatable="yes">_Given:</property>
<property name="use_underline">True</property>
<property name="justify">center</property>
<property name="mnemonic_widget">given_name</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="top_attach">3</property>
</packing>
</child>
<child>
<object class="UndoableEntry" id="given_name">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="can_default">True</property>
<property name="has_default">True</property>
<property name="tooltip_text" translatable="yes">The person's given names</property>
<property name="invisible_char">●</property>
<signal name="focus-out-event" handler="on_given_focus_out" swapped="no"/>
</object>
<packing>
<property name="left_attach">3</property>
<property name="top_attach">3</property>
<property name="width">4</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label444">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="label" translatable="yes">C_all:</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">call</property>
</object>
<packing>
<property name="left_attach">6</property>
<property name="top_attach">2</property>
</packing>
</child>
<child>
<object class="ValidatableMaskedEntry" id="call">
<property name="width_request">75</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="tooltip_text" translatable="yes">Part of the Given name that is the normally used name. If background is red, call name is not part of Given name and will not be printed underlined in some reports.</property>
<property name="invisible_char">●</property>
</object>
<packing>
<property name="left_attach">7</property>
<property name="top_attach">2</property>
<property name="width">2</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="titlelabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="margin_left">3</property>
<property name="margin_right">3</property>
<property name="margin_top">3</property>
<property name="margin_bottom">3</property>
<property name="label" translatable="yes">T_itle:</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">title</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="top_attach">2</property>
</packing>
</child>
<child>
<object class="UndoableEntry" id="title">
<property name="width_request">100</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="tooltip_text" translatable="yes">A title used to refer to the person, such as 'Dr.' or 'Rev.'</property>
<property name="hexpand">True</property>
<property name="invisible_char">●</property>
</object>
<packing>
<property name="left_attach">3</property>
<property name="top_attach">2</property>
</packing>
</child>
<child>
<object class="UndoableEntry" id="suffix">
<property name="width_request">75</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="tooltip_text" translatable="yes">An optional suffix to the name, such as "Jr." or "III"</property>
<property name="invisible_char">●</property>
<child internal-child="accessible">
<object class="AtkObject" id="suffix-atkobject">
<property name="AtkObject::accessible-name" translatable="yes">Suffix</property>
</object>
</child>
</object>
<packing>
<property name="left_attach">7</property>
<property name="top_attach">3</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label6">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="margin_left">3</property>
<property name="margin_right">3</property>
<property name="label" translatable="yes">_Nick:</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">nickname</property>
</object>
<packing>
<property name="left_attach">4</property>
<property name="top_attach">2</property>
</packing>
</child>
<child>
<object class="UndoableEntry" id="nickname">
<property name="width_request">100</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="tooltip_text" translatable="yes">A descriptive name given in place of or in addition to the official given name.</property>
<property name="hexpand">True</property>
<property name="invisible_char">●</property>
</object>
<packing>
<property name="left_attach">5</property>
<property name="top_attach">2</property>
</packing>
</child>
<child>
<object class="GtkFrame" id="frame5">
<property name="width_request">114</property>
<property name="height_request">114</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label_xalign">2.2351741291171123e-10</property>
<child>
<object class="GtkEventBox" id="eventbox1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkImage" id="personPix">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="valign">start</property>
</object>
</child>
</object>
</child>
<child type="label">
<object class="GtkLabel" id="label270">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Image</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
</child>
<child internal-child="accessible">
<object class="AtkObject" id="frame5-atkobject">
<property name="AtkObject::accessible-description" translatable="yes">Image</property>
</object>
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
<property name="width">2</property>
<property name="height">4</property>
</packing>
</child>
<child>
<object class="GtkComboBox" id="ntype">
<property name="width_request">100</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="tooltip_text" translatable="yes">An identification of what type of Name this is, eg. Birth Name, Married Name.</property>
<property name="has_entry">True</property>
<child internal-child="entry">
<object class="GtkEntry" id="ntype-entry">
<property name="can_focus">True</property>
<property name="overwrite_mode">True</property>
</object>
</child>
</object>
<packing>
<property name="left_attach">7</property>
<property name="top_attach">1</property>
<property name="width">2</property>
</packing>
</child>
<child>
<object class="GtkBox" id="hboxmultsurnames">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="tooltip_text" translatable="yes">Click on a table cell to edit.</property>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="left_attach">2</property>
<property name="top_attach">5</property>
<property name="width">6</property>
</packing>
</child>
<child>
<object class="GtkButton" id="multsurnamebtn">
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="tooltip_text" translatable="yes">Use Multiple Surnames
Indicate that the surname consists of different parts. Every surname has its own prefix and a possible connector to the next surname. Eg., the surname Ramón y Cajal can be stored as Ramón, which is inherited from the father, the connector y, and Cajal, which is inherited from the mother.</property>
<property name="image">image2</property>
<property name="use_underline">True</property>
<child internal-child="accessible">
<object class="AtkObject" id="multsurnamebtn-atkobject">
<property name="AtkObject::accessible-name" translatable="yes">Add</property>
</object>
</child>
<accelerator key="a" signal="activate" modifiers="GDK_CONTROL_MASK"/>
</object>
<packing>
<property name="left_attach">8</property>
<property name="top_attach">4</property>
</packing>
</child>
<child>
<object class="GtkBox" id="hbox1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkLabel" id="label3">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="margin_top">3</property>
<property name="margin_bottom">3</property>
<property name="label" translatable="yes">General</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkToggleButton" id="private">
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="tooltip_text" translatable="yes">Set person as private data</property>
<property name="halign">end</property>
<property name="relief">none</property>
<child>
<object class="GtkImage" id="image3">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="pixel_size">16</property>
<property name="icon_name">dialog-password</property>
<child internal-child="accessible">
<object class="AtkObject" id="image3-atkobject">
<property name="AtkObject::accessible-description" translatable="yes">Privacy</property>
</object>
</child>
</object>
</child>
<child internal-child="accessible">
<object class="AtkObject" id="private-atkobject">
<property name="AtkObject::accessible-name" translatable="yes">Private</property>
</object>
</child>
<accelerator key="p" signal="activate" modifiers="GDK_CONTROL_MASK"/>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="pack_type">end</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">6</property>
<property name="width">9</property>
</packing>
</child>
<child>
<object class="GtkBox" id="hbox4">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel" id="surnamelabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="margin_left">6</property>
<property name="margin_right">6</property>
<property name="margin_top">3</property>
<property name="margin_bottom">3</property>
<property name="label" translatable="yes">_Surname:</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">surname</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="padding">3</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="UndoableEntry" id="prefix">
<property name="width_request">70</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="tooltip_text" translatable="yes">An optional prefix for the family that is not used in sorting, such as "de" or "van".</property>
<property name="invisible_char">●</property>
<child internal-child="accessible">
<object class="AtkObject" id="prefix-atkobject">
<property name="AtkObject::accessible-name" translatable="yes">Prefix</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="UndoableEntry" id="surname">
<property name="width_request">150</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="tooltip_text" translatable="yes">Part of a person's name indicating the family to which the person belongs</property>
<property name="hexpand">True</property>
<property name="invisible_char">●</property>
<accessibility>
<relation type="labelled-by" target="surnamelabel"/>
</accessibility>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">4</property>
<property name="width">6</property>
</packing>
</child>
<child>
<object class="GtkButton" id="editnamebtn">
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="tooltip_text" translatable="yes">Go to Name Editor to add more information about this name</property>
<property name="image">image1</property>
<signal name="clicked" handler="on_edit_name_clicked" swapped="no"/>
<child internal-child="accessible">
<object class="AtkObject" id="editnamebtn-atkobject">
<property name="AtkObject::accessible-name" translatable="yes">Edit</property>
</object>
</child>
<accelerator key="e" signal="activate" modifiers="GDK_CONTROL_MASK"/>
</object>
<packing>
<property name="left_attach">8</property>
<property name="top_attach">3</property>
</packing>
</child>
<child>
<object class="GtkBox" id="hbox5">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel" id="originlabel">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="label" translatable="yes">O_rigin:</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">cmborigin</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkComboBox" id="cmborigin">
<property name="width_request">75</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="tooltip_text" translatable="yes">The origin of this family name for this family, eg 'Inherited' or 'Patronymic'.</property>
<property name="has_entry">True</property>
<child internal-child="entry">
<object class="GtkEntry" id="cmborigin-entry">
<property name="can_focus">True</property>
<property name="overwrite_mode">True</property>
</object>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="left_attach">6</property>
<property name="top_attach">4</property>
<property name="width">2</property>
</packing>
</child>
<child>
<object class="GtkBox" id="hbox6">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="spacing">6</property>
<child>
<object class="GtkLabel" id="label436">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="margin_left">6</property>
<property name="margin_right">6</property>
<property name="label" translatable="yes">G_ender:</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">gender</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkComboBox" id="gender">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkCellRendererText" id="cellrenderertext2"/>
<attributes>
<attribute name="text">0</attribute>
</attributes>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label437">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="label" translatable="yes">_ID:</property>
<property name="use_underline">True</property>
<property name="justify">right</property>
<property name="mnemonic_widget">gid</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="UndoableEntry" id="gid">
<property name="width_request">75</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="tooltip_text" translatable="yes">A unique ID for the person.</property>
<property name="invisible_char">●</property>
<property name="width_chars">6</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">3</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="margin_left">6</property>
<property name="margin_right">6</property>
<property name="label" translatable="yes">_Tags:</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">tag_button</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">4</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="tag_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">5</property>
</packing>
</child>
<child>
<object class="GtkButton" id="tag_button">
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="halign">end</property>
<accessibility>
<relation type="labelled-by" target="label1"/>
</accessibility>
<child internal-child="accessible">
<object class="AtkObject" id="tag_button-atkobject">
<property name="AtkObject::accessible-name" translatable="yes">Tags</property>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="pack_type">end</property>
<property name="position">6</property>
</packing>
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">7</property>
<property name="width">9</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="margin_top">3</property>
<property name="margin_bottom">3</property>
<property name="label" translatable="yes">Preferred Name</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
<packing>
<property name="left_attach">2</property>
<property name="top_attach">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label269">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="margin_left">3</property>
<property name="margin_right">3</property>
<property name="margin_top">3</property>
<property name="margin_bottom">3</property>
<property name="label" translatable="yes">_Type:</property>
<property name="use_underline">True</property>
<property name="justify">center</property>
<property name="mnemonic_widget">ntype</property>
</object>
<packing>
<property name="left_attach">6</property>
<property name="top_attach">1</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="full_name">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="halign">start</property>
<property name="margin_left">3</property>
<property name="margin_right">3</property>
<property name="margin_top">3</property>
<property name="margin_bottom">3</property>
<property name="hexpand">True</property>
<property name="use_markup">True</property>
<property name="ellipsize">end</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="top_attach">1</property>
<property name="width">4</property>
</packing>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="padding">2</property>
<property name="position">0</property>
</packing>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
<action-widgets>
<action-widget response="-6">button15</action-widget>
<action-widget response="-5">ok</action-widget>
<action-widget response="-11">button134</action-widget>
</action-widgets>
</object>
</interface>

View File

@ -0,0 +1,19 @@
655c655,670
< <property name="expand">False</property>
---
> <property name="expand">True</property>
> <property name="fill">True</property>
> <property name="position">4</property>
> </packing>
> </child>
> <child>
> <object class="GtkLabel" id="age_label">
> <property name="visible">True</property>
> <property name="can_focus">False</property>
> <property name="halign">start</property>
> <property name="margin_left">6</property>
> <property name="margin_right">6</property>
> <property name="label" translatable="yes">Age:</property>
> </object>
> <packing>
> <property name="expand">True</property>