GEPS 6: Implement place hierarchy

svn: r23444
This commit is contained in:
Nick Hall 2013-11-01 19:13:16 +00:00
parent 8e123f8695
commit d6ae8cffb4
44 changed files with 2208 additions and 1272 deletions

View File

@ -245,6 +245,8 @@ register('interface.person-sel-height', 450)
register('interface.person-sel-width', 600) register('interface.person-sel-width', 600)
register('interface.person-width', 750) register('interface.person-width', 750)
register('interface.place-height', 450) register('interface.place-height', 450)
register('interface.place-ref-height', 450)
register('interface.place-ref-width', 600)
register('interface.place-sel-height', 450) register('interface.place-sel-height', 450)
register('interface.place-sel-width', 600) register('interface.place-sel-width', 600)
register('interface.place-width', 650) register('interface.place-width', 650)

View File

@ -199,6 +199,32 @@ class DbReadCursor(BsddbBaseCursor):
self.cursor = source.db.cursor(txn) self.cursor = source.db.cursor(txn)
self.source = source self.source = source
#-------------------------------------------------------------------------
#
# DbBsddbTreeCursor
#
#-------------------------------------------------------------------------
class DbBsddbTreeCursor(BsddbBaseCursor):
def __init__(self, source, txn=None, **kwargs):
BsddbBaseCursor.__init__(self, txn=txn, **kwargs)
self.cursor = source.cursor(txn)
self.source = source
def __iter__(self):
"""
Iterator
"""
to_do = ['']
while to_do:
data = self.set(str(to_do.pop()))
_n = self.next_dup
while data:
payload = pickle.loads(data[1])
yield (payload[0], payload)
to_do.append(payload[0])
data = _n()
class DbBsddbRead(DbReadBase, Callback): class DbBsddbRead(DbReadBase, Callback):
""" """
Read class for the GRAMPS databases. Implements methods necessary to read Read class for the GRAMPS databases. Implements methods necessary to read
@ -488,6 +514,9 @@ class DbBsddbRead(DbReadBase, Callback):
def get_place_cursor(self, *args, **kwargs): def get_place_cursor(self, *args, **kwargs):
return self.get_cursor(self.place_map, *args, **kwargs) return self.get_cursor(self.place_map, *args, **kwargs)
def get_place_tree_cursor(self, *args, **kwargs):
return DbBsddbTreeCursor(self.parents, self.txn)
def get_source_cursor(self, *args, **kwargs): def get_source_cursor(self, *args, **kwargs):
return self.get_cursor(self.source_map, *args, **kwargs) return self.get_cursor(self.source_map, *args, **kwargs)

View File

@ -25,8 +25,12 @@ from __future__ import with_statement, unicode_literals
import sys import sys
import os import os
import re
from ..lib.markertype import MarkerType from ..lib.markertype import MarkerType
from ..lib.tag import Tag from ..lib.tag import Tag
from ..lib.place import Place
from ..lib.placeref import PlaceRef
from ..lib.placetype import PlaceType
from ..utils.file import create_checksum from ..utils.file import create_checksum
import time import time
import logging import logging
@ -81,11 +85,65 @@ def gramps_upgrade_17(self):
# --------------------------------- # ---------------------------------
# Modify Place # Modify Place
# --------------------------------- # ---------------------------------
# Add new tag_list field. # Convert to hierarchical structure and add new tag_list field.
locations = {}
self.max_id = 0
index = re.compile('[0-9]+')
for handle in self.place_map.keys(): for handle in self.place_map.keys():
place = self.place_map[handle]
match = index.search(place[1])
if match:
if self.max_id <= int(match.group(0)):
self.max_id = int(match.group(0))
if place[5] is not None:
locations[get_location(place[5])] = handle
for handle in list(self.place_map.keys()):
place = self.place_map[handle] place = self.place_map[handle]
new_place = list(place) new_place = list(place)
new_place = new_place[:12] + [[]] + new_place[12:]
zip_code = ''
if new_place[5]:
zip_code = new_place[5][0][6]
# find title and type
main_loc = get_location(new_place[5])
for type_num, name in enumerate(main_loc):
if name:
break
loc = list(main_loc[:])
loc[type_num] = ''
# find top parent
parent_handle = None
for n in range(7):
if loc[n]:
tup = tuple([''] * n + loc[n:])
parent_handle = locations.get(tup, None)
if parent_handle:
break
# create nodes
if parent_handle:
n -= 1
while n > type_num:
if loc[n]:
title = ', '.join([item for item in loc[n:] if item])
parent_handle = add_place(self, loc[n], n, parent_handle, title)
locations[tuple([''] * n + loc[n:])] = parent_handle
n -= 1
if parent_handle is not None:
placeref = PlaceRef()
placeref.ref = parent_handle
placeref_list = [placeref.serialize()]
else:
placeref_list = []
new_place = new_place[:5] + [placeref_list, name,
PlaceType(7-type_num).serialize(), zip_code] + \
new_place[6:12] + [[]] + new_place[12:]
new_place = tuple(new_place) new_place = tuple(new_place)
with BSDDBTxn(self.env, self.place_map) as txn: with BSDDBTxn(self.env, self.place_map) as txn:
if isinstance(handle, UNITYPE): if isinstance(handle, UNITYPE):
@ -194,6 +252,33 @@ def gramps_upgrade_17(self):
with BSDDBTxn(self.env, self.metadata) as txn: with BSDDBTxn(self.env, self.metadata) as txn:
txn.put(b'version', 17) txn.put(b'version', 17)
def get_location(loc):
# (street, locality, parish, city, county, state, country)
if loc is None:
location = ('',) * 7
else:
location = loc[0][:2] + (loc[1],) + loc[0][2:6]
return location
def add_place(self, name, type_num, parent, title):
handle = self.create_id()
place = Place()
place.handle = handle
self.max_id += 1
place.gramps_id = self.place_prefix % self.max_id
place.name = name
place.title = title
place.place_type = PlaceType(7-type_num)
if parent is not None:
placeref = PlaceRef()
placeref.ref = parent
place.set_placeref_list([placeref])
with BSDDBTxn(self.env, self.place_map) as txn:
if isinstance(handle, UNITYPE):
handle = handle.encode('utf-8')
txn.put(handle, place.serialize())
return handle
def upgrade_datamap_17(datamap): def upgrade_datamap_17(datamap):
""" """
In version 16 key value pairs are stored in source and citation. These become In version 16 key value pairs are stored in source and citation. These become

View File

@ -110,6 +110,7 @@ TAGTRANS = "tag_name"
SURNAMES = "surnames" SURNAMES = "surnames"
NAME_GROUP = "name_group" NAME_GROUP = "name_group"
META = "meta_data" META = "meta_data"
PPARENT = "place_parent"
FAMILY_TBL = "family" FAMILY_TBL = "family"
PLACES_TBL = "place" PLACES_TBL = "place"
@ -183,6 +184,15 @@ def find_idmap(key, data):
val = val.encode('utf-8') val = val.encode('utf-8')
return val return val
def find_parent(key, data):
if len(data[5]) > 0:
val = data[5][0][0]
else:
val = ''
if isinstance(val, UNITYPE):
val = val.encode('utf-8')
return val
# Secondary database key lookups for reference_map table # Secondary database key lookups for reference_map table
# reference_map data values are of the form: # reference_map data values are of the form:
# ((primary_object_class_name, primary_object_handle), # ((primary_object_class_name, primary_object_handle),
@ -374,6 +384,13 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback):
return DbBsddbAssocCursor(self.reference_map_referenced_map, return DbBsddbAssocCursor(self.reference_map_referenced_map,
self.txn) self.txn)
@catch_db_error
def get_place_parent_cursor(self):
"""
Returns a reference to a cursor over the place parents
"""
return DbBsddbAssocCursor(self.parents, self.txn)
# These are overriding the DbBsddbRead's methods of saving metadata # These are overriding the DbBsddbRead's methods of saving metadata
# because we now have txn-capable metadata table # because we now have txn-capable metadata table
@ -870,6 +887,7 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback):
("rid_trans", RIDTRANS, db.DB_HASH, 0), ("rid_trans", RIDTRANS, db.DB_HASH, 0),
("nid_trans", NIDTRANS, db.DB_HASH, 0), ("nid_trans", NIDTRANS, db.DB_HASH, 0),
("tag_trans", TAGTRANS, db.DB_HASH, 0), ("tag_trans", TAGTRANS, db.DB_HASH, 0),
("parents", PPARENT, db.DB_HASH, 0),
("reference_map_primary_map", REF_PRI, db.DB_BTREE, 0), ("reference_map_primary_map", REF_PRI, db.DB_BTREE, 0),
("reference_map_referenced_map", REF_REF, db.DB_BTREE, db.DB_DUPSORT), ("reference_map_referenced_map", REF_REF, db.DB_BTREE, db.DB_DUPSORT),
] ]
@ -887,6 +905,7 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback):
(self.family_map, self.fid_trans, find_idmap), (self.family_map, self.fid_trans, find_idmap),
(self.event_map, self.eid_trans, find_idmap), (self.event_map, self.eid_trans, find_idmap),
(self.place_map, self.pid_trans, find_idmap), (self.place_map, self.pid_trans, find_idmap),
(self.place_map, self.parents, find_parent),
(self.source_map, self.sid_trans, find_idmap), (self.source_map, self.sid_trans, find_idmap),
(self.citation_map, self.cid_trans, find_idmap), (self.citation_map, self.cid_trans, find_idmap),
(self.media_map, self.oid_trans, find_idmap), (self.media_map, self.oid_trans, find_idmap),
@ -934,6 +953,7 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback):
( self.nid_trans, NIDTRANS ), ( self.nid_trans, NIDTRANS ),
( self.cid_trans, CIDTRANS ), ( self.cid_trans, CIDTRANS ),
( self.tag_trans, TAGTRANS ), ( self.tag_trans, TAGTRANS ),
( self.parents, PPARENT ),
( self.reference_map_primary_map, REF_PRI), ( self.reference_map_primary_map, REF_PRI),
( self.reference_map_referenced_map, REF_REF), ( self.reference_map_referenced_map, REF_REF),
] ]
@ -960,6 +980,36 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback):
if callback: if callback:
callback(12) callback(12)
@catch_db_error
def find_place_child_handles(self, handle):
"""
Find all child places having the given place as the primary parent.
"""
handle = str(handle)
parent_cur = self.get_place_parent_cursor()
try:
ret = parent_cur.set(handle)
except:
ret = None
while (ret is not None):
(key, data) = ret
### FIXME: this is a dirty hack that works without no
### sensible explanation. For some reason, for a readonly
### database, secondary index returns a primary table key
### corresponding to the data, not the data.
if self.readonly:
data = self.place_map.get(data)
else:
data = pickle.loads(data)
yield data[0]
ret = parent_cur.next_dup()
parent_cur.close()
@catch_db_error @catch_db_error
def find_backlink_handles(self, handle, include_classes=None): def find_backlink_handles(self, handle, include_classes=None):
""" """
@ -1303,6 +1353,7 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback):
self.__close_metadata() self.__close_metadata()
self.name_group.close() self.name_group.close()
self.surnames.close() self.surnames.close()
self.parents.close()
self.id_trans.close() self.id_trans.close()
self.fid_trans.close() self.fid_trans.close()
self.eid_trans.close() self.eid_trans.close()

View File

