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() East = East.replace("1", " ").strip()
West = West.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 # keep translation only if it does not conflict with english
if 'N' == South or 'S' == North or 'E' == West or 'W' == East: if 'N' == South or 'S' == North or 'E' == West or 'W' == East:
translate_en_loc['N'] = 'N' North = 'N'
translate_en_loc['S'] = 'S' South = 'S'
translate_en_loc['E'] = 'E' East = 'E'
translate_en_loc['W'] = 'W' 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 # 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 # 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 # entry is not in english, convert to english
latitude = latitude.replace(translate_en_loc['N'], 'N') latitude = latitude.replace(North, 'N')
latitude = latitude.replace(translate_en_loc['S'], 'S') latitude = latitude.replace(South, 'S')
if longitude.find('E') == -1 and longitude.find('W') == -1: 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 # entry is not in english, convert to english
longitude = longitude.replace(translate_en_loc['W'], 'W') longitude = longitude.replace(West, 'W')
longitude = longitude.replace(translate_en_loc['E'], 'E') 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 # take away leading spaces
latitude = latitude.lstrip() latitude = latitude.lstrip()
@ -454,16 +472,16 @@ def conv_lat_lon(latitude, longitude, format="D.D4"):
sign_lat = "+" sign_lat = "+"
dir_lat = "" dir_lat = ""
if lat_float >= 0.: if lat_float >= 0.:
dir_lat = translate_en_loc['N'] dir_lat = North
else: else:
dir_lat = translate_en_loc['S'] dir_lat = South
sign_lat = "-" sign_lat = "-"
sign_lon = "+" sign_lon = "+"
dir_lon = "" dir_lon = ""
if lon_float >= 0.: if lon_float >= 0.:
dir_lon = translate_en_loc['E'] dir_lon = East
else: else:
dir_lon = translate_en_loc['W'] dir_lon = West
sign_lon = "-" sign_lon = "-"
if format == "DEG": 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 str_lon[-6-len(dir_lon)] == '6':
if min_lon == 59: if min_lon == 59:
if deg_lon == 179 and sign_lon == "+": if deg_lon == 179 and sign_lon == "+":
str_lon = ("%d°%02d'%05.2f\"" % (180, 0, 0.)) \ str_lon = ("%d°%02d'%05.2f\"" % (180, 0, 0.)) + West
+ translate_en_loc['W']
else: else:
str_lon = ("%d°%02d'%05.2f\"" % (deg_lon+1, 0, 0.)) \ str_lon = ("%d°%02d'%05.2f\"" % (deg_lon+1, 0, 0.)) \
+ dir_lon + dir_lon
@ -674,6 +691,38 @@ def __conv_SWED_RT90_WGS84(X, Y):
return LAT, LON 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: # 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, from ..widgets import (MonitoredEntry, PrivacyButton, MonitoredTagList,
MonitoredDataType) MonitoredDataType)
from gramps.gen.errors import ValidationError, WindowActiveError 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.display.place import displayer as place_displayer
from gramps.gen.config import config from gramps.gen.config import config
from ..dialog import ErrorDialog from ..dialog import ErrorDialog
@ -160,6 +161,9 @@ class EditPlace(EditPrimary):
entry = self.top.get_object("lon_entry") entry = self.top.get_object("lon_entry")
entry.set_ltr_mode() 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( self.longitude = MonitoredEntry(
entry, entry,
self.obj.set_longitude, self.obj.get_longitude, self.obj.set_longitude, self.obj.get_longitude,
@ -170,6 +174,9 @@ class EditPlace(EditPrimary):
entry = self.top.get_object("lat_entry") entry = self.top.get_object("lat_entry")
entry.set_ltr_mode() 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( self.latitude = MonitoredEntry(
entry, entry,
self.obj.set_latitude, self.obj.get_latitude, self.obj.set_latitude, self.obj.get_latitude,
@ -331,6 +338,11 @@ class EditPlace(EditPrimary):
return return
place_title = place_displayer.display(self.db, self.obj) 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: if not self.obj.handle:
with DbTxn(_("Add Place (%s)") % place_title, with DbTxn(_("Add Place (%s)") % place_title,
self.db) as trans: self.db) as trans:

View File

@ -34,7 +34,8 @@ from .displaytabs import (PlaceRefEmbedList, PlaceNameEmbedList,
from gramps.gen.lib import NoteType from gramps.gen.lib import NoteType
from gramps.gen.db import DbTxn from gramps.gen.db import DbTxn
from gramps.gen.errors import ValidationError, WindowActiveError 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.display.place import displayer as place_displayer
from gramps.gen.config import config from gramps.gen.config import config
from ..dialog import ErrorDialog from ..dialog import ErrorDialog
@ -153,6 +154,9 @@ class EditPlaceRef(EditReference):
entry = self.top.get_object("lon_entry") entry = self.top.get_object("lon_entry")
entry.set_ltr_mode() 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( self.longitude = MonitoredEntry(
entry, entry,
self.source.set_longitude, self.source.get_longitude, self.source.set_longitude, self.source.get_longitude,
@ -163,6 +167,9 @@ class EditPlaceRef(EditReference):
entry = self.top.get_object("lat_entry") entry = self.top.get_object("lat_entry")
entry.set_ltr_mode() 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( self.latitude = MonitoredEntry(
entry, entry,
self.source.set_latitude, self.source.get_latitude, self.source.set_latitude, self.source.get_latitude,
@ -311,6 +318,13 @@ class EditPlaceRef(EditReference):
self.ok_button.set_sensitive(True) self.ok_button.set_sensitive(True)
return 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: if self.source.handle:
with DbTxn(_("Modify Place"), self.db) as trans: with DbTxn(_("Modify Place"), self.db) as trans:
self.db.commit_place(self.source, trans) self.db.commit_place(self.source, trans)