Fix Lat/Long translated NSEW display and entry in rtl language;Store Lat/Long in place objects with NSEW always in English (#965)

* Fix Lat/Long translated NSEW display and entry in rtl language

* Store Lat/Long in place objects with NSEW always in English

Issue #11335
This commit is contained in:
Paul Culley 2020-01-09 12:03:20 -06:00 committed by GitHub
parent 7807ff8a6d
commit 801be84465
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 100 additions and 25 deletions

View File

@ -57,19 +57,25 @@ South = South.replace("1", " ").strip()
East = East.replace("1", " ").strip()
West = West.replace("1", " ").strip()
# build dictionary with translation en to local language
translate_en_loc = {}
translate_en_loc['N'] = North
translate_en_loc['S'] = South
translate_en_loc['E'] = East
translate_en_loc['W'] = West
# keep translation only if it does not conflict with english
if 'N' == South or 'S' == North or 'E' == West or 'W' == East:
translate_en_loc['N'] = 'N'
translate_en_loc['S'] = 'S'
translate_en_loc['E'] = 'E'
translate_en_loc['W'] = 'W'
North = 'N'
South = 'S'
East = 'E'
West = 'W'
# for rtl locales the lat/long strings are always displayed ltr, so we need to
# reverse the translated NSEW strings to make them correctly display rtl
# we keep both normal/reversed for comparison on input
if glocale.rtl_locale:
North_ = North
North = North[::-1]
South_ = South
South = South[::-1]
East_ = East
East = East[::-1]
West_ = West
West = West[::-1]
# end localisation part
@ -356,14 +362,26 @@ def conv_lat_lon(latitude, longitude, format="D.D4"):
"""
# we start the function changing latitude/longitude in english
if latitude.find('N') == -1 and latitude.find('S') == -1:
if 'N' not in latitude and 'S' not in latitude:
# entry is not in english, convert to english
latitude = latitude.replace(translate_en_loc['N'], 'N')
latitude = latitude.replace(translate_en_loc['S'], 'S')
if longitude.find('E') == -1 and longitude.find('W') == -1:
latitude = latitude.replace(North, 'N')
latitude = latitude.replace(South, 'S')
if glocale.rtl_locale:
# since Gtk.Entry doesn't handle mixed bidi strings like lat/long
# well, we always force ltr. So depending on wether user makes it
# look right, or enters blindly, the translated NSEW could be
# normal or reversed, so,
# we also allow user to use reversed string
latitude = latitude.replace(North_, 'N')
latitude = latitude.replace(South_, 'S')
if 'E' not in longitude and 'W' not in longitude:
# entry is not in english, convert to english
longitude = longitude.replace(translate_en_loc['W'], 'W')
longitude = longitude.replace(translate_en_loc['E'], 'E')
longitude = longitude.replace(West, 'W')
longitude = longitude.replace(East, 'E')
if glocale.rtl_locale:
# we also allow user to use reversed string
longitude = longitude.replace(West_, 'W')
longitude = longitude.replace(East_, 'E')
# take away leading spaces
latitude = latitude.lstrip()
@ -454,16 +472,16 @@ def conv_lat_lon(latitude, longitude, format="D.D4"):
sign_lat = "+"
dir_lat = ""
if lat_float >= 0.:
dir_lat = translate_en_loc['N']
dir_lat = North
else:
dir_lat = translate_en_loc['S']
dir_lat = South
sign_lat = "-"
sign_lon = "+"
dir_lon = ""
if lon_float >= 0.:
dir_lon = translate_en_loc['E']
dir_lon = East
else:
dir_lon = translate_en_loc['W']
dir_lon = West
sign_lon = "-"
if format == "DEG":
@ -479,8 +497,7 @@ def conv_lat_lon(latitude, longitude, format="D.D4"):
if str_lon[-6-len(dir_lon)] == '6':
if min_lon == 59:
if deg_lon == 179 and sign_lon == "+":
str_lon = ("%d°%02d'%05.2f\"" % (180, 0, 0.)) \
+ translate_en_loc['W']
str_lon = ("%d°%02d'%05.2f\"" % (180, 0, 0.)) + West
else:
str_lon = ("%d°%02d'%05.2f\"" % (deg_lon+1, 0, 0.)) \
+ dir_lon
@ -674,6 +691,38 @@ def __conv_SWED_RT90_WGS84(X, Y):
return LAT, LON
def translate_lat_to_en(latitude):
""" Translate the localized NS portion of a latitude to the English 'N'
and 'S' characters. """
if 'N' not in latitude and 'S' not in latitude:
# entry is not in english, convert to english
latitude = latitude.replace(North, 'N')
latitude = latitude.replace(South, 'S')
if glocale.rtl_locale:
# since Gtk.Entry doesn't handle mixed bidi strings like lat/long
# well, we always force ltr. So depending on wether user makes it
# look right, or enters blindly, the translated NSEW could be
# normal or reversed, so,
# we also allow user to use reversed string
latitude = latitude.replace(North_, 'N')
latitude = latitude.replace(South_, 'S')
return latitude
def translate_long_to_en(longitude):
""" Translate the localized EW portion of a latitude to the English 'E'
and 'W' characters. """
if 'E' not in longitude and 'W' not in longitude:
# entry is not in english, convert to english
longitude = longitude.replace(West, 'W')
longitude = longitude.replace(East, 'E')
if glocale.rtl_locale:
# we also allow user to use reversed string
longitude = longitude.replace(West_, 'W')
longitude = longitude.replace(East_, 'E')
return longitude
#-------------------------------------------------------------------------
#
# For Testing the convert function in this module, apply it as a script:

View File

@ -52,7 +52,8 @@ from .displaytabs import (PlaceRefEmbedList, PlaceNameEmbedList,
from ..widgets import (MonitoredEntry, PrivacyButton, MonitoredTagList,
MonitoredDataType)
from gramps.gen.errors import ValidationError, WindowActiveError
from gramps.gen.utils.place import conv_lat_lon
from gramps.gen.utils.place import (conv_lat_lon, North, South, East, West,
translate_lat_to_en, translate_long_to_en)
from gramps.gen.display.place import displayer as place_displayer
from gramps.gen.config import config
from ..dialog import ErrorDialog
@ -160,6 +161,9 @@ class EditPlace(EditPrimary):
entry = self.top.get_object("lon_entry")
entry.set_ltr_mode()
# get E,W translated to local
self.obj.set_longitude(self.obj.get_longitude().replace(
'E', East).replace('W', West))
self.longitude = MonitoredEntry(
entry,
self.obj.set_longitude, self.obj.get_longitude,
@ -170,6 +174,9 @@ class EditPlace(EditPrimary):
entry = self.top.get_object("lat_entry")
entry.set_ltr_mode()
# get N,S translated to local
self.obj.set_latitude(self.obj.get_latitude().replace(
'N', North).replace('S', South))
self.latitude = MonitoredEntry(
entry,
self.obj.set_latitude, self.obj.get_latitude,
@ -331,6 +338,11 @@ class EditPlace(EditPrimary):
return
place_title = place_displayer.display(self.db, self.obj)
# get localized E,W translated to English
self.obj.set_longitude(translate_long_to_en(self.obj.get_longitude()))
# get localized N,S translated to English
self.obj.set_latitude(translate_lat_to_en(self.obj.get_latitude()))
if not self.obj.handle:
with DbTxn(_("Add Place (%s)") % place_title,
self.db) as trans:

View File

@ -34,7 +34,8 @@ from .displaytabs import (PlaceRefEmbedList, PlaceNameEmbedList,
from gramps.gen.lib import NoteType
from gramps.gen.db import DbTxn
from gramps.gen.errors import ValidationError, WindowActiveError
from gramps.gen.utils.place import conv_lat_lon
from gramps.gen.utils.place import (conv_lat_lon, North, South, East, West,
translate_lat_to_en, translate_long_to_en)
from gramps.gen.display.place import displayer as place_displayer
from gramps.gen.config import config
from ..dialog import ErrorDialog
@ -153,6 +154,9 @@ class EditPlaceRef(EditReference):
entry = self.top.get_object("lon_entry")
entry.set_ltr_mode()
# get E,W translated to local
self.source.set_longitude(self.source.get_longitude().replace(
'E', East).replace('W', West))
self.longitude = MonitoredEntry(
entry,
self.source.set_longitude, self.source.get_longitude,
@ -163,6 +167,9 @@ class EditPlaceRef(EditReference):
entry = self.top.get_object("lat_entry")
entry.set_ltr_mode()
# get N,S translated to local
self.source.set_latitude(self.source.get_latitude().replace(
'N', North).replace('S', South))
self.latitude = MonitoredEntry(
entry,
self.source.set_latitude, self.source.get_latitude,
@ -311,6 +318,13 @@ class EditPlaceRef(EditReference):
self.ok_button.set_sensitive(True)
return
# get localized E,W translated to English
self.source.set_longitude(translate_long_to_en(
self.source.get_longitude()))
# get localized N,S translated to English
self.source.set_latitude(translate_lat_to_en(
self.source.get_latitude()))
if self.source.handle:
with DbTxn(_("Modify Place"), self.db) as trans:
self.db.commit_place(self.source, trans)