diff --git a/gramps/gen/utils/place.py b/gramps/gen/utils/place.py index 910232df8..9c29a141e 100644 --- a/gramps/gen/utils/place.py +++ b/gramps/gen/utils/place.py @@ -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: diff --git a/gramps/gui/editors/editplace.py b/gramps/gui/editors/editplace.py index 38730b81c..e95b053c0 100644 --- a/gramps/gui/editors/editplace.py +++ b/gramps/gui/editors/editplace.py @@ -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: diff --git a/gramps/gui/editors/editplaceref.py b/gramps/gui/editors/editplaceref.py index 34d2e2619..2531c25b1 100644 --- a/gramps/gui/editors/editplaceref.py +++ b/gramps/gui/editors/editplaceref.py @@ -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)