@ -36,7 +36,8 @@ _ = glocale.translation.gettext
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
from .. import Rule from .. import Rule
from ....lib import Location from ....lib import PlaceType
from ....utils.location import get_locations
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
@ -46,7 +47,6 @@ from ....lib import Location
class HasPlace(Rule): class HasPlace(Rule):
"""Rule that checks for a place with a particular value""" """Rule that checks for a place with a particular value"""
labels = [ _('Name:'), labels = [ _('Name:'),
_('Street:'), _('Street:'),
_('Locality:'), _('Locality:'),
@ -62,50 +62,37 @@ class HasPlace(Rule):
category = _('General filters') category = _('General filters')
allow_regex = True allow_regex = True
TYPE2FIELD = {PlaceType.STREET: 1,
PlaceType.LOCALITY: 2,
PlaceType.CITY: 3,
PlaceType.COUNTY: 4,
PlaceType.STATE: 5,
PlaceType.COUNTRY: 6,
PlaceType.PARISH: 8}
def apply(self, db, place): def apply(self, db, place):
if not self.match_substring(0, place.get_title()): if not self.match_substring(0, place.get_title()):
return False return False
if not self.match_substring(7, place.get_code()):
return False
# If no location data was given then we're done: match # If no location data was given then we're done: match
if not any(self.list[1:]): if not any(self.list[1:7] + [self.list[8]]):
return True return True
# Something was given, so checking for location until we match for location in get_locations(db, place):
for loc in [place.main_loc] + place.alt_loc: if self.check(location):
if self.apply_location(loc):
return True return True
# Nothing matched
return False return False
def apply_location(self, loc): def check(self, location):
if not loc: """
# Allow regular expressions to match empty fields Check each location for a match.
loc = Location() """
for place_type, field in self.TYPE2FIELD.iteritems():
if not self.match_substring(1, loc.get_street()): name = location.get(place_type, '')
return False if not self.match_substring(field, name):
return False
if not self.match_substring(2, loc.get_locality()):
return False
if not self.match_substring(3, loc.get_city()):
return False
if not self.match_substring(4, loc.get_county()):
return False
if not self.match_substring(5, loc.get_state()):
return False
if not self.match_substring(6, loc.get_country()):
return False
if not self.match_substring(7, loc.get_postal_code()):
return False
if not self.match_substring(8, loc.get_parish()):
return False
# Nothing contradicted, so we're matching this location
return True return True

View File

@ -36,6 +36,7 @@ from .eventref import EventRef
from .ldsord import LdsOrd from .ldsord import LdsOrd
from .mediaref import MediaRef from .mediaref import MediaRef
from .name import Name from .name import Name
from .placeref import PlaceRef
from .reporef import RepoRef from .reporef import RepoRef
from .surname import Surname from .surname import Surname
from .url import Url from .url import Url
@ -78,6 +79,7 @@ from .markertype import MarkerType
from .nameorigintype import NameOriginType from .nameorigintype import NameOriginType
from .notetype import NoteType from .notetype import NoteType
from .styledtexttagtype import StyledTextTagType from .styledtexttagtype import StyledTextTagType
from .placetype import PlaceType
# Text # Text
from .styledtexttag import StyledTextTag from .styledtexttag import StyledTextTag

View File

@ -33,6 +33,8 @@ from __future__ import unicode_literals
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
from .primaryobj import PrimaryObject from .primaryobj import PrimaryObject
from .placeref import PlaceRef
from .placetype import PlaceType
from .citationbase import CitationBase from .citationbase import CitationBase
from .notebase import NoteBase from .notebase import NoteBase
from .mediabase import MediaBase from .mediabase import MediaBase
@ -41,8 +43,6 @@ from .tagbase import TagBase
from .location import Location from .location import Location
from .handle import Handle from .handle import Handle
_EMPTY_LOC = Location().serialize()
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
# Place class # Place class
@ -71,13 +71,19 @@ class Place(CitationBase, NoteBase, MediaBase, UrlBase, PrimaryObject):
self.long = source.long self.long = source.long
self.lat = source.lat self.lat = source.lat
self.title = source.title self.title = source.title
self.main_loc = Location(source.main_loc) self.name = source.name
self.placeref_list = list(map(PlaceRef, source.placeref_list))
self.place_type = source.place_type
self.code = source.code
self.alt_loc = list(map(Location, source.alt_loc)) self.alt_loc = list(map(Location, source.alt_loc))
else: else:
self.long = "" self.long = ""
self.lat = "" self.lat = ""
self.title = "" self.title = ""
self.main_loc = None self.name = ""
self.placeref_list = []
self.place_type = PlaceType()
self.code = ""
self.alt_loc = [] self.alt_loc = []
def serialize(self): def serialize(self):
@ -98,14 +104,10 @@ class Place(CitationBase, NoteBase, MediaBase, UrlBase, PrimaryObject):
be considered persistent. be considered persistent.
:rtype: tuple :rtype: tuple
""" """
if self.main_loc is None or self.main_loc.serialize() == _EMPTY_LOC:
main_loc = None
else:
main_loc = self.main_loc.serialize()
return (self.handle, self.gramps_id, self.title, self.long, self.lat, return (self.handle, self.gramps_id, self.title, self.long, self.lat,
main_loc, [al.serialize() for al in self.alt_loc], [pr.serialize() for pr in self.placeref_list],
self.name, self.place_type.serialize(), self.code,
[al.serialize() for al in self.alt_loc],
UrlBase.serialize(self), UrlBase.serialize(self),
MediaBase.serialize(self), MediaBase.serialize(self),
CitationBase.serialize(self), CitationBase.serialize(self),
@ -132,17 +134,15 @@ class Place(CitationBase, NoteBase, MediaBase, UrlBase, PrimaryObject):
:returns: Returns a struct containing the data of the object. :returns: Returns a struct containing the data of the object.
:rtype: dict :rtype: dict
""" """
if self.main_loc is None or self.main_loc.serialize() == _EMPTY_LOC:
main_loc = None
else:
main_loc = self.main_loc.to_struct()
return {"handle": Handle("Place", self.handle), return {"handle": Handle("Place", self.handle),
"gramps_id": self.gramps_id, "gramps_id": self.gramps_id,
"title": self.title, "title": self.title,
"long": self.long, "long": self.long,
"lat": self.lat, "lat": self.lat,
"main_loc": main_loc, "placeref_list": [pr.to_struct() for pr in self.placeref_list],
"name": self.name,
"place_type": self.place_type.to_struct(),
"code": self.code,
"alt_loc": [al.to_struct() for al in self.alt_loc], "alt_loc": [al.to_struct() for al in self.alt_loc],
"urls": UrlBase.to_struct(self), "urls": UrlBase.to_struct(self),
"media_list": MediaBase.to_struct(self), "media_list": MediaBase.to_struct(self),
@ -162,14 +162,14 @@ class Place(CitationBase, NoteBase, MediaBase, UrlBase, PrimaryObject):
:type data: tuple :type data: tuple
""" """
(self.handle, self.gramps_id, self.title, self.long, self.lat, (self.handle, self.gramps_id, self.title, self.long, self.lat,
main_loc, alt_loc, urls, media_list, citation_list, note_list, placeref_list, self.name, the_type, self.code,
alt_loc, urls, media_list, citation_list, note_list,
self.change, tag_list, self.private) = data self.change, tag_list, self.private) = data
if main_loc is None: self.place_type = PlaceType()
self.main_loc = None self.place_type.unserialize(the_type)
else:
self.main_loc = Location().unserialize(main_loc)
self.alt_loc = [Location().unserialize(al) for al in alt_loc] self.alt_loc = [Location().unserialize(al) for al in alt_loc]
self.placeref_list = [PlaceRef().unserialize(pr) for pr in placeref_list]
UrlBase.unserialize(self, urls) UrlBase.unserialize(self, urls)
MediaBase.unserialize(self, media_list) MediaBase.unserialize(self, media_list)
CitationBase.unserialize(self, citation_list) CitationBase.unserialize(self, citation_list)
@ -184,7 +184,7 @@ class Place(CitationBase, NoteBase, MediaBase, UrlBase, PrimaryObject):
:returns: Returns the list of all textual attributes of the object. :returns: Returns the list of all textual attributes of the object.
:rtype: list :rtype: list
""" """
return [self.long, self.lat, self.title, self.gramps_id] return [self.long, self.lat, self.title, self.name, self.gramps_id]
def get_text_data_child_list(self): def get_text_data_child_list(self):
""" """
@ -195,8 +195,6 @@ class Place(CitationBase, NoteBase, MediaBase, UrlBase, PrimaryObject):
""" """
ret = self.media_list + self.alt_loc + self.urls ret = self.media_list + self.alt_loc + self.urls
if self.main_loc:
ret.append(self.main_loc)
return ret return ret
def get_citation_child_list(self): def get_citation_child_list(self):
@ -226,7 +224,7 @@ class Place(CitationBase, NoteBase, MediaBase, UrlBase, PrimaryObject):
:returns: Returns the list of objects referencing primary objects. :returns: Returns the list of objects referencing primary objects.
:rtype: list :rtype: list
""" """
return self.get_citation_child_list() return self.get_citation_child_list() + self.placeref_list
def get_referenced_handles(self): def get_referenced_handles(self):
""" """
@ -253,6 +251,7 @@ class Place(CitationBase, NoteBase, MediaBase, UrlBase, PrimaryObject):
self._merge_note_list(acquisition) self._merge_note_list(acquisition)
self._merge_citation_list(acquisition) self._merge_citation_list(acquisition)
self._merge_tag_list(acquisition) self._merge_tag_list(acquisition)
self._merge_placeref_list(acquisition)
def set_title(self, title): def set_title(self, title):
""" """
@ -272,6 +271,24 @@ class Place(CitationBase, NoteBase, MediaBase, UrlBase, PrimaryObject):
""" """
return self.title return self.title
def set_name(self, name):
"""
Set the name of the Place object.
:param title: name to assign to the Place
:type title: str
"""
self.name = name
def get_name(self):
"""
Return the name of the Place object.
:returns: Returns the name of the Place
:rtype: str
"""
return self.name
def set_longitude(self, longitude): def set_longitude(self, longitude):
""" """
Set the longitude of the Place object. Set the longitude of the Place object.
@ -308,31 +325,120 @@ class Place(CitationBase, NoteBase, MediaBase, UrlBase, PrimaryObject):
""" """
return self.lat return self.lat
def get_main_location(self): def set_type(self, place_type):
""" """
Return the :class:`~gen.lib.location.Location` object representing the primary information for Set the type of the Place object.
the Place instance.
:param type: type to assign to the Place
:type type: PlaceType
"""
self.place_type.set(place_type)
def get_type(self):
"""
Return the type of the Place object.
:returns: Returns the type of the Place
:rtype: PlaceType
"""
return self.place_type
def set_code(self, code):
"""
Set the code of the Place object.
:param code: code to assign to the Place
:type code: str
"""
self.code = code
def get_code(self):
"""
Return the code of the Place object.
:returns: Returns the code of the Place
:rtype: str
"""
return self.code
def add_placeref(self, placeref):
"""
Add a place reference to the list of place references.
:param code: place reference to append to the list
:type code: PlaceRef
"""
self.placeref_list.append(placeref)
def get_placeref_list(self):
"""
Return the place reference list for the Place object.
:returns: Returns the place reference list for the Place
:rtype: list
"""
return self.placeref_list
def set_placeref_list(self, placeref_list):
"""
Set the place reference list for the Place object.
:param code: place reference list to assign to the Place
:type code: list
"""
self.placeref_list = placeref_list
def _merge_placeref_list(self, acquisition):
"""
Add the main and alternate locations of acquisition to the alternate
location list.
:param acquisition: instance to merge
:type acquisition: :class:'~gen.lib.place.Place
"""
placeref_list = self.placeref_list[:]
add_list = acquisition.placeref_list
for addendum in add_list:
for placeref in placeref_list:
if placeref.is_equal(addendum):
break
else:
self.placeref_list.append(addendum)
def _has_handle_reference(self, classname, handle):
"""
Return True if the object has reference to a given handle of given
primary object type.
If a :class:`~gen.lib.location.Location` hasn't been assigned yet, an empty one is created. :param classname: The name of the primary object class.
:type classname: str
:returns: Returns the :class:`~gen.lib.location.Location` instance representing the primary :param handle: The handle to be checked.
location information about the Place. :type handle: str
:rtype: :class:`~gen.lib.location.Location` :returns: Returns whether the object has reference to this handle of
this object type.
:rtype: bool
""" """
if not self.main_loc: if classname == 'Place':
self.main_loc = Location() for placeref in self.placeref_list:
return self.main_loc if placeref.ref == handle:
return True
return False
def set_main_location(self, location): def _replace_handle_reference(self, classname, old_handle, new_handle):
""" """
Assign the main location information about the Place to the :class:`~gen.lib.location.Location` Replace all references to old handle with those to the new handle.
object passed.
:param location: :class:`~gen.lib.location.Location` instance to assign to as the main :param classname: The name of the primary object class.
information for the Place. :type classname: str
:type location: :class:`~gen.lib.location.Location` :param old_handle: The handle to be replaced.
:type old_handle: str
:param new_handle: The handle to replace the old one with.
:type new_handle: str
""" """
self.main_loc = location if classname == 'Place':
for placeref in self.placeref_list:
if placeref.ref == old_handle:
placeref.ref = new_handle
def get_alternate_locations(self): def get_alternate_locations(self):
""" """
@ -376,40 +482,10 @@ class Place(CitationBase, NoteBase, MediaBase, UrlBase, PrimaryObject):
:type acquisition: :class:'~gen.lib.place.Place :type acquisition: :class:'~gen.lib.place.Place
""" """
altloc_list = self.alt_loc[:] altloc_list = self.alt_loc[:]
if self.main_loc and not self.main_loc.is_empty():
altloc_list.insert(0, self.main_loc)
add_list = acquisition.get_alternate_locations() add_list = acquisition.get_alternate_locations()
acq_main_loc = acquisition.get_main_location()
if acq_main_loc and not acq_main_loc.is_empty():
add_list.insert(0, acquisition.get_main_location())
for addendum in add_list: for addendum in add_list:
for altloc in altloc_list: for altloc in altloc_list:
if altloc.is_equal(addendum): if altloc.is_equal(addendum):
break break
else: else:
self.alt_loc.append(addendum) self.alt_loc.append(addendum)
def get_display_info(self):
"""
Get the display information associated with the object.
This includes the information that is used for display and for sorting.
Returns a list consisting of 13 strings. These are:
Place Title, Place ID, Main Location Parish, Main Location County,
Main Location City, Main Location State/Province,
Main Location Country, upper case Place Title, upper case Parish,
upper case city, upper case county, upper case state,
upper case country.
"""
if self.main_loc:
return [self.title, self.gramps_id, self.main_loc.parish,
self.main_loc.city, self.main_loc.county,
self.main_loc.state, self.main_loc.country,
self.title.upper(), self.main_loc.parish.upper(),
self.main_loc.city.upper(), self.main_loc.county.upper(),
self.main_loc.state.upper(), self.main_loc.country.upper()]
else:
return [self.title, self.gramps_id, '', '', '', '', '',
self.title.upper(), '', '', '', '', '']

176
gramps/gen/lib/placeref.py Normal file
View File

@ -0,0 +1,176 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2000-2007 Donald N. Allingham
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# $Id$
"""
Place Reference class for Gramps
"""
#-------------------------------------------------------------------------
#
# GRAMPS modules
#
#-------------------------------------------------------------------------
from .secondaryobj import SecondaryObject
from .refbase import RefBase
from .datebase import DateBase
from .const import IDENTICAL, EQUAL, DIFFERENT
#-------------------------------------------------------------------------
#
# Place References
#
#-------------------------------------------------------------------------
class PlaceRef(RefBase, DateBase, SecondaryObject):
"""
Place reference class.
This class is for keeping information about how places link to other places
in the place hierarchy.
"""
def __init__(self, source=None):
"""
Create a new PlaceRef instance, copying from the source if present.
"""
RefBase.__init__(self, source)
DateBase.__init__(self, source)
def serialize(self):
"""
Convert the object to a serialized tuple of data.
"""
return (
RefBase.serialize(self),
DateBase.serialize(self)
)
def to_struct(self):
"""
Convert the data held in this object to a structure (eg,
struct) that represents all the data elements.
This method is used to recursively convert the object into a
self-documenting form that can easily be used for various
purposes, including diffs and queries.
These structures may be primitive Python types (string,
integer, boolean, etc.) or complex Python types (lists,
tuples, or dicts). If the return type is a dict, then the keys
of the dict match the fieldname of the object. If the return
struct (or value of a dict key) is a list, then it is a list
of structs. Otherwise, the struct is just the value of the
attribute.
:returns: Returns a struct containing the data of the object.
:rtype: dict
"""
return {
"ref": RefBase.to_struct(self),
"date": DateBase.to_struct(self)
}
def unserialize(self, data):
"""
Convert a serialized tuple of data to an object.
"""
(ref, date) = data
RefBase.unserialize(self, ref)
DateBase.unserialize(self, date)
return self
def get_text_data_list(self):
"""
Return the list of all textual attributes of the object.
:returns: Returns the list of all textual attributes of the object.
:rtype: list
"""
return []
def get_text_data_child_list(self):
"""
Return the list of child objects that may carry textual data.
:returns: Returns the list of child objects that may carry textual data.
:rtype: list
"""
return []
def get_citation_child_list(self):
"""
Return the list of child secondary objects that may refer citations.
:returns: Returns the list of child secondary child objects that may
refer citations.
:rtype: list
"""
return []
def get_note_child_list(self):
"""
Return the list of child secondary objects that may refer notes.
:returns: Returns the list of child secondary child objects that may
refer notes.
:rtype: list
"""
return []
def get_referenced_handles(self):
"""
Return the list of (classname, handle) tuples for all directly
referenced primary objects.
:returns: Returns the list of (classname, handle) tuples for referenced
objects.
:rtype: list
"""
return [('Place', self.ref)]
def get_handle_referents(self):
"""
Return the list of child objects which may, directly or through their
children, reference primary objects..
:returns: Returns the list of objects referencing primary objects.
:rtype: list
"""
return []
def is_equivalent(self, other):
"""
Return if this eventref is equivalent, that is agrees in handle and
role, to other.
:param other: The eventref to compare this one to.
:rtype other: EventRef
:returns: Constant indicating degree of equivalence.
:rtype: int
"""
if self.ref != other.ref or self.date != other.date:
return DIFFERENT
else:
if self.is_equal(other):
return IDENTICAL
else:
return EQUAL

View File

@ -0,0 +1,68 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2000-2007 Donald N. Allingham
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# $Id$
"""
Provide the different place types.
"""
#------------------------------------------------------------------------
#
# Python modules
#
#------------------------------------------------------------------------
from ..const import GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext
#-------------------------------------------------------------------------
#
# GRAMPS modules
#
#-------------------------------------------------------------------------
from .grampstype import GrampsType
class PlaceType(GrampsType):
UNKNOWN = -1
CUSTOM = 0
COUNTRY = 1
STATE = 2
COUNTY = 3
CITY = 4
PARISH = 5
LOCALITY = 6
STREET = 7
_CUSTOM = CUSTOM
_DEFAULT = COUNTRY
_DATAMAP = [
(UNKNOWN, _("Unknown"), "Unknown"),
(CUSTOM, _("Custom"), "Custom"),
(COUNTRY, _("Country"), "Country"),
(STATE, _("State"), "State"),
(COUNTY, _("County"), "County"),
(CITY, _("City"), "City"),
(PARISH, _("Parish"), "Parish"),
(LOCALITY, _("Locality"), "Locality"),
(STREET, _("Street"), "Street"),
]
def __init__(self, value=None):
GrampsType.__init__(self, value)

View File

@ -30,7 +30,7 @@ Provide merge capabilities for places.
# Gramps modules # Gramps modules
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
from ..lib import Person, Family, Event from ..lib import Person, Family, Event, Place
from ..db import DbTxn from ..db import DbTxn
from ..const import GRAMPS_LOCALE as glocale from ..const import GRAMPS_LOCALE as glocale
_ = glocale.translation.sgettext _ = glocale.translation.sgettext
@ -81,6 +81,12 @@ class MergePlaceQuery(object):
event.replace_handle_reference('Place', old_handle, event.replace_handle_reference('Place', old_handle,
new_handle) new_handle)
self.database.commit_event(event, trans) self.database.commit_event(event, trans)
elif class_name == Place.__name__:
place = self.database.get_place_from_handle(handle)
assert(place.has_handle_reference('Place', old_handle))
place.replace_handle_reference('Place', old_handle,
new_handle)
self.database.commit_place(place, trans)
else: else:
raise MergeError("Encounter an object of type %s that has " raise MergeError("Encounter an object of type %s that has "
"a place reference." % class_name) "a place reference." % class_name)

View File

@ -980,8 +980,11 @@ def sanitize_place(db, place):
new_place.set_change_time(place.get_change_time()) new_place.set_change_time(place.get_change_time())
new_place.set_longitude(place.get_longitude()) new_place.set_longitude(place.get_longitude())
new_place.set_latitude(place.get_latitude()) new_place.set_latitude(place.get_latitude())
new_place.set_main_location(place.get_main_location())
new_place.set_alternate_locations(place.get_alternate_locations()) new_place.set_alternate_locations(place.get_alternate_locations())
new_place.set_name(place.get_name())
new_place.set_type(place.get_type())
new_place.set_code(place.get_code())
new_place.set_placeref_list(place.get_placeref_list())
copy_citation_ref_list(db, place, new_place) copy_citation_ref_list(db, place, new_place)
copy_notes(db, place, new_place) copy_notes(db, place, new_place)

View File

@ -0,0 +1,80 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# $Id$
"""
Location utility functions
"""
#-------------------------------------------------------------------------
#
# get_location_list
#
#-------------------------------------------------------------------------
def get_location_list(db, place):
"""
Return a list of place names for display.
"""
lines = [place.name]
while len(place.get_placeref_list()) > 0:
place = db.get_place_from_handle(place.get_placeref_list()[0].ref)
lines.append(place.name)
return lines
#-------------------------------------------------------------------------
#
# get_main_location
#
#-------------------------------------------------------------------------
def get_main_location(db, place):
"""
Find all places in the hierarchy above the given place, and return the
result as a dictionary of place types and names.
"""
items = {int(place.get_type()): place.name}
while len(place.get_placeref_list()) > 0:
place = db.get_place_from_handle(place.get_placeref_list()[0].ref)
items[int(place.get_type())] = place.name
return items
#-------------------------------------------------------------------------
#
# get_locations
#
#-------------------------------------------------------------------------
def get_locations(db, place):
"""
Determine each possible route up the place hierarchy, and return a list
containing dictionaries of place types and names.
"""
locations = []
todo = [(place, [(int(place.get_type()), place.get_name())])]
while len(todo):
place, tree = todo.pop()
if len(place.get_placeref_list()):
for parent in place.get_placeref_list():
parent_place = db.get_place_from_handle(parent.ref)
parent_tree = tree + [(int(parent_place.get_type()),
parent_place.get_name())]
todo.append((parent_place, parent_tree))
else:
locations.append(dict(tree))
return locations

View File

@ -121,6 +121,7 @@ def map2class(target):
'mediaobj': ClipMediaObj, 'mediaobj': ClipMediaObj,
'mediaref': ClipMediaRef, 'mediaref': ClipMediaRef,
'place-link': ClipPlace, 'place-link': ClipPlace,
'placeref': ClipPlaceRef,
'note-link': ClipNote, 'note-link': ClipNote,
} }
return d[target] if target in d else None return d[target] if target in d else None
@ -568,6 +569,24 @@ class ClipEventRef(ClipObjWrapper):
self._title = base.gramps_id self._title = base.gramps_id
self._value = str(base.get_type()) self._value = str(base.get_type())
class ClipPlaceRef(ClipObjWrapper):
DROP_TARGETS = [DdTargets.PLACEREF]
DRAG_TARGET = DdTargets.PLACEREF
ICON = LINK_PIC
def __init__(self, dbstate, obj):
super(ClipPlaceRef, self).__init__(dbstate, obj)
self._type = _("Place ref")
self.refresh()
def refresh(self):
if self._obj:
base = self._db.get_place_from_handle(self._obj.ref)
if base:
self._title = base.gramps_id
self._value = str(base.get_name())
class ClipName(ClipObjWrapper): class ClipName(ClipObjWrapper):
DROP_TARGETS = [DdTargets.NAME] DROP_TARGETS = [DdTargets.NAME]
@ -1082,6 +1101,7 @@ class ClipboardListView(object):
self.register_wrapper_class(ClipEvent) self.register_wrapper_class(ClipEvent)
self.register_wrapper_class(ClipPlace) self.register_wrapper_class(ClipPlace)
self.register_wrapper_class(ClipEventRef) self.register_wrapper_class(ClipEventRef)
self.register_wrapper_class(ClipPlaceRef)
self.register_wrapper_class(ClipRepoRef) self.register_wrapper_class(ClipRepoRef)
self.register_wrapper_class(ClipFamilyEvent) self.register_wrapper_class(ClipFamilyEvent)
self.register_wrapper_class(ClipUrl) self.register_wrapper_class(ClipUrl)

View File

@ -142,6 +142,7 @@ class _DdTargets(object):
self.NAME = _DdType(self, 'name') self.NAME = _DdType(self, 'name')
self.NOTE_LINK = _DdType(self, 'note-link') self.NOTE_LINK = _DdType(self, 'note-link')
self.PLACE_LINK = _DdType(self, 'place-link') self.PLACE_LINK = _DdType(self, 'place-link')
self.PLACEREF = _DdType(self, 'placeref')
self.REPO_LINK = _DdType(self, 'repo-link') self.REPO_LINK = _DdType(self, 'repo-link')
self.REPOREF = _DdType(self, 'reporef') self.REPOREF = _DdType(self, 'reporef')
self.PERSON_LINK = _DdType(self, 'person-link') self.PERSON_LINK = _DdType(self, 'person-link')
@ -172,6 +173,7 @@ class _DdTargets(object):
self.NAME, self.NAME,
self.NOTE_LINK, self.NOTE_LINK,
self.PLACE_LINK, self.PLACE_LINK,
self.PLACEREF,
self.PERSON_LINK, self.PERSON_LINK,
self.FAMILY_LINK, self.FAMILY_LINK,
self.LINK_LIST, self.LINK_LIST,

View File

@ -39,6 +39,7 @@ from .editnote import EditNote, DeleteNoteQuery
from .editperson import EditPerson from .editperson import EditPerson
from .editpersonref import EditPersonRef from .editpersonref import EditPersonRef
from .editplace import EditPlace, DeletePlaceQuery from .editplace import EditPlace, DeletePlaceQuery
from .editplaceref import EditPlaceRef
from .editrepository import EditRepository, DeleteRepositoryQuery from .editrepository import EditRepository, DeleteRepositoryQuery
from .editreporef import EditRepoRef from .editreporef import EditRepoRef
from .editsource import EditSource, DeleteSrcQuery from .editsource import EditSource, DeleteSrcQuery

View File

@ -56,6 +56,7 @@ from .personeventembedlist import PersonEventEmbedList
from .personrefembedlist import PersonRefEmbedList from .personrefembedlist import PersonRefEmbedList
from .personbackreflist import PersonBackRefList from .personbackreflist import PersonBackRefList
from .placebackreflist import PlaceBackRefList from .placebackreflist import PlaceBackRefList
from .placerefembedlist import PlaceRefEmbedList
from .repoembedlist import RepoEmbedList from .repoembedlist import RepoEmbedList
from .surnametab import SurnameTab from .surnametab import SurnameTab
from .sourcebackreflist import SourceBackRefList from .sourcebackreflist import SourceBackRefList

View File

@ -0,0 +1,101 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2000-2006 Donald N. Allingham
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# $Id$
#-------------------------------------------------------------------------
#
# Python classes
#
#-------------------------------------------------------------------------
from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext
from gi.repository import GObject
#-------------------------------------------------------------------------
#
# GRAMPS classes
#
#-------------------------------------------------------------------------
from gramps.gen.lib import PlaceRef
from gramps.gen.errors import WindowActiveError
from ...ddtargets import DdTargets
from .placerefmodel import PlaceRefModel
from .embeddedlist import EmbeddedList, TEXT_COL
#-------------------------------------------------------------------------
#
#
#
#-------------------------------------------------------------------------
class PlaceRefEmbedList(EmbeddedList):
_HANDLE_COL = 4
#_DND_TYPE = DdTargets.PLACEREF
#index = column in model. Value =
# (name, sortcol in model, width, markup/text, weigth_col
_column_names = [
(_('ID'), 0, 75, TEXT_COL, -1, None),
(_('Name'), 1, 250, TEXT_COL, -1, None),
(_('Type'), 2, 100, TEXT_COL, -1, None),
(_('Date'), 3, 150, TEXT_COL, -1, None),
]
def __init__(self, dbstate, uistate, track, data, handle):
self.data = data
self.handle = handle
EmbeddedList.__init__(self, dbstate, uistate, track,
_('Parents'), PlaceRefModel,
move_buttons=True)
def get_data(self):
return self.data
def column_order(self):
return ((1, 0), (1, 1), (1, 2), (1, 3))
def add_button_clicked(self, obj):
placeref = PlaceRef()
try:
from .. import EditPlaceRef
EditPlaceRef(self.dbstate, self.uistate, self.track,
placeref, self.handle, self.add_callback)
except WindowActiveError:
pass
def add_callback(self, name):
data = self.get_data()
data.append(name)
self.rebuild()
GObject.idle_add(self.tree.scroll_to_cell, len(data) - 1)
def edit_button_clicked(self, obj):
placeref = self.get_selected()
if placeref:
try:
from .. import EditPlaceRef
EditPlaceRef(self.dbstate, self.uistate, self.track,
placeref, self.handle, self.edit_callback)
except WindowActiveError:
pass
def edit_callback(self, name):
self.rebuild()

View File

@ -0,0 +1,53 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2000-2006 Donald N. Allingham
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# $Id$
#-------------------------------------------------------------------------
#
# GTK libraries
#
#-------------------------------------------------------------------------
from gi.repository import Gtk
#-------------------------------------------------------------------------
#
# Gramps classes
#
#-------------------------------------------------------------------------
from gramps.gen.datehandler import displayer
#-------------------------------------------------------------------------
#
# PlaceRefModel
#
#-------------------------------------------------------------------------
class PlaceRefModel(Gtk.ListStore):
def __init__(self, obj_list, db):
Gtk.ListStore.__init__(self, str, str, str, str, object)
self.db = db
for obj in obj_list:
place = self.db.get_place_from_handle(obj.ref)
self.append(row=[place.get_gramps_id(),
place.get_name(),
str(place.get_type()),
displayer.display(obj.date),
obj, ])

View File

@ -50,57 +50,15 @@ from gi.repository import Gtk
from gramps.gen.lib import NoteType, Place from gramps.gen.lib import NoteType, Place
from gramps.gen.db import DbTxn from gramps.gen.db import DbTxn
from .editprimary import EditPrimary from .editprimary import EditPrimary
from .displaytabs import (GrampsTab, LocationEmbedList, CitationEmbedList, from .displaytabs import (PlaceRefEmbedList, LocationEmbedList, CitationEmbedList,
GalleryTab, NoteTab, WebEmbedList, PlaceBackRefList) GalleryTab, NoteTab, WebEmbedList, PlaceBackRefList)
from ..widgets import MonitoredEntry, PrivacyButton, MonitoredTagList from ..widgets import (MonitoredEntry, PrivacyButton, MonitoredTagList,
MonitoredDataType)
from gramps.gen.errors import ValidationError from gramps.gen.errors import ValidationError
from gramps.gen.utils.place import conv_lat_lon from gramps.gen.utils.place import conv_lat_lon
from ..dialog import ErrorDialog from ..dialog import ErrorDialog
from ..glade import Glade from ..glade import Glade
#-------------------------------------------------------------------------
#
# Classes
#
#-------------------------------------------------------------------------
class MainLocTab(GrampsTab):
"""
This class provides the tabpage of the main location tab
"""
def __init__(self, dbstate, uistate, track, name, widget):
"""
@param dbstate: The database state. Contains a reference to
the database, along with other state information. The GrampsTab
uses this to access the database and to pass to and created
child windows (such as edit dialogs).
@type dbstate: DbState
@param uistate: The UI state. Used primarily to pass to any created
subwindows.
@type uistate: DisplayState
@param track: The window tracking mechanism used to manage windows.
This is only used to pass to generted child windows.
@type track: list
@param name: Notebook label name
@type name: str/unicode
@param widget: widget to be shown in the tab
@type widge: gtk widget
"""
GrampsTab.__init__(self, dbstate, uistate, track, name)
eventbox = Gtk.EventBox()
eventbox.add(widget)
self.pack_start(eventbox, True, True, 0)
self._set_label(show_image=False)
eventbox.connect('key_press_event', self.key_pressed)
self.show_all()
def is_empty(self):
"""
Override base class
"""
return False
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
# EditPlace # EditPlace
@ -121,17 +79,7 @@ class EditPlace(EditPrimary):
self.height_key = 'interface.place-height' self.height_key = 'interface.place-height'
self.top = Glade() self.top = Glade()
self.set_window(self.top.toplevel, None, self.get_menu_title())
self.set_window(self.top.toplevel, None,
self.get_menu_title())
tblmloc = self.top.get_object('table19')
notebook = self.top.get_object('notebook3')
#recreate start page as GrampsTab
notebook.remove_page(0)
self.mloc = MainLocTab(self.dbstate, self.uistate, self.track,
_('_Location'), tblmloc)
self.track_ref_for_deletion("mloc")
def get_menu_title(self): def get_menu_title(self):
if self.obj and self.obj.get_handle(): if self.obj and self.obj.get_handle():
@ -155,23 +103,14 @@ class EditPlace(EditPrimary):
self._add_db_signal('place-delete', self.check_for_close) self._add_db_signal('place-delete', self.check_for_close)
def _setup_fields(self): def _setup_fields(self):
mloc = self.obj.get_main_location()
self.title = MonitoredEntry(self.top.get_object("place_title"), self.title = MonitoredEntry(self.top.get_object("place_title"),
self.obj.set_title, self.obj.get_title, self.obj.set_title, self.obj.get_title,
self.db.readonly) self.db.readonly)
self.street = MonitoredEntry(self.top.get_object("street"), self.name = MonitoredEntry(self.top.get_object("name_entry"),
mloc.set_street, mloc.get_street, self.obj.set_name, self.obj.get_name,
self.db.readonly) self.db.readonly)
self.locality = MonitoredEntry(self.top.get_object("locality"),
mloc.set_locality, mloc.get_locality,
self.db.readonly)
self.city = MonitoredEntry(self.top.get_object("city"),
mloc.set_city, mloc.get_city,
self.db.readonly)
self.gid = MonitoredEntry(self.top.get_object("gid"), self.gid = MonitoredEntry(self.top.get_object("gid"),
self.obj.set_gramps_id, self.obj.set_gramps_id,
@ -188,29 +127,14 @@ class EditPlace(EditPrimary):
self.privacy = PrivacyButton(self.top.get_object("private"), self.obj, self.privacy = PrivacyButton(self.top.get_object("private"), self.obj,
self.db.readonly) self.db.readonly)
self.parish = MonitoredEntry(self.top.get_object("parish"), self.place_type = MonitoredDataType(self.top.get_object("place_type"),
mloc.set_parish, mloc.get_parish, self.obj.set_type,
self.db.readonly) self.obj.get_type)
self.county = MonitoredEntry(self.top.get_object("county"),
mloc.set_county, mloc.get_county,
self.db.readonly)
self.state = MonitoredEntry(self.top.get_object("state"),
mloc.set_state, mloc.get_state,
self.db.readonly)
self.phone = MonitoredEntry(self.top.get_object("phone"), self.code = MonitoredEntry(
mloc.set_phone, mloc.get_phone, self.top.get_object("code_entry"),
self.db.readonly) self.obj.set_code, self.obj.get_code,
self.db.readonly)
self.postal = MonitoredEntry(self.top.get_object("postal"),
mloc.set_postal_code,
mloc.get_postal_code, self.db.readonly)
self.country = MonitoredEntry(self.top.get_object("country"),
mloc.set_country, mloc.get_country,
self.db.readonly)
self.longitude = MonitoredEntry( self.longitude = MonitoredEntry(
self.top.get_object("lon_entry"), self.top.get_object("lon_entry"),
@ -247,8 +171,14 @@ class EditPlace(EditPrimary):
""" """
notebook = self.top.get_object('notebook3') notebook = self.top.get_object('notebook3')
self._add_tab(notebook, self.mloc) self.placeref_list = PlaceRefEmbedList(self.dbstate,
self.uistate,
self.track,
self.obj.get_placeref_list(),
self.obj.handle)
self._add_tab(notebook, self.placeref_list)
self.track_ref_for_deletion("placeref_list")
self.loc_list = LocationEmbedList(self.dbstate, self.loc_list = LocationEmbedList(self.dbstate,
self.uistate, self.uistate,
self.track, self.track,
@ -306,6 +236,20 @@ class EditPlace(EditPrimary):
self.ok_button.set_sensitive(True) self.ok_button.set_sensitive(True)
return return
if self.obj.get_title().strip() == '':
msg1 = _("Cannot save location. Title not entered.")
msg2 = _("You must enter a title before saving.'")
ErrorDialog(msg1, msg2)
self.ok_button.set_sensitive(True)
return
if self.obj.get_name().strip() == '':
msg1 = _("Cannot save location. Name not entered.")
msg2 = _("You must enter a name before saving.'")
ErrorDialog(msg1, msg2)
self.ok_button.set_sensitive(True)
return
(uses_dupe_id, id) = self._uses_duplicate_id() (uses_dupe_id, id) = self._uses_duplicate_id()
if uses_dupe_id: if uses_dupe_id:
prim_object = self.get_from_gramps_id(id) prim_object = self.get_from_gramps_id(id)

View File

@ -0,0 +1,100 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# Copyright (C) 2000-2006 Donald N. Allingham
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# $Id$
#-------------------------------------------------------------------------
#
# Gramps modules
#
#-------------------------------------------------------------------------
from .editsecondary import EditSecondary
from ..glade import Glade
from ..widgets import MonitoredDate
from ..selectors import SelectorFactory
from ..dialog import ErrorDialog
from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext
SelectPlace = SelectorFactory('Place')
#-------------------------------------------------------------------------
#
# EditPlaceRef class
#
#-------------------------------------------------------------------------
class EditPlaceRef(EditSecondary):
def __init__(self, dbstate, uistate, track, placeref, handle, callback):
self.handle = handle
EditSecondary.__init__(self, dbstate, uistate, track,
placeref, callback)
def _local_init(self):
self.width_key = 'interface.place-ref-width'
self.height_key = 'interface.place-ref-height'
self.top = Glade()
self.set_window(self.top.toplevel, None, _('Place Reference Editor'))
def _setup_fields(self):
self.date_field = MonitoredDate(self.top.get_object("date_entry"),
self.top.get_object("date_stat"),
self.obj.get_date_object(),
self.uistate, self.track,
self.db.readonly)
self.parent = self.top.get_object('place_label')
if self.obj.ref is not None:
place = self.db.get_place_from_handle(self.obj.ref)
self.parent.set_text(place.get_name())
else:
self.parent.set_text(_('Top level place'))
button = self.top.get_object('place_button')
button.connect('clicked', self.select_parent)
def get_skip_list(self, handle):
todo = [handle]
skip = [handle]
while todo:
handle = todo.pop()
for child in self.dbstate.db.find_place_child_handles(handle):
todo.append(child)
skip.append(child)
return skip
def select_parent(self, button):
skip = self.get_skip_list(self.handle)
sel = SelectPlace(self.dbstate, self.uistate, self.track, skip=skip)
parent = sel.run()
if parent:
self.parent.set_text(parent.get_name())
self.obj.ref = parent.get_handle()
def _connect_signals(self):
self.define_cancel_button(self.top.get_object('cancel_button'))
self.define_ok_button(self.top.get_object('ok_button'), self.save)
self.define_help_button(self.top.get_object('help_button'))
def save(self, *obj):
if self.callback:
self.callback(self.obj)
self.close()

View File

@ -16,12 +16,10 @@
<child> <child>
<object class="GtkButton" id="cancel"> <object class="GtkButton" id="cancel">
<property name="label">gtk-cancel</property> <property name="label">gtk-cancel</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="can_default">True</property> <property name="can_default">True</property>
<property name="receives_default">True</property> <property name="receives_default">True</property>
<property name="use_action_appearance">False</property>
<property name="use_stock">True</property> <property name="use_stock">True</property>
</object> </object>
<packing> <packing>
@ -33,13 +31,11 @@
<child> <child>
<object class="GtkButton" id="ok"> <object class="GtkButton" id="ok">
<property name="label">gtk-ok</property> <property name="label">gtk-ok</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="can_default">True</property> <property name="can_default">True</property>
<property name="has_default">True</property> <property name="has_default">True</property>
<property name="receives_default">True</property> <property name="receives_default">True</property>
<property name="use_action_appearance">False</property>
<property name="use_stock">True</property> <property name="use_stock">True</property>
</object> </object>
<packing> <packing>
@ -51,12 +47,10 @@
<child> <child>
<object class="GtkButton" id="help"> <object class="GtkButton" id="help">
<property name="label">gtk-help</property> <property name="label">gtk-help</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="can_default">True</property> <property name="can_default">True</property>
<property name="receives_default">True</property> <property name="receives_default">True</property>
<property name="use_action_appearance">False</property>
<property name="use_stock">True</property> <property name="use_stock">True</property>
</object> </object>
<packing> <packing>
@ -82,23 +76,26 @@
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="border_width">12</property> <property name="border_width">12</property>
<property name="n_rows">3</property> <property name="n_rows">4</property>
<property name="n_columns">5</property> <property name="n_columns">5</property>
<property name="column_spacing">6</property> <property name="column_spacing">6</property>
<property name="row_spacing">4</property> <property name="row_spacing">4</property>
<child>
<placeholder/>
</child>
<child> <child>
<object class="GtkLabel" id="label244"> <object class="GtkLabel" id="label244">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="xalign">0</property> <property name="xalign">0</property>
<property name="label" translatable="yes">_Place Name:</property> <property name="label" translatable="yes">_Place Title:</property>
<property name="use_underline">True</property> <property name="use_underline">True</property>
<property name="justify">center</property> <property name="justify">center</property>
<property name="mnemonic_widget">place_title</property> <property name="mnemonic_widget">place_title</property>
</object> </object>
<packing> <packing>
<property name="x_options">GTK_FILL</property> <property name="x_options">GTK_FILL</property>
<property name="y_options"></property> <property name="y_options"/>
</packing> </packing>
</child> </child>
<child> <child>
@ -112,10 +109,10 @@
<property name="mnemonic_widget">lat_entry</property> <property name="mnemonic_widget">lat_entry</property>
</object> </object>
<packing> <packing>
<property name="top_attach">1</property> <property name="top_attach">2</property>
<property name="bottom_attach">2</property> <property name="bottom_attach">3</property>
<property name="x_options">GTK_FILL</property> <property name="x_options">GTK_FILL</property>
<property name="y_options"></property> <property name="y_options"/>
</packing> </packing>
</child> </child>
<child> <child>
@ -131,23 +128,23 @@
<packing> <packing>
<property name="left_attach">2</property> <property name="left_attach">2</property>
<property name="right_attach">3</property> <property name="right_attach">3</property>
<property name="top_attach">1</property> <property name="top_attach">2</property>
<property name="bottom_attach">2</property> <property name="bottom_attach">3</property>
<property name="x_options">GTK_FILL</property> <property name="x_options">GTK_FILL</property>
<property name="y_options"></property> <property name="y_options"/>
</packing> </packing>
</child> </child>
<child> <child>
<object class="UndoableEntry" id="place_title"> <object class="UndoableEntry" id="place_title">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="tooltip_text" translatable="yes">Full name of this place.</property> <property name="tooltip_text" translatable="yes">Full title of this place.</property>
<property name="invisible_char">●</property> <property name="invisible_char">●</property>
</object> </object>
<packing> <packing>
<property name="left_attach">1</property> <property name="left_attach">1</property>
<property name="right_attach">5</property> <property name="right_attach">5</property>
<property name="y_options"></property> <property name="y_options"/>
</packing> </packing>
</child> </child>
<child> <child>
@ -160,10 +157,10 @@
<property name="mnemonic_widget">gid</property> <property name="mnemonic_widget">gid</property>
</object> </object>
<packing> <packing>
<property name="top_attach">2</property> <property name="top_attach">3</property>
<property name="bottom_attach">3</property> <property name="bottom_attach">4</property>
<property name="x_options">GTK_FILL</property> <property name="x_options">GTK_FILL</property>
<property name="y_options"></property> <property name="y_options"/>
</packing> </packing>
</child> </child>
<child> <child>
@ -178,9 +175,9 @@ You can set these values via the Geography View by searching the place, or via a
<packing> <packing>
<property name="left_attach">1</property> <property name="left_attach">1</property>
<property name="right_attach">2</property> <property name="right_attach">2</property>
<property name="top_attach">1</property> <property name="top_attach">2</property>
<property name="bottom_attach">2</property> <property name="bottom_attach">3</property>
<property name="y_options"></property> <property name="y_options"/>
</packing> </packing>
</child> </child>
<child> <child>
@ -195,9 +192,9 @@ You can set these values via the Geography View by searching the place, or via a
<packing> <packing>
<property name="left_attach">3</property> <property name="left_attach">3</property>
<property name="right_attach">4</property> <property name="right_attach">4</property>
<property name="top_attach">1</property> <property name="top_attach">2</property>
<property name="bottom_attach">2</property> <property name="bottom_attach">3</property>
<property name="y_options"></property> <property name="y_options"/>
</packing> </packing>
</child> </child>
<child> <child>
@ -221,11 +218,12 @@ You can set these values via the Geography View by searching the place, or via a
</packing> </packing>
</child> </child>
<child> <child>
<object class="GtkLabel" id="label2"> <object class="GtkLabel" id="label5">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="xalign">0</property> <property name="xalign">0</property>
<property name="label" translatable="yes">Tags:</property> <property name="label" translatable="yes">Code:</property>
<property name="use_underline">True</property>
</object> </object>
<packing> <packing>
<property name="expand">False</property> <property name="expand">False</property>
@ -234,10 +232,12 @@ You can set these values via the Geography View by searching the place, or via a
</packing> </packing>
</child> </child>
<child> <child>
<object class="GtkLabel" id="tag_label"> <object class="UndoableEntry" id="code_entry">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">True</property>
<property name="xalign">0</property> <property name="tooltip_text" translatable="yes">Code associated with this place. Eg Country Code or Postal Code.</property>
<property name="invisible_char">●</property>
<property name="width_chars">8</property>
</object> </object>
<packing> <packing>
<property name="expand">True</property> <property name="expand">True</property>
@ -248,19 +248,17 @@ You can set these values via the Geography View by searching the place, or via a
</object> </object>
<packing> <packing>
<property name="left_attach">1</property> <property name="left_attach">1</property>
<property name="right_attach">4</property> <property name="right_attach">2</property>
<property name="top_attach">2</property> <property name="top_attach">3</property>
<property name="bottom_attach">3</property> <property name="bottom_attach">4</property>
<property name="y_options">GTK_FILL</property> <property name="y_options">GTK_FILL</property>
</packing> </packing>
</child> </child>
<child> <child>
<object class="GtkToggleButton" id="private"> <object class="GtkToggleButton" id="private">
<property name="use_action_appearance">False</property>
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="receives_default">True</property> <property name="receives_default">True</property>
<property name="use_action_appearance">False</property>
<property name="relief">none</property> <property name="relief">none</property>
<accelerator key="p" signal="activate" modifiers="GDK_CONTROL_MASK"/> <accelerator key="p" signal="activate" modifiers="GDK_CONTROL_MASK"/>
<child internal-child="accessible"> <child internal-child="accessible">
@ -284,28 +282,121 @@ You can set these values via the Geography View by searching the place, or via a
<packing> <packing>
<property name="left_attach">4</property> <property name="left_attach">4</property>
<property name="right_attach">5</property> <property name="right_attach">5</property>
<property name="top_attach">1</property> <property name="top_attach">2</property>
<property name="bottom_attach">2</property> <property name="bottom_attach">3</property>
<property name="x_options"></property> <property name="x_options"/>
<property name="y_options"></property> <property name="y_options"/>
</packing> </packing>
</child> </child>
<child> <child>
<object class="GtkButton" id="tag_button"> <object class="GtkButton" id="tag_button">
<property name="use_action_appearance">False</property>
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="receives_default">True</property> <property name="receives_default">True</property>
<property name="use_action_appearance">False</property>
<property name="use_stock">True</property> <property name="use_stock">True</property>
</object> </object>
<packing> <packing>
<property name="left_attach">4</property> <property name="left_attach">4</property>
<property name="right_attach">5</property> <property name="right_attach">5</property>
<property name="top_attach">2</property> <property name="top_attach">3</property>
<property name="bottom_attach">3</property> <property name="bottom_attach">4</property>
<property name="x_options"></property> <property name="x_options"/>
<property name="y_options"></property> <property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkLabel" id="label3">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Name:</property>
</object>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkLabel" id="label4">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Type:</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="UndoableEntry" id="name_entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="tooltip_text" translatable="yes">The name of this place.</property>
<property name="invisible_char">●</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkComboBox" id="place_type">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="tooltip_text" translatable="yes">What type of place this is. Eg 'Country', 'City', ... .</property>
<property name="has_entry">True</property>
<child internal-child="entry">
<object class="GtkEntry" id="combobox-entry2">
<property name="can_focus">False</property>
</object>
</child>
</object>
<packing>
<property name="left_attach">3</property>
<property name="right_attach">4</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkLabel" id="label2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Tags:</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkLabel" id="tag_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
</object>
<packing>
<property name="left_attach">3</property>
<property name="right_attach">4</property>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="y_options"/>
</packing> </packing>
</child> </child>
</object> </object>
@ -320,345 +411,10 @@ You can set these values via the Geography View by searching the place, or via a
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<child> <child>
<object class="GtkTable" id="table19"> <placeholder/>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="border_width">12</property>
<property name="n_rows">5</property>
<property name="n_columns">4</property>
<property name="column_spacing">12</property>
<property name="row_spacing">6</property>
<child>
<object class="GtkLabel" id="label245">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">C_ity:</property>
<property name="use_underline">True</property>
<property name="justify">center</property>
<property name="mnemonic_widget">city</property>
</object>
<packing>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label664">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">S_treet:</property>
<property name="use_underline">True</property>
<property name="justify">center</property>
<property name="mnemonic_widget">street</property>
</object>
<packing>
<property name="x_options">GTK_FILL</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<object class="UndoableEntry" id="street">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="tooltip_text" translatable="yes">Lowest level of a place division: eg the street name.
Use Alternate Locations tab to store the current name.</property>
<property name="invisible_char">●</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">4</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<object class="UndoableEntry" id="city">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="tooltip_text" translatable="yes">The town or city where the place is.
Use Alternate Locations tab to store the current name.</property>
<property name="invisible_char">●</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<object class="UndoableEntry" id="parish">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="tooltip_text" translatable="yes">Lowest clergical division of this place. Typically used for church sources that only mention the parish.</property>
<property name="invisible_char">●</property>
</object>
<packing>
<property name="left_attach">3</property>
<property name="right_attach">4</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label279">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Ch_urch parish:</property>
<property name="use_underline">True</property>
<property name="justify">center</property>
<property name="mnemonic_widget">parish</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label247">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Co_unty:</property>
<property name="use_underline">True</property>
<property name="justify">center</property>
<property name="mnemonic_widget">county</property>
</object>
<packing>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<object class="UndoableEntry" id="county">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="tooltip_text" translatable="yes">Third level of place division. Eg., in the USA a county.</property>
<property name="invisible_char">●</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label246">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">_State:</property>
<property name="use_underline">True</property>
<property name="justify">center</property>
<property name="mnemonic_widget">state</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<object class="UndoableEntry" id="state">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="tooltip_text" translatable="yes">Second level of place division, eg., in the USA a state, in Germany a Bundesland.</property>
<property name="invisible_char">●</property>
</object>
<packing>
<property name="left_attach">3</property>
<property name="right_attach">4</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label248">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Count_ry:</property>
<property name="use_underline">True</property>
<property name="justify">center</property>
<property name="mnemonic_widget">country</property>
</object>
<packing>
<property name="top_attach">4</property>
<property name="bottom_attach">5</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<object class="UndoableEntry" id="country">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="tooltip_text" translatable="yes">The country where the place is.
</property>
<property name="invisible_char">●</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">4</property>
<property name="bottom_attach">5</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label290">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">_ZIP/Postal code:</property>
<property name="use_underline">True</property>
<property name="justify">center</property>
<property name="mnemonic_widget">postal</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<object class="UndoableEntry" id="postal">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">●</property>
</object>
<packing>
<property name="left_attach">3</property>
<property name="right_attach">4</property>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label291">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Phon_e:</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">phone</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
<property name="top_attach">4</property>
<property name="bottom_attach">5</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<object class="UndoableEntry" id="phone">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="invisible_char">●</property>
</object>
<packing>
<property name="left_attach">3</property>
<property name="right_attach">4</property>
<property name="top_attach">4</property>
<property name="bottom_attach">5</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">_Locality:</property>
<property name="use_underline">True</property>
<property name="mnemonic_widget">locality</property>
</object>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<object class="GtkEntry" id="locality">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="tooltip_text" translatable="yes">A district within, or a settlement near to, a town or city.
Use Alternate Locations tab to store the current name.</property>
<property name="invisible_char">●</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="y_options"></property>
</packing>
</child>
</object>
</child> </child>
<child type="tab"> <child type="tab">
<object class="GtkHBox" id="hbox107"> <placeholder/>
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkImage" id="image2598">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="stock">gtk-file</property>
<property name="icon-size">1</property>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="label252">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="label" translatable="yes">Location</property>
<property name="justify">center</property>
<attributes>
<attribute name="weight" value="bold"/>
</attributes>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">1</property>
</packing>
</child>
</object>
<packing>
<property name="tab_fill">False</property>
</packing>
</child> </child>
</object> </object>
<packing> <packing>

View File

@ -0,0 +1,215 @@
<?xml version="1.0" encoding="UTF-8"?>
<interface>
<!-- interface-requires gtk+ 3.0 -->
<object class="GtkDialog" id="editplaceref">
<property name="can_focus">False</property>
<property name="default_width">550</property>
<property name="type_hint">dialog</property>
<child internal-child="vbox">
<object class="GtkBox" id="dialog-vbox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child internal-child="action_area">
<object class="GtkButtonBox" id="dialog-action_area">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="layout_style">end</property>
<child>
<object class="GtkButton" id="cancel_button">
<property name="label">gtk-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_stock">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_button">
<property name="label">gtk-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_stock">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="help_button">
<property name="label">gtk-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_stock">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="GtkVBox" id="vbox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkTable" id="table">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="border_width">12</property>
<property name="n_rows">2</property>
<property name="n_columns">3</property>
<property name="column_spacing">12</property>
<property name="row_spacing">6</property>
<child>
<object class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Parent Place:</property>
<property name="use_underline">True</property>
<property name="justify">right</property>
</object>
<packing>
<property name="x_options">GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkLabel" id="label2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">Date:</property>
<property name="use_underline">True</property>
</object>
<packing>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkButton" id="place_button">
<property name="label" translatable="yes">...</property>
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="receives_default">True</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkButton" id="date_stat">
<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>
<accelerator key="d" signal="activate" modifiers="GDK_CONTROL_MASK"/>
<child internal-child="accessible">
<object class="AtkObject" id="date_stat-atkobject">
<property name="AtkObject::accessible-name" translatable="yes">Date</property>
</object>
</child>
<child>
<object class="GtkImage" id="date_stat_child">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="has_tooltip">True</property>
<property name="tooltip_text" translatable="yes">Show Date Editor</property>
<property name="icon_name">gramps-date</property>
<child internal-child="accessible">
<object class="AtkObject" id="date_stat_child-atkobject">
<property name="AtkObject::accessible-description" translatable="yes">Date</property>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkLabel" id="place_label">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="ValidatableMaskedEntry" id="date_entry">
<property name="height_request">27</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="tooltip_text" translatable="yes">Date range for which the parent is valid.</property>
<property name="invisible_char">●</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="y_options"/>
</packing>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
<action-widgets>
<action-widget response="-6">cancel_button</action-widget>
<action-widget response="-5">ok_button</action-widget>
<action-widget response="-11">help_button</action-widget>
</action-widgets>
</object>
</interface>

View File

@ -19,12 +19,10 @@
<child> <child>
<object class="GtkButton" id="place_cancel"> <object class="GtkButton" id="place_cancel">
<property name="label">gtk-cancel</property> <property name="label">gtk-cancel</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="can_default">True</property> <property name="can_default">True</property>
<property name="receives_default">False</property> <property name="receives_default">False</property>
<property name="use_action_appearance">False</property>
<property name="use_stock">True</property> <property name="use_stock">True</property>
</object> </object>
<packing> <packing>
@ -36,12 +34,10 @@
<child> <child>
<object class="GtkButton" id="place_ok"> <object class="GtkButton" id="place_ok">
<property name="label">gtk-ok</property> <property name="label">gtk-ok</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="can_default">True</property> <property name="can_default">True</property>
<property name="receives_default">False</property> <property name="receives_default">False</property>
<property name="use_action_appearance">False</property>
<property name="use_stock">True</property> <property name="use_stock">True</property>
</object> </object>
<packing> <packing>
@ -53,12 +49,10 @@
<child> <child>
<object class="GtkButton" id="place_help"> <object class="GtkButton" id="place_help">
<property name="label">gtk-help</property> <property name="label">gtk-help</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="can_default">True</property> <property name="can_default">True</property>
<property name="receives_default">False</property> <property name="receives_default">False</property>
<property name="use_action_appearance">False</property>
<property name="use_stock">True</property> <property name="use_stock">True</property>
</object> </object>
<packing> <packing>
@ -111,11 +105,9 @@ primary data for the merged place.</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<child> <child>
<object class="GtkRadioButton" id="handle_btn1"> <object class="GtkRadioButton" id="handle_btn1">
<property name="use_action_appearance">False</property>
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="receives_default">False</property> <property name="receives_default">False</property>
<property name="use_action_appearance">False</property>
<property name="xalign">0.5</property> <property name="xalign">0.5</property>
<property name="draw_indicator">True</property> <property name="draw_indicator">True</property>
<child> <child>
@ -135,11 +127,9 @@ primary data for the merged place.</property>
</child> </child>
<child> <child>
<object class="GtkRadioButton" id="handle_btn2"> <object class="GtkRadioButton" id="handle_btn2">
<property name="use_action_appearance">False</property>
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="receives_default">False</property> <property name="receives_default">False</property>
<property name="use_action_appearance">False</property>
<property name="xalign">0.5</property> <property name="xalign">0.5</property>
<property name="draw_indicator">True</property> <property name="draw_indicator">True</property>
<property name="group">handle_btn1</property> <property name="group">handle_btn1</property>
@ -179,7 +169,7 @@ primary data for the merged place.</property>
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">False</property> <property name="can_focus">False</property>
<property name="border_width">6</property> <property name="border_width">6</property>
<property name="n_rows">6</property> <property name="n_rows">8</property>
<property name="n_columns">4</property> <property name="n_columns">4</property>
<property name="column_spacing">6</property> <property name="column_spacing">6</property>
<property name="row_spacing">6</property> <property name="row_spacing">6</property>
@ -194,7 +184,7 @@ primary data for the merged place.</property>
</object> </object>
<packing> <packing>
<property name="x_options">GTK_FILL</property> <property name="x_options">GTK_FILL</property>
<property name="y_options"></property> <property name="y_options"/>
</packing> </packing>
</child> </child>
<child> <child>
@ -210,17 +200,15 @@ primary data for the merged place.</property>
<property name="left_attach">2</property> <property name="left_attach">2</property>
<property name="right_attach">3</property> <property name="right_attach">3</property>
<property name="x_options">GTK_FILL</property> <property name="x_options">GTK_FILL</property>
<property name="y_options"></property> <property name="y_options"/>
</packing> </packing>
</child> </child>
<child> <child>
<object class="GtkRadioButton" id="title_btn1"> <object class="GtkRadioButton" id="title_btn1">
<property name="label" translatable="yes">Title:</property> <property name="label" translatable="yes">Title:</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="receives_default">False</property> <property name="receives_default">False</property>
<property name="use_action_appearance">False</property>
<property name="use_underline">True</property> <property name="use_underline">True</property>
<property name="xalign">0.5</property> <property name="xalign">0.5</property>
<property name="draw_indicator">True</property> <property name="draw_indicator">True</property>
@ -229,17 +217,15 @@ primary data for the merged place.</property>
<property name="top_attach">1</property> <property name="top_attach">1</property>
<property name="bottom_attach">2</property> <property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property> <property name="x_options">GTK_FILL</property>
<property name="y_options"></property> <property name="y_options"/>
</packing> </packing>
</child> </child>
<child> <child>
<object class="GtkRadioButton" id="title_btn2"> <object class="GtkRadioButton" id="title_btn2">
<property name="label" translatable="yes">Title:</property> <property name="label" translatable="yes">Title:</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="receives_default">False</property> <property name="receives_default">False</property>
<property name="use_action_appearance">False</property>
<property name="use_underline">True</property> <property name="use_underline">True</property>
<property name="xalign">0.5</property> <property name="xalign">0.5</property>
<property name="draw_indicator">True</property> <property name="draw_indicator">True</property>
@ -251,36 +237,32 @@ primary data for the merged place.</property>
<property name="top_attach">1</property> <property name="top_attach">1</property>
<property name="bottom_attach">2</property> <property name="bottom_attach">2</property>
<property name="x_options">GTK_FILL</property> <property name="x_options">GTK_FILL</property>
<property name="y_options"></property> <property name="y_options"/>
</packing> </packing>
</child> </child>
<child> <child>
<object class="GtkRadioButton" id="lat_btn1"> <object class="GtkRadioButton" id="lat_btn1">
<property name="label" translatable="yes">Latitude:</property> <property name="label" translatable="yes">Latitude:</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="receives_default">False</property> <property name="receives_default">False</property>
<property name="use_action_appearance">False</property>
<property name="use_underline">True</property> <property name="use_underline">True</property>
<property name="xalign">0.5</property> <property name="xalign">0.5</property>
<property name="draw_indicator">True</property> <property name="draw_indicator">True</property>
</object> </object>
<packing> <packing>
<property name="top_attach">2</property> <property name="top_attach">5</property>
<property name="bottom_attach">3</property> <property name="bottom_attach">6</property>
<property name="x_options">GTK_FILL</property> <property name="x_options">GTK_FILL</property>
<property name="y_options"></property> <property name="y_options"/>
</packing> </packing>
</child> </child>
<child> <child>
<object class="GtkRadioButton" id="lat_btn2"> <object class="GtkRadioButton" id="lat_btn2">
<property name="label" translatable="yes">Latitude:</property> <property name="label" translatable="yes">Latitude:</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="receives_default">False</property> <property name="receives_default">False</property>
<property name="use_action_appearance">False</property>
<property name="use_underline">True</property> <property name="use_underline">True</property>
<property name="xalign">0.5</property> <property name="xalign">0.5</property>
<property name="draw_indicator">True</property> <property name="draw_indicator">True</property>
@ -289,39 +271,35 @@ primary data for the merged place.</property>
<packing> <packing>
<property name="left_attach">2</property> <property name="left_attach">2</property>
<property name="right_attach">3</property> <property name="right_attach">3</property>
<property name="top_attach">2</property> <property name="top_attach">5</property>
<property name="bottom_attach">3</property> <property name="bottom_attach">6</property>
<property name="x_options">GTK_FILL</property> <property name="x_options">GTK_FILL</property>
<property name="y_options"></property> <property name="y_options"/>
</packing> </packing>
</child> </child>
<child> <child>
<object class="GtkRadioButton" id="long_btn1"> <object class="GtkRadioButton" id="long_btn1">
<property name="label" translatable="yes">Longitude:</property> <property name="label" translatable="yes">Longitude:</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="receives_default">False</property> <property name="receives_default">False</property>
<property name="use_action_appearance">False</property>
<property name="use_underline">True</property> <property name="use_underline">True</property>
<property name="xalign">0.5</property> <property name="xalign">0.5</property>
<property name="draw_indicator">True</property> <property name="draw_indicator">True</property>
</object> </object>
<packing> <packing>
<property name="top_attach">3</property> <property name="top_attach">6</property>
<property name="bottom_attach">4</property> <property name="bottom_attach">7</property>
<property name="x_options">GTK_FILL</property> <property name="x_options">GTK_FILL</property>
<property name="y_options"></property> <property name="y_options"/>
</packing> </packing>
</child> </child>
<child> <child>
<object class="GtkRadioButton" id="long_btn2"> <object class="GtkRadioButton" id="long_btn2">
<property name="label" translatable="yes">Longitude:</property> <property name="label" translatable="yes">Longitude:</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="receives_default">False</property> <property name="receives_default">False</property>
<property name="use_action_appearance">False</property>
<property name="use_underline">True</property> <property name="use_underline">True</property>
<property name="xalign">0.5</property> <property name="xalign">0.5</property>
<property name="draw_indicator">True</property> <property name="draw_indicator">True</property>
@ -330,80 +308,35 @@ primary data for the merged place.</property>
<packing> <packing>
<property name="left_attach">2</property> <property name="left_attach">2</property>
<property name="right_attach">3</property> <property name="right_attach">3</property>
<property name="top_attach">3</property> <property name="top_attach">6</property>
<property name="bottom_attach">4</property> <property name="bottom_attach">7</property>
<property name="x_options">GTK_FILL</property> <property name="x_options">GTK_FILL</property>
<property name="y_options"></property> <property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkRadioButton" id="loc_btn1">
<property name="label" translatable="yes">Location:</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_action_appearance">False</property>
<property name="use_underline">True</property>
<property name="xalign">0.5</property>
<property name="draw_indicator">True</property>
</object>
<packing>
<property name="top_attach">4</property>
<property name="bottom_attach">5</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<object class="GtkRadioButton" id="loc_btn2">
<property name="label" translatable="yes">Location:</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_action_appearance">False</property>
<property name="use_underline">True</property>
<property name="xalign">0.5</property>
<property name="draw_indicator">True</property>
<property name="group">loc_btn1</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
<property name="top_attach">4</property>
<property name="bottom_attach">5</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"></property>
</packing> </packing>
</child> </child>
<child> <child>
<object class="GtkRadioButton" id="gramps_btn1"> <object class="GtkRadioButton" id="gramps_btn1">
<property name="label" translatable="yes">Gramps ID:</property> <property name="label" translatable="yes">Gramps ID:</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="receives_default">False</property> <property name="receives_default">False</property>
<property name="use_action_appearance">False</property>
<property name="use_underline">True</property> <property name="use_underline">True</property>
<property name="xalign">0.5</property> <property name="xalign">0.5</property>
<property name="draw_indicator">True</property> <property name="draw_indicator">True</property>
</object> </object>
<packing> <packing>
<property name="top_attach">5</property> <property name="top_attach">7</property>
<property name="bottom_attach">6</property> <property name="bottom_attach">8</property>
<property name="x_options">GTK_FILL</property> <property name="x_options">GTK_FILL</property>
<property name="y_options"></property> <property name="y_options"/>
</packing> </packing>
</child> </child>
<child> <child>
<object class="GtkRadioButton" id="gramps_btn2"> <object class="GtkRadioButton" id="gramps_btn2">
<property name="label" translatable="yes">Gramps ID:</property> <property name="label" translatable="yes">Gramps ID:</property>
<property name="use_action_appearance">False</property>
<property name="visible">True</property> <property name="visible">True</property>
<property name="can_focus">True</property> <property name="can_focus">True</property>
<property name="receives_default">False</property> <property name="receives_default">False</property>
<property name="use_action_appearance">False</property>
<property name="use_underline">True</property> <property name="use_underline">True</property>
<property name="xalign">0.5</property> <property name="xalign">0.5</property>
<property name="draw_indicator">True</property> <property name="draw_indicator">True</property>
@ -412,10 +345,10 @@ primary data for the merged place.</property>
<packing> <packing>
<property name="left_attach">2</property> <property name="left_attach">2</property>
<property name="right_attach">3</property> <property name="right_attach">3</property>
<property name="top_attach">5</property> <property name="top_attach">7</property>
<property name="bottom_attach">6</property> <property name="bottom_attach">8</property>
<property name="x_options">GTK_FILL</property> <property name="x_options">GTK_FILL</property>
<property name="y_options"></property> <property name="y_options"/>
</packing> </packing>
</child> </child>
<child> <child>
@ -429,7 +362,7 @@ primary data for the merged place.</property>
<property name="right_attach">2</property> <property name="right_attach">2</property>
<property name="top_attach">1</property> <property name="top_attach">1</property>
<property name="bottom_attach">2</property> <property name="bottom_attach">2</property>
<property name="y_options"></property> <property name="y_options"/>
</packing> </packing>
</child> </child>
<child> <child>
@ -443,7 +376,7 @@ primary data for the merged place.</property>
<property name="right_attach">4</property> <property name="right_attach">4</property>
<property name="top_attach">1</property> <property name="top_attach">1</property>
<property name="bottom_attach">2</property> <property name="bottom_attach">2</property>
<property name="y_options"></property> <property name="y_options"/>
</packing> </packing>
</child> </child>
<child> <child>
@ -455,9 +388,9 @@ primary data for the merged place.</property>
<packing> <packing>
<property name="left_attach">1</property> <property name="left_attach">1</property>
<property name="right_attach">2</property> <property name="right_attach">2</property>
<property name="top_attach">2</property> <property name="top_attach">5</property>
<property name="bottom_attach">3</property> <property name="bottom_attach">6</property>
<property name="y_options"></property> <property name="y_options"/>
</packing> </packing>
</child> </child>
<child> <child>
@ -469,9 +402,9 @@ primary data for the merged place.</property>
<packing> <packing>
<property name="left_attach">3</property> <property name="left_attach">3</property>
<property name="right_attach">4</property> <property name="right_attach">4</property>
<property name="top_attach">2</property> <property name="top_attach">5</property>
<property name="bottom_attach">3</property> <property name="bottom_attach">6</property>
<property name="y_options"></property> <property name="y_options"/>
</packing> </packing>
</child> </child>
<child> <child>
@ -483,9 +416,9 @@ primary data for the merged place.</property>
<packing> <packing>
<property name="left_attach">1</property> <property name="left_attach">1</property>
<property name="right_attach">2</property> <property name="right_attach">2</property>
<property name="top_attach">3</property> <property name="top_attach">6</property>
<property name="bottom_attach">4</property> <property name="bottom_attach">7</property>
<property name="y_options"></property> <property name="y_options"/>
</packing> </packing>
</child> </child>
<child> <child>
@ -497,49 +430,9 @@ primary data for the merged place.</property>
<packing> <packing>
<property name="left_attach">3</property> <property name="left_attach">3</property>
<property name="right_attach">4</property> <property name="right_attach">4</property>
<property name="top_attach">3</property> <property name="top_attach">6</property>
<property name="bottom_attach">4</property> <property name="bottom_attach">7</property>
<property name="y_options"></property> <property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkViewport" id="viewport1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkTextView" id="loc1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="editable">False</property>
</object>
</child>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">4</property>
<property name="bottom_attach">5</property>
<property name="y_options"></property>
</packing>
</child>
<child>
<object class="GtkViewport" id="viewport2">
<property name="visible">True</property>
<property name="can_focus">False</property>
<child>
<object class="GtkTextView" id="loc2">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="editable">False</property>
</object>
</child>
</object>
<packing>
<property name="left_attach">3</property>
<property name="right_attach">4</property>
<property name="top_attach">4</property>
<property name="bottom_attach">5</property>
<property name="y_options"></property>
</packing> </packing>
</child> </child>
<child> <child>
@ -551,9 +444,9 @@ primary data for the merged place.</property>
<packing> <packing>
<property name="left_attach">1</property> <property name="left_attach">1</property>
<property name="right_attach">2</property> <property name="right_attach">2</property>
<property name="top_attach">5</property> <property name="top_attach">7</property>
<property name="bottom_attach">6</property> <property name="bottom_attach">8</property>
<property name="y_options"></property> <property name="y_options"/>
</packing> </packing>
</child> </child>
<child> <child>
@ -568,14 +461,229 @@ primary data for the merged place.</property>
<packing> <packing>
<property name="left_attach">3</property> <property name="left_attach">3</property>
<property name="right_attach">4</property> <property name="right_attach">4</property>
<property name="top_attach">5</property> <property name="top_attach">7</property>
<property name="bottom_attach">6</property> <property name="bottom_attach">8</property>
<property name="y_options"></property> <property name="y_options"/>
</packing> </packing>
</child> </child>
<child> <child>
<placeholder/> <placeholder/>
</child> </child>
<child>
<object class="GtkRadioButton" id="name_btn1">
<property name="label" translatable="yes">Name:</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="relief">half</property>
<property name="use_underline">True</property>
<property name="xalign">0</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
</object>
<packing>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkRadioButton" id="name_btn2">
<property name="label" translatable="yes">Name:</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="relief">half</property>
<property name="use_underline">True</property>
<property name="xalign">0</property>
<property name="draw_indicator">True</property>
<property name="group">name_btn1</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkEntry" id="name1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="editable">False</property>
<property name="invisible_char">•</property>
<property name="invisible_char_set">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkEntry" id="name2">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="editable">False</property>
<property name="invisible_char">•</property>
<property name="invisible_char_set">True</property>
</object>
<packing>
<property name="left_attach">3</property>
<property name="right_attach">4</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkRadioButton" id="type_btn1">
<property name="label" translatable="yes">Type:</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="relief">half</property>
<property name="use_underline">True</property>
<property name="xalign">0</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
</object>
<packing>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkRadioButton" id="type_btn2">
<property name="label" translatable="yes">Type:</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="relief">half</property>
<property name="use_underline">True</property>
<property name="xalign">0</property>
<property name="draw_indicator">True</property>
<property name="group">type_btn1</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkEntry" id="type1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="editable">False</property>
<property name="invisible_char">•</property>
<property name="invisible_char_set">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkEntry" id="type2">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="editable">False</property>
<property name="invisible_char">•</property>
<property name="invisible_char_set">True</property>
</object>
<packing>
<property name="left_attach">3</property>
<property name="right_attach">4</property>
<property name="top_attach">3</property>
<property name="bottom_attach">4</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkRadioButton" id="code_btn1">
<property name="label" translatable="yes">Code:</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="relief">half</property>
<property name="use_underline">True</property>
<property name="xalign">0</property>
<property name="active">True</property>
<property name="draw_indicator">True</property>
</object>
<packing>
<property name="top_attach">4</property>
<property name="bottom_attach">5</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkRadioButton" id="code_btn2">
<property name="label" translatable="yes">Code:</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
<property name="use_underline">True</property>
<property name="xalign">0</property>
<property name="draw_indicator">True</property>
<property name="group">code_btn1</property>
</object>
<packing>
<property name="left_attach">2</property>
<property name="right_attach">3</property>
<property name="top_attach">4</property>
<property name="bottom_attach">5</property>
<property name="x_options">GTK_FILL</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkEntry" id="code1">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="editable">False</property>
<property name="invisible_char">•</property>
<property name="invisible_char_set">True</property>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">4</property>
<property name="bottom_attach">5</property>
<property name="y_options"/>
</packing>
</child>
<child>
<object class="GtkEntry" id="code2">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="editable">False</property>
<property name="invisible_char">•</property>
<property name="invisible_char_set">True</property>
</object>
<packing>
<property name="left_attach">3</property>
<property name="right_attach">4</property>
<property name="top_attach">4</property>
<property name="bottom_attach">5</property>
<property name="y_options"/>
</packing>
</child>
</object> </object>
<packing> <packing>
<property name="expand">True</property> <property name="expand">True</property>

View File

@ -63,10 +63,11 @@ class MergePlace(ManagedWindow):
""" """
Displays a dialog box that allows the places to be combined into one. Displays a dialog box that allows the places to be combined into one.
""" """
def __init__(self, dbstate, uistate, handle1, handle2): def __init__(self, dbstate, uistate, handle1, handle2, callback=None):
ManagedWindow.__init__(self, uistate, [], self.__class__) ManagedWindow.__init__(self, uistate, [], self.__class__)
self.dbstate = dbstate self.dbstate = dbstate
database = dbstate.db database = dbstate.db
self.callback = callback
self.pl1 = database.get_place_from_handle(handle1) self.pl1 = database.get_place_from_handle(handle1)
self.pl2 = database.get_place_from_handle(handle2) self.pl2 = database.get_place_from_handle(handle2)
@ -86,6 +87,30 @@ class MergePlace(ManagedWindow):
for widget_name in ('title1', 'title2', 'title_btn1', 'title_btn2'): for widget_name in ('title1', 'title2', 'title_btn1', 'title_btn2'):
self.get_widget(widget_name).set_sensitive(False) self.get_widget(widget_name).set_sensitive(False)
entry1 = self.get_widget("name1")
entry2 = self.get_widget("name2")
entry1.set_text(self.pl1.get_name())
entry2.set_text(self.pl2.get_name())
if entry1.get_text() == entry2.get_text():
for widget_name in ('name1', 'name2', 'name_btn1', 'name_btn2'):
self.get_widget(widget_name).set_sensitive(False)
entry1 = self.get_widget("type1")
entry2 = self.get_widget("type2")
entry1.set_text(str(self.pl1.get_type()))
entry2.set_text(str(self.pl2.get_type()))
if entry1.get_text() == entry2.get_text():
for widget_name in ('type1', 'type2', 'type_btn1', 'type_btn2'):
self.get_widget(widget_name).set_sensitive(False)
entry1 = self.get_widget("code1")
entry2 = self.get_widget("code2")
entry1.set_text(self.pl1.get_code())
entry2.set_text(self.pl2.get_code())
if entry1.get_text() == entry2.get_text():
for widget_name in ('code1', 'code2', 'code_btn1', 'code_btn2'):
self.get_widget(widget_name).set_sensitive(False)
entry1 = self.get_widget("lat1") entry1 = self.get_widget("lat1")
entry2 = self.get_widget("lat2") entry2 = self.get_widget("lat2")
entry1.set_text(self.pl1.get_latitude()) entry1.set_text(self.pl1.get_latitude())
@ -102,20 +127,6 @@ class MergePlace(ManagedWindow):
for widget_name in ('long1', 'long2', 'long_btn1', 'long_btn2'): for widget_name in ('long1', 'long2', 'long_btn1', 'long_btn2'):
self.get_widget(widget_name).set_sensitive(False) self.get_widget(widget_name).set_sensitive(False)
loc1 = self.pl1.get_main_location().get_text_data_list()
loc2 = self.pl2.get_main_location().get_text_data_list()
tv1 = self.get_widget("loc1")
tv2 = self.get_widget("loc2")
tb1 = Gtk.TextBuffer()
tb2 = Gtk.TextBuffer()
tv1.set_buffer(tb1)
tv2.set_buffer(tb2)
tb1.set_text("\n".join(loc1))
tb2.set_text("\n".join(loc2))
if loc1 == loc2:
for widget_name in ('loc1', 'loc2', 'loc_btn1', 'loc_btn2'):
self.get_widget(widget_name).set_sensitive(False)
gramps1 = self.pl1.get_gramps_id() gramps1 = self.pl1.get_gramps_id()
gramps2 = self.pl2.get_gramps_id() gramps2 = self.pl2.get_gramps_id()
entry1 = self.get_widget("gramps1") entry1 = self.get_widget("gramps1")
@ -144,12 +155,18 @@ class MergePlace(ManagedWindow):
"""first chosen place changes""" """first chosen place changes"""
if obj.get_active(): if obj.get_active():
self.get_widget("title_btn1").set_active(True) self.get_widget("title_btn1").set_active(True)
self.get_widget("name_btn1").set_active(True)
self.get_widget("type_btn1").set_active(True)
self.get_widget("code_btn1").set_active(True)
self.get_widget("lat_btn1").set_active(True) self.get_widget("lat_btn1").set_active(True)
self.get_widget("long_btn1").set_active(True) self.get_widget("long_btn1").set_active(True)
self.get_widget("loc_btn1").set_active(True) self.get_widget("loc_btn1").set_active(True)
self.get_widget("gramps_btn1").set_active(True) self.get_widget("gramps_btn1").set_active(True)
else: else:
self.get_widget("title_btn2").set_active(True) self.get_widget("title_btn2").set_active(True)
self.get_widget("name_btn2").set_active(True)
self.get_widget("type_btn2").set_active(True)
self.get_widget("code_btn2").set_active(True)
self.get_widget("lat_btn2").set_active(True) self.get_widget("lat_btn2").set_active(True)
self.get_widget("long_btn2").set_active(True) self.get_widget("long_btn2").set_active(True)
self.get_widget("loc_btn2").set_active(True) self.get_widget("loc_btn2").set_active(True)
@ -179,18 +196,23 @@ class MergePlace(ManagedWindow):
if self.get_widget("title_btn1").get_active() ^ use_handle1: if self.get_widget("title_btn1").get_active() ^ use_handle1:
phoenix.set_title(titanic.get_title()) phoenix.set_title(titanic.get_title())
if self.get_widget("name_btn1").get_active() ^ use_handle1:
phoenix.set_name(titanic.get_name())
if self.get_widget("type_btn1").get_active() ^ use_handle1:
phoenix.set_type(titanic.get_type())
if self.get_widget("code_btn1").get_active() ^ use_handle1:
phoenix.set_code(titanic.get_code())
if self.get_widget("lat_btn1").get_active() ^ use_handle1: if self.get_widget("lat_btn1").get_active() ^ use_handle1:
phoenix.set_latitude(titanic.get_latitude()) phoenix.set_latitude(titanic.get_latitude())
if self.get_widget("long_btn1").get_active() ^ use_handle1: if self.get_widget("long_btn1").get_active() ^ use_handle1:
phoenix.set_longitude(titanic.get_longitude()) phoenix.set_longitude(titanic.get_longitude())
if self.get_widget("loc_btn1").get_active() ^ use_handle1:
swaploc = phoenix.get_main_location()
phoenix.set_main_location(titanic.get_main_location())
titanic.set_main_location(swaploc)
if self.get_widget("gramps_btn1").get_active() ^ use_handle1: if self.get_widget("gramps_btn1").get_active() ^ use_handle1:
phoenix.set_gramps_id(titanic.get_gramps_id()) phoenix.set_gramps_id(titanic.get_gramps_id())
query = MergePlaceQuery(self.dbstate, phoenix, titanic) query = MergePlaceQuery(self.dbstate, phoenix, titanic)
query.execute() query.execute()
if self.callback:
self.callback()
self.uistate.set_busy_cursor(False) self.uistate.set_busy_cursor(False)
self.close() self.close()

View File

@ -35,7 +35,7 @@ _ = glocale.translation.gettext
# gramps modules # gramps modules
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
from ..views.treemodels.placemodel import PlaceListModel from ..views.treemodels.placemodel import PlaceTreeModel
from .baseselector import BaseSelector from .baseselector import BaseSelector
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
@ -56,19 +56,14 @@ class SelectPlace(BaseSelector):
return _("Select Place") return _("Select Place")
def get_model_class(self): def get_model_class(self):
return PlaceListModel return PlaceTreeModel
def get_column_titles(self): def get_column_titles(self):
return [ return [
(_('Title'), 350, BaseSelector.TEXT, 0), (_('Name'), 200, BaseSelector.TEXT, 0),
(_('ID'), 75, BaseSelector.TEXT, 1), (_('ID'), 75, BaseSelector.TEXT, 1),
(_('Street'), 75, BaseSelector.TEXT, 2), (_('Type'), 100, BaseSelector.TEXT, 3),
(_('Locality'), 75, BaseSelector.TEXT, 3), (_('Title'), 300, BaseSelector.TEXT, 2),
(_('City'), 75, BaseSelector.TEXT, 4),
(_('County'), 75, BaseSelector.TEXT, 5),
(_('State'), 75, BaseSelector.TEXT, 6),
(_('Country'), 75, BaseSelector.TEXT, 7),
(_('Parish'), 75, BaseSelector.TEXT, 9),
] ]
def get_from_handle_func(self): def get_from_handle_func(self):

View File

@ -424,11 +424,12 @@ class ListView(NavigationView):
parent_iter = self.model.iter_parent(iter_) parent_iter = self.model.iter_parent(iter_)
if parent_iter: if parent_iter:
parent_path = self.model.get_path(parent_iter) parent_path = self.model.get_path(parent_iter)
parent_path_list = parent_path.get_indices() if parent_path:
for i in range(len(parent_path_list)): parent_path_list = parent_path.get_indices()
expand_path = Gtk.TreePath( for i in range(len(parent_path_list)):
tuple([x for x in parent_path_list[:i+1]])) expand_path = Gtk.TreePath(
self.list.expand_row(expand_path, False) tuple([x for x in parent_path_list[:i+1]]))
self.list.expand_row(expand_path, False)
# Select active object # Select active object
path = self.model.get_path(iter_) path = self.model.get_path(iter_)

View File

@ -30,7 +30,6 @@ Place Model.
# python modules # python modules
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
import cgi
import logging import logging
_LOG = logging.getLogger(".gui.views.treemodels.placemodel") _LOG = logging.getLogger(".gui.views.treemodels.placemodel")
@ -46,6 +45,7 @@ from gi.repository import Gtk
# GRAMPS modules # GRAMPS modules
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
from gramps.gen.lib.placetype import PlaceType
from gramps.gen.datehandler import format_time from gramps.gen.datehandler import format_time
from gramps.gen.utils.place import conv_lat_lon from gramps.gen.utils.place import conv_lat_lon
from gramps.gen.constfunc import cuni from gramps.gen.constfunc import cuni
@ -60,16 +60,6 @@ from .treebasemodel import TreeBaseModel
from gramps.gen.const import GRAMPS_LOCALE as glocale from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext _ = glocale.translation.gettext
#-------------------------------------------------------------------------
#
# Constants
#
#-------------------------------------------------------------------------
COUNTRYLEVELS = {
'default': [_('<Countries>'), _('<States>'), _('<Counties>'),
_('<Places>')]
}
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
# PlaceBaseModel # PlaceBaseModel
@ -83,39 +73,27 @@ class PlaceBaseModel(object):
self.fmap = [ self.fmap = [
self.column_name, self.column_name,
self.column_id, self.column_id,
self.column_street, self.column_title,
self.column_locality, self.column_type,
self.column_city, self.column_code,
self.column_county,
self.column_state,
self.column_country,
self.column_postal_code,
self.column_parish,
self.column_latitude, self.column_latitude,
self.column_longitude, self.column_longitude,
self.column_private, self.column_private,
self.column_tags, self.column_tags,
self.column_change, self.column_change,
self.column_place_name,
self.column_tag_color self.column_tag_color
] ]
self.smap = [ self.smap = [
self.column_name, self.column_name,
self.column_id, self.column_id,
self.column_street, self.column_title,
self.column_locality, self.column_type,
self.column_city, self.column_code,
self.column_county,
self.column_state,
self.column_country,
self.column_postal_code,
self.column_parish,
self.sort_latitude, self.sort_latitude,
self.sort_longitude, self.sort_longitude,
self.column_private, self.column_private,
self.column_tags, self.column_tags,
self.sort_change, self.sort_change,
self.column_place_name,
self.column_tag_color self.column_tag_color
] ]
@ -133,14 +111,17 @@ class PlaceBaseModel(object):
""" """
Return the color column. Return the color column.
""" """
return 16 return 10
def on_get_n_columns(self): def on_get_n_columns(self):
return len(self.fmap)+1 return len(self.fmap)+1
def column_place_name(self, data): def column_title(self, data):
return cuni(data[2]) return cuni(data[2])
def column_name(self, data):
return cuni(data[6])
def column_longitude(self, data): def column_longitude(self, data):
if not data[3]: if not data[3]:
return '' return ''
@ -176,66 +157,24 @@ class PlaceBaseModel(object):
def column_id(self, data): def column_id(self, data):
return cuni(data[1]) return cuni(data[1])
def column_parish(self, data): def column_type(self, data):
try: return str(PlaceType(data[7]))
return data[5][1]
except:
return ''
def column_street(self, data): def column_code(self, data):
try: return cuni(data[8])
return data[5][0][0]
except:
return ''
def column_locality(self, data):
try:
return data[5][0][1]
except:
return ''
def column_city(self, data):
try:
return data[5][0][2]
except:
return ''
def column_county(self, data):
try:
return data[5][0][3]
except:
return ''
def column_state(self, data):
try:
return data[5][0][4]
except:
return ''
def column_country(self, data):
try:
return data[5][0][5]
except:
return ''
def column_postal_code(self, data):
try:
return data[5][0][6]
except:
return ''
def column_private(self, data): def column_private(self, data):
if data[13]: if data[16]:
return 'gramps-lock' return 'gramps-lock'
else: else:
# There is a problem returning None here. # There is a problem returning None here.
return '' return ''
def sort_change(self, data): def sort_change(self, data):
return "%012x" % data[11] return "%012x" % data[14]
def column_change(self, data): def column_change(self, data):
return format_time(data[11]) return format_time(data[14])
def get_tag_name(self, tag_handle): def get_tag_name(self, tag_handle):
""" """
@ -249,7 +188,7 @@ class PlaceBaseModel(object):
""" """
tag_color = "#000000000000" tag_color = "#000000000000"
tag_priority = None tag_priority = None
for handle in data[12]: for handle in data[15]:
tag = self.db.get_tag_from_handle(handle) tag = self.db.get_tag_from_handle(handle)
if tag: if tag:
this_priority = tag.get_priority() this_priority = tag.get_priority()
@ -262,7 +201,7 @@ class PlaceBaseModel(object):
""" """
Return the sorted list of tags. Return the sorted list of tags.
""" """
tag_list = list(map(self.get_tag_name, data[12])) tag_list = list(map(self.get_tag_name, data[15]))
return ', '.join(sorted(tag_list, key=glocale.sort_key)) return ', '.join(sorted(tag_list, key=glocale.sort_key))
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
@ -288,9 +227,6 @@ class PlaceListModel(PlaceBaseModel, FlatBaseModel):
PlaceBaseModel.destroy(self) PlaceBaseModel.destroy(self)
FlatBaseModel.destroy(self) FlatBaseModel.destroy(self)
def column_name(self, data):
return cgi.escape(cuni(data[2]))
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
# PlaceTreeModel # PlaceTreeModel
@ -322,6 +258,7 @@ class PlaceTreeModel(PlaceBaseModel, TreeBaseModel):
PlaceBaseModel PlaceBaseModel
""" """
self.number_items = self.db.get_number_of_places self.number_items = self.db.get_number_of_places
self.gen_cursor = self.db.get_place_tree_cursor
def get_tree_levels(self): def get_tree_levels(self):
""" """
@ -336,68 +273,19 @@ class PlaceTreeModel(PlaceBaseModel, TreeBaseModel):
handle The handle of the gramps object. handle The handle of the gramps object.
data The object data. data The object data.
""" """
if data[5] is None:
# No primary location
level = [''] * 6
else:
#country, state, county, city, locality, street
level = [data[5][0][i] for i in range(5,-1,-1)]
node1 = (level[0], )
node2 = (level[1], level[0])
node3 = (level[2], level[1], level[0])
sort_key = self.sort_func(data) sort_key = self.sort_func(data)
if len(data[5]) > 0:
if not (level[3] or level[4] or level[5]): parent = data[5][0][0]
if level[2]:
self.add_node(None, node1, level[0], None, add_parent=False)
self.add_node(node1, node2, level[1], None, add_parent=False)
self.add_node(node2, node3, level[2], None, add_parent=False)
self.add_node(node3, handle, sort_key, handle, add_parent=False)
elif level[1]:
self.add_node(None, node1, level[0], None, add_parent=False)
self.add_node(node1, node2, level[1], None, add_parent=False)
self.add_node(node2, handle, level[1], handle, add_parent=False)
elif level[0]:
self.add_node(None, node1, level[0], None, add_parent=False)
self.add_node(node1, handle, level[0], handle, add_parent=False)
else:
self.add_node(None, node1, level[0], None, add_parent=False)
self.add_node(node1, node2, level[1], None, add_parent=False)
self.add_node(node2, node3, level[2], None, add_parent=False)
self.add_node(node3, handle, sort_key, handle, add_parent=False)
else:
self.add_node(None, node1, level[0], None, add_parent=False)
self.add_node(node1, node2, level[1], None, add_parent=False)
self.add_node(node2, node3, level[2], None, add_parent=False)
self.add_node(node3, handle, sort_key, handle, add_parent=False)
def column_name(self, data):
name = ''
if data[5] is not None:
level = [data[5][0][i] for i in range(5,-1,-1)]
if not (level[3] or level[4] or level[5]):
name = cuni(level[2] or level[1] or level[0])
else:
name = ', '.join([item for item in level[3:] if item])
if not name:
name = cuni(data[2])
if name:
return cgi.escape(name)
else: else:
return "<i>%s<i>" % cgi.escape(_("<no name>")) parent = None
def column_header(self, node): # Add the node as a root node if the parent is not in the tree. This
""" # will happen when the view is filtered.
Return a column heading. This is called for nodes with no associated if not self._get_node(parent):
Gramps handle. parent = None
"""
if node.name: self.add_node(parent, handle, sort_key, handle, add_parent=False)
return '<i>%s</i>' % cgi.escape(node.name)
else: def column_header(self, data):
level = len(self.do_get_path(self._get_iter(node)).get_indices()) # should not get here!
heading = '<i>%s</i>' % cgi.escape(COUNTRYLEVELS['default'][level]) return '????'
# This causes a problem with Gtk3 unless we cast to str.
return str(heading)

View File

@ -44,7 +44,10 @@ import io
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
from gramps.gen.const import GRAMPS_LOCALE as glocale from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext _ = glocale.translation.gettext
from gramps.gen.lib import AttributeType, ChildRefType, Citation, Date, EventRoleType, EventType, LdsOrd, NameType, NoteType, Person, UrlType, SrcAttributeType from gramps.gen.lib import (AttributeType, ChildRefType, Citation, Date,
EventRoleType, EventType, LdsOrd, NameType,
PlaceType, NoteType, Person, UrlType,
SrcAttributeType)
from gramps.version import VERSION from gramps.version import VERSION
import gramps.plugins.lib.libgedcom as libgedcom import gramps.plugins.lib.libgedcom as libgedcom
from gramps.gen.errors import DatabaseError from gramps.gen.errors import DatabaseError
@ -53,6 +56,7 @@ from gramps.gen.updatecallback import UpdateCallback
from gramps.gen.utils.file import media_path_full from gramps.gen.utils.file import media_path_full
from gramps.gen.utils.place import conv_lat_lon from gramps.gen.utils.place import conv_lat_lon
from gramps.gen.constfunc import cuni from gramps.gen.constfunc import cuni
from gramps.gen.utils.location import get_main_location
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
@ -1373,23 +1377,28 @@ class GedcomWriter(UpdateCallback):
# The Gedcom standard shows that an optional address structure can # The Gedcom standard shows that an optional address structure can
# be written out in the event detail. # be written out in the event detail.
# http://homepages.rootsweb.com/~pmcbride/gedcom/55gcch2.htm#EVENT_DETAIL # http://homepages.rootsweb.com/~pmcbride/gedcom/55gcch2.htm#EVENT_DETAIL
location = place.get_main_location() location = get_main_location(self.dbase, place)
if location and not location.is_empty(): street = location.get(PlaceType.STREET)
self._writeln(level, "ADDR", location.get_street()) locality = location.get(PlaceType.LOCALITY)
if location.get_street(): city = location.get(PlaceType.CITY)
self._writeln(level + 1, 'ADR1', location.get_street()) state = location.get(PlaceType.STATE)
if location.get_locality(): country = location.get(PlaceType.COUNTRY)
self._writeln(level + 1, 'ADR2', location.get_locality()) postal_code = place.get_code()
if location.get_city():
self._writeln(level + 1, 'CITY', location.get_city()) if (street or locality or city or state or postal_code or country):
if location.get_state(): self._writeln(level, "ADDR", street)
self._writeln(level + 1, 'STAE', location.get_state()) if street:
if location.get_postal_code(): self._writeln(level + 1, 'ADR1', street)
self._writeln(level + 1, 'POST', location.get_postal_code()) if locality:
if location.get_country(): self._writeln(level + 1, 'ADR2', locality)
self._writeln(level + 1, 'CTRY', location.get_country()) if city:
if location.get_phone(): self._writeln(level + 1, 'CITY', city)
self._writeln(level, 'PHON', location.get_phone()) if state:
self._writeln(level + 1, 'STAE', state)
if postal_code:
self._writeln(level + 1, 'POST', postal_code)
if country:
self._writeln(level + 1, 'CTRY', country)
self._note_references(place.get_note_list(), level+1) self._note_references(place.get_note_list(), level+1)

View File

@ -718,6 +718,16 @@ class GrampsXmlWriter(UpdateCallback):
self.write_note_list(note_list,index+1) self.write_note_list(note_list,index+1)
self.g.write('%s</eventref>\n' % sp) self.g.write('%s</eventref>\n' % sp)
def dump_place_ref(self, placeref, index=1):
sp = " " * index
date = placeref.get_date_object()
if date.is_empty():
self.write_ref('placeref', placeref.ref, index, close=True)
else:
self.write_ref('placeref', placeref.ref, index, close=False)
self.write_date(date, index+1)
self.g.write('%s</placeref>\n' % sp)
def write_event(self,event,index=1): def write_event(self,event,index=1):
if not event: if not event:
return return
@ -1185,25 +1195,21 @@ class GrampsXmlWriter(UpdateCallback):
self.write_primary_tag("placeobj", place, index) self.write_primary_tag("placeobj", place, index)
title = self.fix(place.get_title()) title = self.fix(place.get_title())
name = self.fix(place.get_name())
ptype = self.fix(place.get_type().xml_str())
code = self.fix(place.get_code())
self.write_line_nofix("ptitle", title, index+1)
self.write_line_nofix("pname", name, index+1)
self.write_line_nofix("type", ptype, index+1)
self.write_line_nofix("code", code, index+1)
longitude = self.fix(place.get_longitude()) longitude = self.fix(place.get_longitude())
lat = self.fix(place.get_latitude()) lat = self.fix(place.get_latitude())
main_loc = place.get_main_location()
llen = (len(place.get_alternate_locations()) +
len(place.get_url_list()) +
len(place.get_media_list()) +
len(place.get_citation_list())
)
ml_empty = main_loc.is_empty()
if title == "":
title = self.build_place_title(place.get_main_location())
self.write_line_nofix("ptitle", title, index+1)
if longitude or lat: if longitude or lat:
self.g.write('%s<coord long="%s" lat="%s"/>\n' self.g.write('%s<coord long="%s" lat="%s"/>\n'
% (" "*(index+1), longitude, lat)) % (" "*(index+1), longitude, lat))
self.dump_location(main_loc) for placeref in place.get_placeref_list():
self.dump_place_ref(placeref, index+1)
list(map(self.dump_location, place.get_alternate_locations())) list(map(self.dump_location, place.get_alternate_locations()))
self.write_media_list(place.get_media_list(), index+1) self.write_media_list(place.get_media_list(), index+1)
self.write_url_list(place.get_url_list()) self.write_url_list(place.get_url_list())

View File

@ -25,6 +25,7 @@ from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext _ = glocale.translation.gettext
from gramps.gen.utils.place import conv_lat_lon from gramps.gen.utils.place import conv_lat_lon
from gramps.gen.utils.file import media_path_full from gramps.gen.utils.file import media_path_full
from gramps.gen.utils.location import get_location_list
from gi.repository import Gtk from gi.repository import Gtk
from gi.repository import Pango from gi.repository import Pango
@ -108,7 +109,7 @@ class PlaceDetails(Gramplet):
self.title.set_text(place.get_title()) self.title.set_text(place.get_title())
self.clear_table() self.clear_table()
self.display_location(place.get_main_location()) self.display_location(place)
self.display_separator() self.display_separator()
lat, lon = conv_lat_lon(place.get_latitude(), lat, lon = conv_lat_lon(place.get_latitude(),
place.get_longitude(), place.get_longitude(),
@ -118,11 +119,11 @@ class PlaceDetails(Gramplet):
if lon: if lon:
self.add_row(_('Longitude'), lon) self.add_row(_('Longitude'), lon)
def display_location(self, location): def display_location(self, place):
""" """
Display a location. Display a location.
""" """
lines = [line for line in location.get_text_data_list()[:-1] if line] lines = get_location_list(self.dbstate.db, place)
self.add_row(_('Location'), '\n'.join(lines)) self.add_row(_('Location'), '\n'.join(lines))
def display_empty(self): def display_empty(self):

View File

@ -53,7 +53,7 @@ log = logging.getLogger(".FamilyLines")
#------------------------------------------------------------------------ #------------------------------------------------------------------------
from gramps.gen.const import GRAMPS_LOCALE as glocale from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.gettext _ = glocale.translation.gettext
from gramps.gen.lib import EventRoleType, EventType, Person from gramps.gen.lib import EventRoleType, EventType, Person, PlaceType
from gramps.gen.utils.file import media_path_full from gramps.gen.utils.file import media_path_full
from gramps.gui.thumbnails import get_thumbnail_path from gramps.gui.thumbnails import get_thumbnail_path
from gramps.gen.plug.report import Report from gramps.gen.plug.report import Report
@ -65,6 +65,7 @@ from gramps.gen.plug.menu import (NumberOption, ColorOption, BooleanOption,
SurnameColorOption) SurnameColorOption)
from gramps.gen.utils.db import get_birth_or_fallback, get_death_or_fallback from gramps.gen.utils.db import get_birth_or_fallback, get_death_or_fallback
from gramps.gen.display.name import displayer as global_name_display from gramps.gen.display.name import displayer as global_name_display
from gramps.gen.utils.location import get_main_location
#------------------------------------------------------------------------ #------------------------------------------------------------------------
# #
@ -772,13 +773,13 @@ class FamilyLinesReport(Report):
if not bth_event.private or self._incprivate: if not bth_event.private or self._incprivate:
place = self._db.get_place_from_handle(bth_event.get_place_handle()) place = self._db.get_place_from_handle(bth_event.get_place_handle())
if place: if place:
location = place.get_main_location() location = get_main_location(self._db, place)
if location.get_city: if location.get(PlaceType.CITY):
birthplace = location.get_city() birthplace = location.get(PlaceType.CITY)
elif location.get_state: elif location.get(PlaceType.STATE):
birthplace = location.get_state() birthplace = location.get(PlaceType.STATE)
elif location.get_country: elif location.get(PlaceType.COUNTRY):
birthplace = location.get_country() birthplace = location.get(PlaceType.COUNTRY)
# see if we have a deceased date we can use # see if we have a deceased date we can use
deathStr = None deathStr = None
@ -796,13 +797,13 @@ class FamilyLinesReport(Report):
if not dth_event.private or self._incprivate: if not dth_event.private or self._incprivate:
place = self._db.get_place_from_handle(dth_event.get_place_handle()) place = self._db.get_place_from_handle(dth_event.get_place_handle())
if place: if place:
location = place.get_main_location() location = get_main_location(self._db, place)
if location.get_city: if location.get(PlaceType.CITY):
deathplace = location.get_city() deathplace = location.get(PlaceType.CITY)
elif location.get_state: elif location.get(PlaceType.STATE):
deathplace = location.get_state() deathplace = location.get(PlaceType.STATE)
elif location.get_country: elif location.get(PlaceType.COUNTRY):
deathplace = location.get_country() deathplace = location.get(PlaceType.COUNTRY)
# see if we have an image to use for this person # see if we have an image to use for this person
imagePath = None imagePath = None
@ -920,13 +921,13 @@ class FamilyLinesReport(Report):
if self._incplaces: if self._incplaces:
place = self._db.get_place_from_handle(event.get_place_handle()) place = self._db.get_place_from_handle(event.get_place_handle())
if place: if place:
location = place.get_main_location() location = get_main_location(self._db, place)
if location.get_city: if location.get(PlaceType.CITY):
weddingPlace = location.get_city() weddingPlace = location.get(PlaceType.CITY)
elif location.get_state: elif location.get(PlaceType.STATE):
weddingPlace = location.get_state() weddingPlace = location.get(PlaceType.STATE)
elif location.get_country: elif location.get(PlaceType.COUNTRY):
weddingPlace = location.get_country() weddingPlace = location.get(PlaceType.COUNTRY)
break break
# figure out the number of children (if any) # figure out the number of children (if any)

View File

@ -53,9 +53,9 @@ from gramps.gen.lib import (Address, Attribute, AttributeType, ChildRef,
MediaObject, MediaRef, Name, NameOriginType, MediaObject, MediaRef, Name, NameOriginType,
NameType, Note, NoteType, Person, PersonRef, NameType, Note, NoteType, Person, PersonRef,
Place, RepoRef, Repository, Researcher, Source, Place, RepoRef, Repository, Researcher, Source,
SrcAttribute, SrcAttributeType, SrcAttribute, SrcAttributeType, PlaceType,
StyledText, StyledTextTag, StyledTextTagType, StyledText, StyledTextTag, StyledTextTagType,
Surname, Tag, Url) Surname, Tag, Url, PlaceRef)
from gramps.gen.db import DbTxn from gramps.gen.db import DbTxn
from gramps.gen.db.write import CLASS_TO_KEY_MAP from gramps.gen.db.write import CLASS_TO_KEY_MAP
from gramps.gen.errors import GrampsImportError from gramps.gen.errors import GrampsImportError
@ -75,6 +75,7 @@ from gramps.gen.config import config
#import gramps.plugins.lib.libgrampsxml #import gramps.plugins.lib.libgrampsxml
from gramps.plugins.lib import libgrampsxml from gramps.plugins.lib import libgrampsxml
from gramps.gen.plug.utils import version_str_to_tup from gramps.gen.plug.utils import version_str_to_tup
from gramps.plugins.lib.libplaceimport import PlaceImport
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
@ -542,6 +543,7 @@ class GrampsParser(UpdateCallback):
self.placeobj = None self.placeobj = None
self.locations = 0 self.locations = 0
self.place_map = {} self.place_map = {}
self.place_import = PlaceImport(self.db)
self.resname = "" self.resname = ""
self.resaddr = "" self.resaddr = ""
@ -650,6 +652,7 @@ class GrampsParser(UpdateCallback):
"phone": (None, self.stop_phone), "phone": (None, self.stop_phone),
"date": (None, self.stop_date), "date": (None, self.stop_date),
"cause": (None, self.stop_cause), "cause": (None, self.stop_cause),
"code": (None, self.stop_code),
"description": (None, self.stop_description), "description": (None, self.stop_description),
"event": (self.start_event, self.stop_event), "event": (self.start_event, self.stop_event),
"type": (None, self.stop_type), "type": (None, self.stop_type),
@ -684,6 +687,8 @@ class GrampsParser(UpdateCallback):
"datestr": (self.start_datestr, None), "datestr": (self.start_datestr, None),
"places": (None, self.stop_places), "places": (None, self.stop_places),
"placeobj": (self.start_placeobj, self.stop_placeobj), "placeobj": (self.start_placeobj, self.stop_placeobj),
"placeref": (self.start_placeref, self.stop_placeref),
"pname": (None, self.stop_pname),
"ptitle": (None, self.stop_ptitle), "ptitle": (None, self.stop_ptitle),
"location": (self.start_location, None), "location": (self.start_location, None),
"lds_ord": (self.start_lds_ord, self.stop_lds_ord), "lds_ord": (self.start_lds_ord, self.stop_lds_ord),
@ -1166,11 +1171,32 @@ class GrampsParser(UpdateCallback):
loc.country = attrs.get('country', '') loc.country = attrs.get('country', '')
loc.postal = attrs.get('postal', '') loc.postal = attrs.get('postal', '')
loc.phone = attrs.get('phone', '') loc.phone = attrs.get('phone', '')
if self.locations > 0:
self.placeobj.add_alternate_locations(loc) if self.__xml_version < (1, 6, 0):
if self.locations > 0:
self.placeobj.add_alternate_locations(loc)
else:
location = (attrs.get('street', ''),
attrs.get('locality', ''),
attrs.get('parish', ''),
attrs.get('city', ''),
attrs.get('county', ''),
attrs.get('state', ''),
attrs.get('country', ''))
self.place_import.store_location(location, self.placeobj.handle)
for type_num, name in enumerate(location):
if name:
break
self.placeobj.set_name(name)
self.placeobj.set_type(PlaceType(7-type_num))
codes = [attrs.get('postal'), attrs.get('phone')]
self.placeobj.set_code(' '.join(code for code in codes if code))
else: else:
self.placeobj.set_main_location(loc) self.placeobj.add_alternate_locations(loc)
self.locations = self.locations + 1
self.locations = self.locations + 1
def start_witness(self, attrs): def start_witness(self, attrs):
""" """
@ -1293,6 +1319,15 @@ class GrampsParser(UpdateCallback):
else: else:
self.person.add_event_ref(self.eventref) self.person.add_event_ref(self.eventref)
def start_placeref(self, attrs):
"""
Add a place reference to the place currently being processed.
"""
self.placeref = PlaceRef()
handle = self.inaugurate(attrs['hlink'], "place", Place)
self.placeref.ref = handle
self.placeobj.add_placeref(self.placeref)
def start_attribute(self, attrs): def start_attribute(self, attrs):
self.attribute = Attribute() self.attribute = Attribute()
self.attribute.private = bool(attrs.get("priv")) self.attribute.private = bool(attrs.get("priv"))
@ -2279,8 +2314,10 @@ class GrampsParser(UpdateCallback):
date_value = self.address.get_date_object() date_value = self.address.get_date_object()
elif self.name: elif self.name:
date_value = self.name.get_date_object() date_value = self.name.get_date_object()
else: elif self.event:
date_value = self.event.get_date_object() date_value = self.event.get_date_object()
else:
date_value = self.placeref.get_date_object()
start = attrs['start'].split('-') start = attrs['start'].split('-')
stop = attrs['stop'].split('-') stop = attrs['stop'].split('-')
@ -2361,8 +2398,10 @@ class GrampsParser(UpdateCallback):
date_value = self.address.get_date_object() date_value = self.address.get_date_object()
elif self.name: elif self.name:
date_value = self.name.get_date_object() date_value = self.name.get_date_object()
else: elif self.event:
date_value = self.event.get_date_object() date_value = self.event.get_date_object()
else:
date_value = self.placeref.get_date_object()
bce = 1 bce = 1
val = attrs['val'] val = attrs['val']
@ -2440,8 +2479,10 @@ class GrampsParser(UpdateCallback):
date_value = self.address.get_date_object() date_value = self.address.get_date_object()
elif self.name: elif self.name:
date_value = self.name.get_date_object() date_value = self.name.get_date_object()
else: elif self.event:
date_value = self.event.get_date_object() date_value = self.event.get_date_object()
else:
date_value = self.placeref.get_date_object()
date_value.set_as_text(attrs['val']) date_value.set_as_text(attrs['val'])
@ -2498,6 +2539,9 @@ class GrampsParser(UpdateCallback):
def stop_places(self, *tag): def stop_places(self, *tag):
self.placeobj = None self.placeobj = None
if self.__xml_version < (1, 6, 0):
self.place_import.generate_hierarchy(self.trans)
def stop_photo(self, *tag): def stop_photo(self, *tag):
self.photo = None self.photo = None
@ -2505,11 +2549,13 @@ class GrampsParser(UpdateCallback):
def stop_ptitle(self, tag): def stop_ptitle(self, tag):
self.placeobj.title = tag self.placeobj.title = tag
def stop_placeobj(self, *tag): def stop_pname(self, tag):
if self.placeobj.title == "": self.placeobj.name = tag
loc = self.placeobj.get_main_location()
self.placeobj.title = build_place_title(loc)
def stop_code(self, tag):
self.placeobj.code = tag
def stop_placeobj(self, *tag):
self.db.commit_place(self.placeobj, self.trans, self.db.commit_place(self.placeobj, self.trans,
self.placeobj.get_change_time()) self.placeobj.get_change_time())
self.placeobj = None self.placeobj = None
@ -2526,6 +2572,9 @@ class GrampsParser(UpdateCallback):
elif self.repo: elif self.repo:
# Repository type # Repository type
self.repo.type.set_from_xml_str(tag) self.repo.type.set_from_xml_str(tag)
elif self.placeobj:
# Place type
self.placeobj.place_type.set_from_xml_str(tag)
def stop_childref(self, tag): def stop_childref(self, tag):
self.childref = None self.childref = None
@ -2536,6 +2585,9 @@ class GrampsParser(UpdateCallback):
def stop_eventref(self, tag): def stop_eventref(self, tag):
self.eventref = None self.eventref = None
def stop_placeref(self, tag):
self.placeref = None
def stop_event(self, *tag): def stop_event(self, *tag):
if self.family: if self.family:
ref = EventRef() ref = EventRef()

View File

@ -131,7 +131,7 @@ from gramps.gen.lib import (Address, Attribute, AttributeType, ChildRef,
MediaRef, Name, NameType, Note, NoteType, Person, PersonRef, Place, MediaRef, Name, NameType, Note, NoteType, Person, PersonRef, Place,
RepoRef, Repository, RepositoryType, Researcher, RepoRef, Repository, RepositoryType, Researcher,
Source, SourceMediaType, SrcAttribute, SrcAttributeType, Source, SourceMediaType, SrcAttribute, SrcAttributeType,
Surname, Tag, Url, UrlType) Surname, Tag, Url, UrlType, PlaceType, PlaceRef)
from gramps.gen.db import DbTxn from gramps.gen.db import DbTxn
from gramps.gen.updatecallback import UpdateCallback from gramps.gen.updatecallback import UpdateCallback
from gramps.gen.mime import get_type from gramps.gen.mime import get_type
@ -144,6 +144,7 @@ from gramps.gui.dialog import WarningDialog
from gramps.gen.lib.const import IDENTICAL, DIFFERENT from gramps.gen.lib.const import IDENTICAL, DIFFERENT
from gramps.gen.lib import (StyledText, StyledTextTag, StyledTextTagType) from gramps.gen.lib import (StyledText, StyledTextTag, StyledTextTagType)
from gramps.gen.constfunc import cuni, conv_to_unicode, STRTYPE, UNITYPE from gramps.gen.constfunc import cuni, conv_to_unicode, STRTYPE, UNITYPE
from gramps.plugins.lib.libplaceimport import PlaceImport
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
@ -1661,7 +1662,7 @@ class PlaceParser(object):
fcn = self.__field_map.get(item, lambda x, y: None) fcn = self.__field_map.get(item, lambda x, y: None)
self.parse_function.append(fcn) self.parse_function.append(fcn)
def load_place(self, place, text): def load_place(self, place_import, place, text):
""" """
Takes the text string representing a place, splits it into Takes the text string representing a place, splits it into
its subcomponents (comma separated), and calls the approriate its subcomponents (comma separated), and calls the approriate
@ -1671,12 +1672,31 @@ class PlaceParser(object):
items = [item.strip() for item in text.split(',')] items = [item.strip() for item in text.split(',')]
if len(items) != len(self.parse_function): if len(items) != len(self.parse_function):
return return
loc = place.get_main_location()
index = 0 index = 0
loc = Location()
for item in items: for item in items:
self.parse_function[index](loc, item) self.parse_function[index](loc, item)
index += 1 index += 1
location = (loc.get_street(),
loc.get_locality(),
loc.get_parish(),
loc.get_city(),
loc.get_county(),
loc.get_state(),
loc.get_country())
place_import.store_location(location, place.handle)
for type_num, name in enumerate(location):
if name:
break
place.set_name(name)
place.set_type(PlaceType(7-type_num))
code = loc.get_postal_code()
place.set_code(code)
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
# IdFinder # IdFinder
@ -1908,6 +1928,8 @@ class GedcomParser(UpdateCallback):
self.rid2id = {} self.rid2id = {}
self.nid2id = {} self.nid2id = {}
self.place_import = PlaceImport(self.dbase)
# #
# Parse table for <<SUBMITTER_RECORD>> below the level 0 SUBM tag # Parse table for <<SUBMITTER_RECORD>> below the level 0 SUBM tag
# #
@ -2675,6 +2697,8 @@ class GedcomParser(UpdateCallback):
self.dbase.add_source(src, self.trans) self.dbase.add_source(src, self.trans)
self.__clean_up() self.__clean_up()
self.place_import.generate_hierarchy(self.trans)
if not self.dbase.get_feature("skip-check-xref"): if not self.dbase.get_feature("skip-check-xref"):
self.__check_xref() self.__check_xref()
self.dbase.enable_signals() self.dbase.enable_signals()
@ -4370,7 +4394,8 @@ class GedcomParser(UpdateCallback):
state.msg += sub_state.msg state.msg += sub_state.msg
if sub_state.place: if sub_state.place:
sub_state.place_fields.load_place(sub_state.place, sub_state.place_fields.load_place(self.place_import,
sub_state.place,
sub_state.place.get_title()) sub_state.place.get_title())
def __lds_temple(self, line, state): def __lds_temple(self, line, state):
@ -4929,7 +4954,8 @@ class GedcomParser(UpdateCallback):
state.msg += sub_state.msg state.msg += sub_state.msg
if sub_state.place: if sub_state.place:
sub_state.place_fields.load_place(sub_state.place, sub_state.place_fields.load_place(self.place_import,
sub_state.place,
sub_state.place.get_title()) sub_state.place.get_title())
def __family_source(self, line, state): def __family_source(self, line, state):
@ -5236,7 +5262,6 @@ class GedcomParser(UpdateCallback):
@type state: CurrentState @type state: CurrentState
""" """
location = None
if self.is_ftw and state.event.type in FTW_BAD_PLACE: if self.is_ftw and state.event.type in FTW_BAD_PLACE:
state.event.set_description(line.data) state.event.set_description(line.data)
else: else:
@ -5247,9 +5272,6 @@ class GedcomParser(UpdateCallback):
place_handle = state.event.get_place_handle() place_handle = state.event.get_place_handle()
if place_handle: if place_handle:
place = self.dbase.get_place_from_handle(place_handle) place = self.dbase.get_place_from_handle(place_handle)
location = place.get_main_location()
empty_loc = Location()
place.set_main_location(empty_loc)
else: else:
place = self.__find_or_create_place(line.data) place = self.__find_or_create_place(line.data)
place.set_title(line.data) place.set_title(line.data)
@ -5258,20 +5280,14 @@ class GedcomParser(UpdateCallback):
sub_state = CurrentState() sub_state = CurrentState()
sub_state.place = place sub_state.place = place
sub_state.level = state.level+1 sub_state.level = state.level+1
sub_state.pf = self.place_parser sub_state.pf = PlaceParser()
self.__parse_level(sub_state, self.event_place_map, self.__parse_level(sub_state, self.event_place_map,
self.__undefined) self.__undefined)
state.msg += sub_state.msg state.msg += sub_state.msg
sub_state.pf.load_place(place, place.get_title()) sub_state.pf.load_place(self.place_import, place, place.get_title())
# If we already had a remembered location, we set it into the main
# location if that is empty, else the alternate location
if location and not location.is_empty():
if place.get_main_location().is_empty():
place.set_main_location(location)
else:
place.add_alternate_locations(location)
self.dbase.commit_place(place, self.trans) self.dbase.commit_place(place, self.trans)
def __event_place_note(self, line, state): def __event_place_note(self, line, state):
@ -5393,7 +5409,6 @@ class GedcomParser(UpdateCallback):
place_handle = place.handle place_handle = place.handle
self.__add_location(place, location) self.__add_location(place, location)
# place.set_main_location(location)
list(map(place.add_note, note_list)) list(map(place.add_note, note_list))
@ -5407,19 +5422,11 @@ class GedcomParser(UpdateCallback):
@param location: A location we want to add to this place @param location: A location we want to add to this place
@type location: gen.lib.location @type location: gen.lib.location
""" """
# If there is no main location, we add the location for loc in place.get_alternate_locations():
if place.main_loc is None: if loc.is_equivalent(location) == IDENTICAL:
place.set_main_location(location) return
elif place.get_main_location().is_equivalent(location) == IDENTICAL: place.add_alternate_locations(location)
# the location is already present as the main location
pass
else:
for loc in place.get_alternate_locations():
if loc.is_equivalent(location) == IDENTICAL:
return
place.add_alternate_locations(location)
def __event_phon(self, line, state): def __event_phon(self, line, state):
""" """
@param line: The current line in GedLine format @param line: The current line in GedLine format
@ -5430,8 +5437,8 @@ class GedcomParser(UpdateCallback):
place_handle = state.event.get_place_handle() place_handle = state.event.get_place_handle()
if place_handle: if place_handle:
place = self.dbase.get_place_from_handle(place_handle) place = self.dbase.get_place_from_handle(place_handle)
location = place.get_main_location() codes = [place.get_code(), line.data]
location.set_phone(line.data) place.set_code(' '.join(code for code in codes if code))
self.dbase.commit_place(place, self.trans) self.dbase.commit_place(place, self.trans)
def __event_privacy(self, line, state): def __event_privacy(self, line, state):

View File

@ -0,0 +1,110 @@
#
# Gramps - a GTK+/GNOME based genealogy program
#
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# $Id$
"""
Helper class for importing places.
"""
#-------------------------------------------------------------------------
#
# GRAMPS modules
#
#-------------------------------------------------------------------------
from gramps.gen.lib import Place, PlaceType, PlaceRef
#-------------------------------------------------------------------------
#
# PlaceImport class
#
#-------------------------------------------------------------------------
class PlaceImport(object):
"""
Helper class for importing places.
"""
def __init__(self, db):
self.db = db
self.loc2handle = {}
self.handle2loc = {}
def store_location(self, location, handle):
"""
Store the location of a place already in the database.
"""
self.loc2handle[location] = handle
self.handle2loc[handle] = location
def generate_hierarchy(self, trans):
"""
Generate missing places in the place hierarchy.
"""
for handle, location in self.handle2loc.iteritems():
# find title and type
for type_num, name in enumerate(location):
if name:
break
loc = list(location)
loc[type_num] = ''
# find top parent
parent = None
for n in range(7):
if loc[n]:
tup = tuple([''] * n + loc[n:])
parent = self.loc2handle.get(tup)
if parent:
break
# create missing parent places
if parent:
n -= 1
while n > type_num:
if loc[n]:
title = ', '.join([item for item in loc[n:] if item])
parent = self.__add_place(loc[n], n, parent, title, trans)
self.loc2handle[tuple([''] * n + loc[n:])] = parent
n -= 1
# link to existing place
if parent:
place = self.db.get_place_from_handle(handle)
placeref = PlaceRef()
placeref.ref = parent
place.set_placeref_list([placeref])
self.db.commit_place(place, trans, place.get_change_time())
def __add_place(self, name, type_num, parent, title, trans):
"""
Add a missing place to the database.
"""
place = Place()
place.name = name
place.title = title
place.place_type = PlaceType(7-type_num)
if parent is not None:
placeref = PlaceRef()
placeref.ref = parent
place.set_placeref_list([placeref])
handle = self.db.add_place(place, trans)
self.db.commit_place(place, trans)
return handle

View File

@ -47,7 +47,7 @@ from gi.repository import Gtk
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
from gramps.gen.lib import Place from gramps.gen.lib import Place
from gramps.gui.views.listview import ListView, TEXT, MARKUP, ICON from gramps.gui.views.listview import ListView, TEXT, ICON
from gramps.gui.widgets.menuitem import add_menuitem from gramps.gui.widgets.menuitem import add_menuitem
from gramps.gen.errors import WindowActiveError from gramps.gen.errors import WindowActiveError
from gramps.gui.views.bookmarks import PlaceBookmarks from gramps.gui.views.bookmarks import PlaceBookmarks
@ -79,31 +79,21 @@ class PlaceBaseView(ListView):
""" """
COL_NAME = 0 COL_NAME = 0
COL_ID = 1 COL_ID = 1
COL_STREET = 2 COL_TITLE = 2
COL_LOCALITY = 3 COL_TYPE = 3
COL_CITY = 4 COL_CODE = 4
COL_COUNTY = 5 COL_LAT = 5
COL_STATE = 6 COL_LON = 6
COL_COUNTRY = 7 COL_PRIV = 7
COL_ZIP = 8 COL_TAGS = 8
COL_PARISH = 9 COL_CHAN = 9
COL_LAT = 10
COL_LON = 11
COL_PRIV = 12
COL_TAGS = 13
COL_CHAN = 14
# column definitions # column definitions
COLUMNS = [ COLUMNS = [
(_('Place Name'), MARKUP, None), (_('Name'), TEXT, None),
(_('ID'), TEXT, None), (_('ID'), TEXT, None),
(_('Street'), TEXT, None), (_('Title'), TEXT, None),
(_('Locality'), TEXT, None), (_('Type'), TEXT, None),
(_('City'), TEXT, None), (_('Code'), TEXT, None),
(_('County'), TEXT, None),
(_('State'), TEXT, None),
(_('Country'), TEXT, None),
(_('ZIP/Postal Code'), TEXT, None),
(_('Church Parish'), TEXT, None),
(_('Latitude'), TEXT, None), (_('Latitude'), TEXT, None),
(_('Longitude'), TEXT, None), (_('Longitude'), TEXT, None),
(_('Private'), ICON, 'gramps-lock'), (_('Private'), ICON, 'gramps-lock'),
@ -112,14 +102,10 @@ class PlaceBaseView(ListView):
] ]
# default setting with visible columns, order of the col, and their size # default setting with visible columns, order of the col, and their size
CONFIGSETTINGS = ( CONFIGSETTINGS = (
('columns.visible', [COL_NAME, COL_ID, COL_STREET, COL_LOCALITY, ('columns.visible', [COL_TITLE, COL_ID, COL_TYPE, COL_CODE]),
COL_CITY, COL_COUNTY, COL_STATE]), ('columns.rank', [COL_NAME, COL_TITLE, COL_ID, COL_TYPE, COL_CODE,
('columns.rank', [COL_NAME, COL_ID, COL_STREET, COL_LOCALITY, COL_CITY, COL_LAT, COL_LON, COL_PRIV, COL_TAGS, COL_CHAN]),
COL_COUNTY, COL_STATE, COL_COUNTRY, COL_ZIP, ('columns.size', [250, 250, 75, 100, 100, 150, 150, 40, 100, 100])
COL_PARISH, COL_LAT, COL_LON, COL_PRIV, COL_TAGS,
COL_CHAN]),
('columns.size', [250, 75, 150, 150, 150, 150, 100, 100, 100,
100, 150, 150, 40, 100, 100])
) )
ADD_MSG = _("Add a new place") ADD_MSG = _("Add a new place")
EDIT_MSG = _("Edit the selected place") EDIT_MSG = _("Edit the selected place")
@ -380,7 +366,14 @@ class PlaceBaseView(ListView):
pass pass
def remove(self, obj): def remove(self, obj):
self.remove_selected_objects() for handle in self.selected_handles():
for link in self.dbstate.db.find_backlink_handles(handle,['Place']):
msg = _("Cannot delete place.")
msg2 = _("This place is currently referenced by another place. "
"First remove the places it contains.")
ErrorDialog(msg, msg2)
return
self.remove_selected_objects()
def remove_object_from_handle(self, handle): def remove_object_from_handle(self, handle):
person_list = [ person_list = [
@ -423,7 +416,15 @@ class PlaceBaseView(ListView):
"control key while clicking on the desired place.") "control key while clicking on the desired place.")
ErrorDialog(msg, msg2) ErrorDialog(msg, msg2)
else: else:
MergePlace(self.dbstate, self.uistate, mlist[0], mlist[1]) MergePlace(self.dbstate, self.uistate, mlist[0], mlist[1],
self.merged)
def merged(self):
"""
Rebuild the model after a merge to reflect changes in the hierarchy.
"""
if not (self.model.get_flags() & Gtk.TreeModelFlags.LIST_ONLY):
self.build_tree()
def get_handle_from_gramps_id(self, gid): def get_handle_from_gramps_id(self, gid):
obj = self.dbstate.db.get_place_from_gramps_id(gid) obj = self.dbstate.db.get_place_from_gramps_id(gid)

View File

@ -41,9 +41,10 @@ from __future__ import print_function
#------------------------------------------------------------------------ #------------------------------------------------------------------------
from gramps.gen.display.name import displayer as name_displayer from gramps.gen.display.name import displayer as name_displayer
from gramps.gen.datehandler import displayer from gramps.gen.datehandler import displayer
from gramps.gen.lib import EventType from gramps.gen.lib import EventType, PlaceType, Location
from gramps.gen.utils.db import get_birth_or_fallback, get_death_or_fallback from gramps.gen.utils.db import get_birth_or_fallback, get_death_or_fallback
from gramps.gen.constfunc import STRTYPE, cuni from gramps.gen.constfunc import STRTYPE, cuni
from gramps.gen.utils.location import get_main_location
#------------------------------------------------------------------------ #------------------------------------------------------------------------
@ -159,7 +160,7 @@ class NameFormat(GenericFormat):
def parse_format(self, name): def parse_format(self, name):
""" Parse the name """ """ Parse the name """
if self.is_blank(name): if self.is_blank(name):
return return
def common(): def common():
""" return the common name of the person """ """ return the common name of the person """
@ -310,7 +311,7 @@ class PlaceFormat(GenericFormat):
def _default_format(self, place): def _default_format(self, place):
return place.get_title() return place.get_title()
def parse_format(self, place): def parse_format(self, database, place):
""" Parse the place """ """ Parse the place """
if self.is_blank(place): if self.is_blank(place):
@ -318,16 +319,28 @@ class PlaceFormat(GenericFormat):
code = "elcuspn" + "oitxy" code = "elcuspn" + "oitxy"
upper = code.upper() upper = code.upper()
function = [place.get_main_location().get_street,
place.get_main_location().get_locality, main_loc = get_main_location(database, place)
place.get_main_location().get_city, location = Location()
place.get_main_location().get_county, location.set_street(main_loc.get(PlaceType.STREET, ''))
place.get_main_location().get_state, location.set_locality(main_loc.get(PlaceType.LOCALITY, ''))
place.get_main_location().get_postal_code, location.set_parish(main_loc.get(PlaceType.PARISH, ''))
place.get_main_location().get_country, location.set_city(main_loc.get(PlaceType.CITY, ''))
location.set_county(main_loc.get(PlaceType.COUNTY, ''))
location.set_state(main_loc.get(PlaceType.STATE, ''))
location.set_postal_code(main_loc.get(PlaceType.STREET, ''))
location.set_country(main_loc.get(PlaceType.COUNTRY, ''))
place.get_main_location().get_phone, function = [location.get_street,
place.get_main_location().get_parish, location.get_locality,
location.get_city,
location.get_county,
location.get_state,
place.get_code,
location.get_country,
location.get_phone,
location.get_parish,
place.get_title, place.get_title,
place.get_longitude, place.get_longitude,
place.get_latitude place.get_latitude
@ -382,7 +395,7 @@ class EventFormat(GenericFormat):
""" start formatting a place in this event """ """ start formatting a place in this event """
place_format = PlaceFormat(self.string_in) place_format = PlaceFormat(self.string_in)
place = place_format.get_place(self.database, event) place = place_format.get_place(self.database, event)
return place_format.parse_format(place) return place_format.parse_format(self.database, place)
def format_attrib(): def format_attrib():
""" Get the name and then get the attributes value """ """ Get the name and then get the attributes value """
@ -839,7 +852,7 @@ class VariableParse(object):
place = place_f.get_place(self.database, event) place = place_f.get_place(self.database, event)
if self.empty_item(place): if self.empty_item(place):
return return
return place_f.parse_format(place) return place_f.parse_format(self.database, place)
def __parse_name(self, person): def __parse_name(self, person):
name_format = NameFormat(self._in) name_format = NameFormat(self._in)

View File

@ -51,7 +51,7 @@ import cairo
# Gramps Modules # Gramps Modules
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
from gramps.gen.lib import EventType, Place from gramps.gen.lib import EventType, Place, PlaceType, PlaceRef
from gramps.gen.display.name import displayer as _nd from gramps.gen.display.name import displayer as _nd
from gramps.gui.views.navigationview import NavigationView from gramps.gui.views.navigationview import NavigationView
from gramps.gen.utils.libformatting import FormattingHelper from gramps.gen.utils.libformatting import FormattingHelper
@ -61,6 +61,7 @@ from gramps.gui.managedwindow import ManagedWindow
from gramps.gen.config import config from gramps.gen.config import config
from gramps.gui.editors import EditPlace, EditEvent, EditFamily, EditPerson from gramps.gui.editors import EditPlace, EditEvent, EditFamily, EditPerson
from gramps.gui.selectors.selectplace import SelectPlace from gramps.gui.selectors.selectplace import SelectPlace
from gramps.gen.utils.location import get_main_location
from gi.repository import OsmGpsMap as osmgpsmap from gi.repository import OsmGpsMap as osmgpsmap
from . import constants from . import constants
@ -804,12 +805,14 @@ class GeoGraphyView(OsmGps, NavigationView):
""" """
self.mark = mark self.mark = mark
place = self.dbstate.db.get_place_from_gramps_id(self.mark[9]) place = self.dbstate.db.get_place_from_gramps_id(self.mark[9])
loc = place.get_main_location() parent_list = place.get_placeref_list()
if len(parent_list) > 0:
parent = parent_list[0].ref
else:
parent = None
self.select_fct = PlaceSelection(self.uistate, self.dbstate, self.osm, self.select_fct = PlaceSelection(self.uistate, self.dbstate, self.osm,
self.selection_layer, self.place_list, self.selection_layer, self.place_list,
lat, lon, self.__edit_place, lat, lon, self.__edit_place, parent)
(loc.get_country(), loc.get_state(), loc.get_county())
)
def edit_person(self, menu, event, lat, lon, mark): def edit_person(self, menu, event, lat, lon, mark):
""" """
@ -866,9 +869,11 @@ class GeoGraphyView(OsmGps, NavigationView):
selector = SelectPlace(self.dbstate, self.uistate, []) selector = SelectPlace(self.dbstate, self.uistate, [])
place = selector.run() place = selector.run()
if place: if place:
loc = place.get_main_location() parent_list = place.get_placeref_list()
oldv = (loc.get_country(), loc.get_state(), if len(parent_list) > 0:
loc.get_county()) if loc else None parent = parent_list[0].ref
else:
parent = None
places_handle = self.dbstate.db.iter_place_handles() places_handle = self.dbstate.db.iter_place_handles()
nb_places = 0 nb_places = 0
gids = "" gids = ""
@ -903,9 +908,9 @@ class GeoGraphyView(OsmGps, NavigationView):
lat, lat,
lon, lon,
self.__edit_place, self.__edit_place,
oldv) parent)
def __add_place(self, pcountry, pcounty, pstate, plat, plon): def __add_place(self, parent, plat, plon):
""" """
Add a new place using longitude and latitude of location centered Add a new place using longitude and latitude of location centered
on the map on the map
@ -914,18 +919,17 @@ class GeoGraphyView(OsmGps, NavigationView):
new_place = Place() new_place = Place()
new_place.set_latitude(str(plat)) new_place.set_latitude(str(plat))
new_place.set_longitude(str(plon)) new_place.set_longitude(str(plon))
loc = new_place.get_main_location() if parent:
loc.set_country(pcountry) placeref = PlaceRef()
loc.set_county(pcounty) placeref.ref = parent
loc.set_state(pstate) new_place.add_placeref(placeref)
new_place.set_main_location(loc)
try: try:
EditPlace(self.dbstate, self.uistate, [], new_place) EditPlace(self.dbstate, self.uistate, [], new_place)
self.add_marker(None, None, plat, plon, None, True, 0) self.add_marker(None, None, plat, plon, None, True, 0)
except WindowActiveError: except WindowActiveError:
pass pass
def __edit_place(self, pcountry, pcounty, pstate, plat, plon): def __edit_place(self, parent, plat, plon):
""" """
Edit the selected place at the marker position Edit the selected place at the marker position
""" """
@ -933,17 +937,16 @@ class GeoGraphyView(OsmGps, NavigationView):
place = self.dbstate.db.get_place_from_gramps_id(self.mark[9]) place = self.dbstate.db.get_place_from_gramps_id(self.mark[9])
place.set_latitude(str(plat)) place.set_latitude(str(plat))
place.set_longitude(str(plon)) place.set_longitude(str(plon))
loc = place.get_main_location() if parent:
loc.set_country(pcountry) placeref = PlaceRef()
loc.set_county(pcounty) placeref.ref = parent
loc.set_state(pstate) place.add_placeref(placeref)
place.set_main_location(loc)
try: try:
EditPlace(self.dbstate, self.uistate, [], place) EditPlace(self.dbstate, self.uistate, [], place)
except WindowActiveError: except WindowActiveError:
pass pass
def __link_place(self, pcountry, pcounty, pstate, plat, plon): def __link_place(self, parent, plat, plon):
""" """
Link an existing place using longitude and latitude of location centered Link an existing place using longitude and latitude of location centered
on the map on the map
@ -954,11 +957,10 @@ class GeoGraphyView(OsmGps, NavigationView):
self.select_fct.close() self.select_fct.close()
place.set_latitude(str(plat)) place.set_latitude(str(plat))
place.set_longitude(str(plon)) place.set_longitude(str(plon))
loc = place.get_main_location() if parent:
loc.set_country(pcountry) placeref = PlaceRef()
loc.set_county(pcounty) placeref.ref = parent
loc.set_state(pstate) place.add_placeref(placeref)
place.set_main_location(loc)
try: try:
EditPlace(self.dbstate, self.uistate, [], place) EditPlace(self.dbstate, self.uistate, [], place)
self.add_marker(None, None, plat, plon, None, True, 0) self.add_marker(None, None, plat, plon, None, True, 0)

View File

@ -56,6 +56,8 @@ from gi.repository import Gtk
from gramps.gen.errors import WindowActiveError from gramps.gen.errors import WindowActiveError
from gramps.gui.managedwindow import ManagedWindow from gramps.gui.managedwindow import ManagedWindow
from .osmgps import OsmGps from .osmgps import OsmGps
from gramps.gen.utils.location import get_main_location
from gramps.gen.lib import PlaceType
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
# #
@ -77,9 +79,9 @@ def match(self, lat, lon, radius):
if (math.hypot(lat-float(entry[3]), if (math.hypot(lat-float(entry[3]),
lon-float(entry[4])) <= rds) == True: lon-float(entry[4])) <= rds) == True:
# Do we already have this place ? avoid duplicates # Do we already have this place ? avoid duplicates
self.get_location(entry[9]) country, state, county, place = self.get_location(entry[9])
if not [self.country, self.state, self.county] in self.places: if not [country, state, county, place] in self.places:
self.places.append([self.country, self.state, self.county]) self.places.append([country, state, county, place])
return self.places return self.places
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
@ -100,8 +102,7 @@ class PlaceSelection(ManagedWindow, OsmGps):
Place Selection initialization Place Selection initialization
""" """
try: try:
ManagedWindow.__init__(self, uistate, [], ManagedWindow.__init__(self, uistate, [], PlaceSelection)
PlaceSelection)
except WindowActiveError: except WindowActiveError:
return return
self.uistate = uistate self.uistate = uistate
@ -109,9 +110,6 @@ class PlaceSelection(ManagedWindow, OsmGps):
self.lat = lat self.lat = lat
self.lon = lon self.lon = lon
self.osm = maps self.osm = maps
self.country = None
self.state = None
self.county = None
self.radius = 1.0 self.radius = 1.0
self.circle = None self.circle = None
self.oldvalue = oldvalue self.oldvalue = oldvalue
@ -141,7 +139,7 @@ class PlaceSelection(ManagedWindow, OsmGps):
self.scroll = Gtk.ScrolledWindow(self.vadjust) self.scroll = Gtk.ScrolledWindow(self.vadjust)
self.scroll.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC) self.scroll.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC)
self.scroll.set_shadow_type(Gtk.ShadowType.IN) self.scroll.set_shadow_type(Gtk.ShadowType.IN)
self.plist = Gtk.ListStore(str, str, str) self.plist = Gtk.ListStore(str, str, str, str)
self.choices = Gtk.TreeView(self.plist) self.choices = Gtk.TreeView(self.plist)
self.scroll.add(self.choices) self.scroll.add(self.choices)
self.renderer = Gtk.CellRendererText() self.renderer = Gtk.CellRendererText()
@ -191,17 +189,19 @@ class PlaceSelection(ManagedWindow, OsmGps):
# In this case, we change the color of the row. # In this case, we change the color of the row.
# display the associated message # display the associated message
self.label2.show() self.label2.show()
field1, field2, field3 = self.oldvalue place = self.dbstate.db.get_place_from_handle(self.oldvalue)
self.plist.append((PLACE_STRING % field1, loc = get_main_location(self.dbstate.db, place)
PLACE_STRING % field2, self.plist.append((PLACE_STRING % loc.get(PlaceType.COUNTRY, ''),
PLACE_STRING % field3) PLACE_STRING % loc.get(PlaceType.STATE, ''),
PLACE_STRING % loc.get(PlaceType.COUNTY, ''),
self.oldvalue)
) )
for place in self.places: for place in self.places:
self.plist.append(place) self.plist.append(place)
# here, we could add value from geography names services ... # here, we could add value from geography names services ...
# if we found no place, we must create a default place. # if we found no place, we must create a default place.
self.plist.append((_("New place with empty fields"), "", "...")) self.plist.append((_("New place with empty fields"), "", "...", None))
def hide_the_region(self): def hide_the_region(self):
""" """
@ -220,37 +220,32 @@ class PlaceSelection(ManagedWindow, OsmGps):
self.selection_layer = self.add_selection_layer() self.selection_layer = self.add_selection_layer()
self.selection_layer.add_circle(rds/2.0, self.lat, self.lon) self.selection_layer.add_circle(rds/2.0, self.lat, self.lon)
def get_location(self, place): def get_location(self, gramps_id):
""" """
get location values get location values
""" """
place = self.dbstate.db.get_place_from_gramps_id(place) parent_place = None
loc = place.get_main_location() country = state = county = ''
data = loc.get_text_data_list() place = self.dbstate.db.get_place_from_gramps_id(gramps_id)
# new background or font color on gtk fields ? parent_list = place.get_placeref_list()
self.country = data[6] while len(parent_list) > 0:
self.state = data[5] place = self.dbstate.db.get_place_from_handle(parent_list[0].ref)
self.county = data[4] if int(place.get_type()) == PlaceType.COUNTY:
return(self.country, self.state, self.county) county = place.name
if parent_place is None:
parent_place = place.get_handle()
elif int(place.get_type()) == PlaceType.STATE:
state = place.name
if parent_place is None:
parent_place = place.get_handle()
elif int(place.get_type()) == PlaceType.COUNTRY:
country = place.name
if parent_place is None:
parent_place = place.get_handle()
return(country, state, county, parent_place)
def selection(self, obj, index, column, function): def selection(self, obj, index, column, function):
""" """
get location values and call the real function : add_place, edit_place get location values and call the real function : add_place, edit_place
""" """
if self.plist[index][2] == "...": self.function(self.plist[index][3], self.lat, self.lon)
# case with blank values ( New place with empty fields )
self.function( "", "", "", self.lat, self.lon)
elif self.plist[index][0][1:5] == "span":
# case with old values ( keep the old values of the place )
name = PLACE_REGEXP.search(self.plist[index][0], 0)
country = name.group(1)
name = PLACE_REGEXP.search(self.plist[index][1], 0)
state = name.group(1)
name = PLACE_REGEXP.search(self.plist[index][2], 0)
county = name.group(1)
self.function( country, county, state, self.lat, self.lon)
else:
# Set the new values of the country, county and state fields.
self.function( self.plist[index][0], self.plist[index][2],
self.plist[index][1], self.lat, self.lon)

View File

@ -41,6 +41,8 @@ _ = glocale.translation.gettext
#------------------------------------------------------------------------ #------------------------------------------------------------------------
from gramps.plugins.lib.libmapservice import MapService from gramps.plugins.lib.libmapservice import MapService
from gramps.gui.dialog import WarningDialog from gramps.gui.dialog import WarningDialog
from gramps.gen.utils.location import get_main_location
from gramps.gen.lib import PlaceType
# Make upper case of translaed country so string search works later # Make upper case of translaed country so string search works later
MAP_NAMES_SWEDEN = [_("Sweden").upper(), MAP_NAMES_SWEDEN = [_("Sweden").upper(),
@ -65,12 +67,13 @@ def _strip_leading_comma(descr):
descr = descr.strip()[1:] descr = descr.strip()[1:]
return descr.strip() return descr.strip()
def _build_title(self): def _build_title(db, place):
""" Builds descrition string for title parameter in url """ """ Builds descrition string for title parameter in url """
descr = self.get_title() descr = place.get_title()
parish = self.get_main_location().get_parish() location = get_main_location(db, place)
city = self.get_main_location().get_city() parish = location.get(PlaceType.PARISH)
state = self.get_main_location().get_state() city = location.get(PlaceType.CITY)
state = location.get(PlaceType.STATE)
title_descr = "" title_descr = ""
if descr: if descr:
title_descr += descr.strip() title_descr += descr.strip()
@ -82,19 +85,21 @@ def _build_title(self):
title_descr += ', ' + state.strip() + _(" state") title_descr += ', ' + state.strip() + _(" state")
return _strip_leading_comma(title_descr) return _strip_leading_comma(title_descr)
def _build_city(self): def _build_city(db, place):
""" Builds description string for city parameter in url """ """ Builds description string for city parameter in url """
county = self.get_main_location().get_county() location = get_main_location(db, place)
county = location.get(PlaceType.COUNTY)
# Build a title description string that will work for Eniro # Build a title description string that will work for Eniro
city_descr = _build_area(self) city_descr = _build_area(db, place)
if county: if county:
city_descr += ', ' + county city_descr += ', ' + county
return _strip_leading_comma(city_descr) return _strip_leading_comma(city_descr)
def _build_area(self): def _build_area(db, place):
""" Builds string for area parameter in url """ """ Builds string for area parameter in url """
street = self.get_main_location().get_street() location = get_main_location(db, place)
city = self.get_main_location().get_city() street = location.get(PlaceType.STREET)
city = location.get(PlaceType.CITY)
# Build a title description string that will work for Eniro # Build a title description string that will work for Eniro
area_descr = "" area_descr = ""
if street: if street:
@ -121,7 +126,8 @@ class EniroSVMapService(MapService):
path = "" path = ""
# First see if we are in or near Sweden or Denmark # First see if we are in or near Sweden or Denmark
# Change country to upper case # Change country to upper case
country = place.get_main_location().get_country().upper().strip() location = get_main_location(self.database, place)
country = location.get(PlaceType.COUNTRY, '').upper().strip()
country_given = (country in MAP_NAMES_SWEDEN or \ country_given = (country in MAP_NAMES_SWEDEN or \
country in MAP_NAMES_DENMARK) and (country != "") country in MAP_NAMES_DENMARK) and (country != "")
# if no country given, check if we might be in the vicinity defined by # if no country given, check if we might be in the vicinity defined by
@ -143,8 +149,8 @@ class EniroSVMapService(MapService):
return return
if coord_ok: if coord_ok:
place_title = _build_title(place) place_title = _build_title(self.database, place)
place_city = _build_city(place) place_city = _build_city(self.database, place)
x_coord, y_coord = self._lat_lon(place, format="RT90") x_coord, y_coord = self._lat_lon(place, format="RT90")
# Set zoom level to 5 if Sweden/Denmark, others 3 # Set zoom level to 5 if Sweden/Denmark, others 3
zoom = 5 zoom = 5
@ -157,7 +163,7 @@ class EniroSVMapService(MapService):
self.url = path.replace(" ","%20") self.url = path.replace(" ","%20")
return return
place_area = _build_area(place) place_area = _build_area(self.database, place)
if country_given and place_area: if country_given and place_area:
if country in MAP_NAMES_SWEDEN: if country in MAP_NAMES_SWEDEN:
path = "http://kartor.eniro.se/query?&what=map_adr&mop=aq" \ path = "http://kartor.eniro.se/query?&what=map_adr&mop=aq" \

View File

@ -37,6 +37,8 @@ _ = glocale.translation.gettext
# #
#------------------------------------------------------------------------ #------------------------------------------------------------------------
from gramps.plugins.lib.libmapservice import MapService from gramps.plugins.lib.libmapservice import MapService
from gramps.gen.utils.location import get_main_location
from gramps.gen.lib import PlaceType
class GoogleMapService(MapService): class GoogleMapService(MapService):
"""Map service using http://maps.google.com""" """Map service using http://maps.google.com"""
@ -56,8 +58,9 @@ class GoogleMapService(MapService):
longitude) longitude)
return return
city = place.get_main_location().get_city() location = get_main_location(self.database, place)
country = place.get_main_location().get_country() city = location.get(PlaceType.CITY)
country = location.get(PlaceType.COUNTRY)
if city and country: if city and country:
self.url = "http://maps.google.com/maps?q=%s,%s" % (city, country) self.url = "http://maps.google.com/maps?q=%s,%s" % (city, country)
return return

View File

@ -37,7 +37,8 @@ _ = glocale.translation.gettext
# #
#------------------------------------------------------------------------ #------------------------------------------------------------------------
from gramps.plugins.lib.libmapservice import MapService from gramps.plugins.lib.libmapservice import MapService
from gramps.gen.utils.location import get_main_location
from gramps.gen.lib import PlaceType
class OpensStreetMapService(MapService): class OpensStreetMapService(MapService):
"""Map service using http://openstreetmap.org """Map service using http://openstreetmap.org
@ -60,8 +61,9 @@ class OpensStreetMapService(MapService):
return return
city = place.get_main_location().get_city() location = get_main_location(self.database, place)
country = place.get_main_location().get_country() city = location.get(PlaceType.CITY)
country = location.get(PlaceType.COUNTRY)
if city and country: if city and country:
self.url = "http://open.mapquestapi.com/nominatim/v1/"\ self.url = "http://open.mapquestapi.com/nominatim/v1/"\
"search.php?q=%s%%2C%s" % (city, country) "search.php?q=%s%%2C%s" % (city, country)

View File

@ -51,6 +51,8 @@ from gramps.gen.proxy import PrivateProxyDb
from gramps.gen.datehandler import get_date from gramps.gen.datehandler import get_date
from gramps.gen.sort import Sort from gramps.gen.sort import Sort
from gramps.gen.display.name import displayer as _nd from gramps.gen.display.name import displayer as _nd
from gramps.gen.utils.location import get_main_location
from gramps.gen.lib import PlaceType
class PlaceReport(Report): class PlaceReport(Report):
""" """
@ -148,16 +150,17 @@ class PlaceReport(Report):
This procedure writes out the details of a single place This procedure writes out the details of a single place
""" """
place = self.database.get_place_from_handle(handle) place = self.database.get_place_from_handle(handle)
location = place.get_main_location() location = get_main_location(self.database, place)
place_details = [self._("Gramps ID: %s ") % place.get_gramps_id(), place_details = [
self._("Street: %s ") % location.get_street(), self._("Gramps ID: %s ") % place.get_gramps_id(),
self._("Parish: %s ") % location.get_parish(), self._("Street: %s ") % location.get(PlaceType.STREET, ''),
self._("Locality: %s ") % location.get_locality(), self._("Parish: %s ") % location.get(PlaceType.PARISH, ''),
self._("City: %s ") % location.get_city(), self._("Locality: %s ") % location.get(PlaceType.LOCALITY, ''),
self._("County: %s ") % location.get_county(), self._("City: %s ") % location.get(PlaceType.CITY, ''),
self._("State: %s") % location.get_state(), self._("County: %s ") % location.get(PlaceType.COUNTY, ''),
self._("Country: %s ") % location.get_country()] self._("State: %s") % location.get(PlaceType.STATE, ''),
self._("Country: %s ") % location.get(PlaceType.COUNTRY, '')]
self.doc.start_paragraph("PLC-PlaceTitle") self.doc.start_paragraph("PLC-PlaceTitle")
self.doc.write_text(("%(nbr)s. %(place)s") % self.doc.write_text(("%(nbr)s. %(place)s") %
{'nbr' : place_nbr, {'nbr' : place_nbr,

View File

@ -30,10 +30,10 @@ from __future__ import unicode_literals
# Gramps modules # Gramps modules
# #
#------------------------------------------------------------------------- #-------------------------------------------------------------------------
from gramps.gui.views.listview import TEXT, MARKUP, ICON from gramps.gui.views.listview import TEXT, ICON
from gramps.plugins.lib.libplaceview import PlaceBaseView from gramps.plugins.lib.libplaceview import PlaceBaseView
from gramps.gui.views.treemodels.placemodel import PlaceTreeModel, COUNTRYLEVELS from gramps.gui.views.treemodels.placemodel import PlaceTreeModel
from gramps.gen.lib import Place from gramps.gen.lib import Place, PlaceRef
from gramps.gen.errors import WindowActiveError from gramps.gen.errors import WindowActiveError
from gramps.gui.editors import EditPlace from gramps.gui.editors import EditPlace
@ -54,51 +54,35 @@ class PlaceTreeView(PlaceBaseView):
""" """
A hierarchical view of the top three levels of places. A hierarchical view of the top three levels of places.
""" """
COL_PLACE = 0 COL_NAME = 0
COL_ID = 1 COL_ID = 1
COL_STREET = 2 COL_TITLE = 2
COL_LOCALITY = 3 COL_TYPE = 3
COL_CITY = 4 COL_CODE = 4
COL_COUNTY = 5 COL_LAT = 5
COL_STATE = 6 COL_LON = 6
COL_COUNTRY = 7 COL_PRIV = 7
COL_ZIP = 8 COL_TAGS = 8
COL_PARISH = 9 COL_CHAN = 9
COL_LAT = 10
COL_LON = 11
COL_PRIV = 12
COL_TAGS = 13
COL_CHAN = 14
COL_NAME = 15
# column definitions # column definitions
COLUMNS = [ COLUMNS = [
(_('Place'), MARKUP, None), (_('Name'), TEXT, None),
(_('ID'), TEXT, None), (_('ID'), TEXT, None),
(_('Street'), TEXT, None), (_('Title'), TEXT, None),
(_('Locality'), TEXT, None), (_('Type'), TEXT, None),
(_('City'), TEXT, None), (_('Code'), TEXT, None),
(_('County'), TEXT, None),
(_('State'), TEXT, None),
(_('Country'), TEXT, None),
(_('ZIP/Postal Code'), TEXT, None),
(_('Church Parish'), TEXT, None),
(_('Latitude'), TEXT, None), (_('Latitude'), TEXT, None),
(_('Longitude'), TEXT, None), (_('Longitude'), TEXT, None),
(_('Private'), ICON, 'gramps-lock'), (_('Private'), ICON, 'gramps-lock'),
(_('Tags'), TEXT, None), (_('Tags'), TEXT, None),
(_('Last Changed'), TEXT, None), (_('Last Changed'), TEXT, None),
(_('Place Name'), TEXT, None),
] ]
# default setting with visible columns, order of the col, and their size # default setting with visible columns, order of the col, and their size
CONFIGSETTINGS = ( CONFIGSETTINGS = (
('columns.visible', [COL_PLACE, COL_ID, COL_STREET, COL_LOCALITY, ('columns.visible', [COL_NAME, COL_ID, COL_TYPE, COL_CODE]),
COL_CITY, COL_COUNTY, COL_STATE]), ('columns.rank', [COL_NAME, COL_ID, COL_TITLE, COL_TYPE, COL_CODE,
('columns.rank', [COL_PLACE, COL_ID, COL_STREET, COL_LOCALITY, COL_CITY, COL_LAT, COL_LON, COL_PRIV, COL_TAGS, COL_CHAN]),
COL_COUNTY, COL_STATE, COL_COUNTRY, COL_ZIP, ('columns.size', [250, 75, 150, 100, 100, 150, 150, 40, 100, 100])
COL_PARISH, COL_LAT, COL_LON, COL_PRIV, COL_TAGS,
COL_CHAN, COL_NAME]),
('columns.size', [250, 75, 150, 150, 150, 150, 100, 100, 100,
100, 150, 150, 40, 100, 100, 150])
) )
def __init__(self, pdata, dbstate, uistate): def __init__(self, pdata, dbstate, uistate):
@ -196,41 +180,16 @@ class PlaceTreeView(PlaceBaseView):
Add a new place. Attempt to get the top three levels of hierarchy from Add a new place. Attempt to get the top three levels of hierarchy from
the currently selected row. the currently selected row.
""" """
place = Place() parent_list = []
for handle in self.selected_handles():
model, pathlist = self.selection.get_selected_rows() placeref = PlaceRef()
level = ["", "", ""] placeref.ref = handle
level1 = level2 = level3 = "" parent_list.append(placeref)
if len(pathlist) == 1:
path = pathlist[0]
iter_ = model.get_iter(path)
if iter_:
if len(path) == 1:
level[0] = model.get_node_from_iter(iter_).name
elif len(path) == 2:
level[1] = model.get_node_from_iter(iter_).name
parent = model.iter_parent(iter_)
level[0] = model.get_node_from_iter(parent).name
elif len(path) == 3:
level[2] = model.get_node_from_iter(iter_).name
parent = model.iter_parent(iter_)
level[1] = model.get_node_from_iter(parent).name
parent = model.iter_parent(parent)
level[0] = model.get_node_from_iter(parent).name
else:
parent = model.iter_parent(iter_)
level[2] = model.get_node_from_iter(parent).name
parent = model.iter_parent(parent)
level[1] = model.get_node_from_iter(parent).name
parent = model.iter_parent(parent)
level[0] = model.get_node_from_iter(parent).name
for ind in [0, 1, 2]: place = Place()
if level[ind] and level[ind] == COUNTRYLEVELS['default'][ind+1]: if len(parent_list) > 0:
level[ind] = "" place.parent = parent_list
place.get_main_location().set_country(level[0])
place.get_main_location().set_state(level[1])
place.get_main_location().set_county(level[2])
try: try:
EditPlace(self.dbstate, self.uistate, [], place) EditPlace(self.dbstate, self.uistate, [], place)
except WindowActiveError: except WindowActiveError:

View File

@ -108,7 +108,7 @@ log = logging.getLogger(".NarrativeWeb")
from gramps.gen.const import GRAMPS_LOCALE as glocale from gramps.gen.const import GRAMPS_LOCALE as glocale
_ = glocale.translation.sgettext _ = glocale.translation.sgettext
from gramps.gen.lib import (ChildRefType, Date, EventType, FamilyRelType, Name, from gramps.gen.lib import (ChildRefType, Date, EventType, FamilyRelType, Name,
NameType, Person, UrlType, NoteType, NameType, Person, UrlType, NoteType, PlaceType,
EventRoleType, Family, Event, Place, Source, EventRoleType, Family, Event, Place, Source,
Citation, MediaObject, Repository, Note, Tag) Citation, MediaObject, Repository, Note, Tag)
from gramps.gen.lib.date import Today from gramps.gen.lib.date import Today
@ -148,6 +148,7 @@ from gramps.gen.utils.place import conv_lat_lon
from gramps.gui.pluginmanager import GuiPluginManager from gramps.gui.pluginmanager import GuiPluginManager
from gramps.gen.relationship import get_relationship_calculator from gramps.gen.relationship import get_relationship_calculator
from gramps.gen.utils.location import get_main_location
COLLATE_LANG = glocale.collation COLLATE_LANG = glocale.collation
SORT_KEY = glocale.sort_key SORT_KEY = glocale.sort_key
@ -508,14 +509,11 @@ def get_gendex_data(database, event_ref):
if place_handle: if place_handle:
place = database.get_place_from_handle(place_handle) place = database.get_place_from_handle(place_handle)
if place: if place:
location = place.get_main_location() location = get_main_location(self.dbase_, place)
if location and not location.is_empty(): poe = ", ".join(l for l in [
poe = ", ".join(l for l in location.get(PlaceType.CITY, '').strip(),
[ location.get(PlaceType.STATE, '').strip(),
location.get_city().strip(), location.get(PlaceType.COUNTRY, '').strip()] if l)
location.get_state().strip(),
location.get_country().strip()
] if l)
return doe, poe return doe, poe
def format_date(date): def format_date(date):
@ -2641,26 +2639,22 @@ class BasePage(object):
) )
tbody += trow tbody += trow
if place.main_loc: ml = get_main_location(self.dbase_, place)
ml = place.get_main_location() for (label, data) in [
if ml and not ml.is_empty(): (STREET, ml.get(PlaceType.STREET, '')),
(LOCALITY, ml.get(PlaceType.LOCALITY, '')),
for (label, data) in [ (CITY, ml.get(PlaceType.CITY, '')),
(STREET, ml.street), (PARISH, ml.get(PlaceType.PARISH, '')),
(LOCALITY, ml.locality), (COUNTY, ml.get(PlaceType.COUNTY, '')),
(CITY, ml.city), (STATE, ml.get(PlaceType.STATE, '')),
(PARISH, ml.parish), (POSTAL, place.get_code()),
(COUNTY, ml.county), (COUNTRY, ml.get(PlaceType.COUNTRY, ''))]:
(STATE, ml.state), if data:
(POSTAL, ml.postal), trow = Html("tr") + (
(COUNTRY, ml.country), Html("td", label, class_ = "ColumnAttribute", inline = True),
(_("Telephone"), ml.phone) ]: Html("td", data, class_ = "ColumnValue", inline = True)
if data: )
trow = Html("tr") + ( tbody += trow
Html("td", label, class_ = "ColumnAttribute", inline = True),
Html("td", data, class_ = "ColumnValue", inline = True)
)
tbody += trow
altloc = place.get_alternate_locations() altloc = place.get_alternate_locations()
if altloc: if altloc:
@ -3384,7 +3378,7 @@ class PlacePages(BasePage):
place = self.dbase_.get_place_from_handle(place_handle) place = self.dbase_.get_place_from_handle(place_handle)
if place: if place:
place_title = place.get_title() place_title = place.get_title()
ml = place.get_main_location() ml = get_main_location(self.dbase_, place)
if place_title and not place_title.isspace(): if place_title and not place_title.isspace():
letter = get_index_letter(first_letter(place_title), letter = get_index_letter(first_letter(place_title),
@ -3414,8 +3408,8 @@ class PlacePages(BasePage):
trow.extend( trow.extend(
Html("td", data or "&nbsp;", class_ =colclass, inline =True) Html("td", data or "&nbsp;", class_ =colclass, inline =True)
for (colclass, data) in [ for (colclass, data) in [
["ColumnState", ml.state], ["ColumnState", ml.get(PlaceType.STATE, '')],
["ColumnCountry", ml.country] ] ["ColumnCountry", ml.get(PlaceType.COUNTRY, '')] ]
) )
tcell1 = Html("td", class_ ="ColumnLatitude", inline =True) tcell1 = Html("td", class_ ="ColumnLatitude", inline =True)