From 8222d4c04c1da50df4d2c8ac2073e1e58adc74d2 Mon Sep 17 00:00:00 2001 From: John Ralls Date: Sun, 24 Feb 2013 00:55:46 +0000 Subject: [PATCH] [r21275]GrampsLocale: Replace locale functions locale.strcoll, locale.strxfrm, and conv*_tosrtkey With GrampsLocale.sort_key (for strxfrm and conv*_tosrtkey) and GrampsLocale.strcoll. If ICU is available will use the correct ICU::Collator for the locale, otherwise falls back to locale.strxfrm -- for which it temporarily changes the LC_COLLATE locale. svn: r21416 --- gramps/gen/db/read.py | 24 ++++----- gramps/gen/db/write.py | 11 ++-- gramps/gen/sort.py | 38 +++++++------- gramps/gen/utils/cast.py | 50 ------------------- gramps/gen/utils/grampslocale.py | 50 +++++++++++++++++++ gramps/gui/autocomp.py | 6 +-- gramps/gui/editors/displaytabs/surnametab.py | 5 +- gramps/gui/editors/filtereditor.py | 3 +- .../gui/views/treemodels/citationbasemodel.py | 1 + gramps/gui/views/treemodels/eventmodel.py | 1 + gramps/gui/views/treemodels/familymodel.py | 4 +- gramps/gui/views/treemodels/flatbasemodel.py | 10 ++-- gramps/gui/views/treemodels/mediamodel.py | 4 +- gramps/gui/views/treemodels/notemodel.py | 4 +- gramps/gui/views/treemodels/peoplemodel.py | 4 +- gramps/gui/views/treemodels/repomodel.py | 2 +- gramps/gui/views/treemodels/sourcemodel.py | 1 + gramps/gui/views/treemodels/treebasemodel.py | 16 ++---- gramps/gui/widgets/monitoredwidgets.py | 5 +- gramps/plugins/lib/libgrdb.py | 16 +++--- gramps/plugins/textreport/ancestorreport.py | 2 +- .../plugins/textreport/detancestralreport.py | 2 +- .../plugins/textreport/detdescendantreport.py | 2 +- gramps/plugins/tool/changetypes.py | 8 ++- gramps/plugins/tool/notrelated.py | 9 +--- gramps/plugins/webreport/narrativeweb.py | 5 +- 26 files changed, 130 insertions(+), 153 deletions(-) diff --git a/gramps/gen/db/read.py b/gramps/gen/db/read.py index 657bdf514..21f3506d8 100644 --- a/gramps/gen/db/read.py +++ b/gramps/gen/db/read.py @@ -40,7 +40,6 @@ else: import pickle import time import random -import locale import os from sys import maxsize @@ -81,6 +80,7 @@ from . import (BsddbBaseCursor, DbReadBase) from ..utils.id import create_id from ..errors import DbError from ..constfunc import UNITYPE, STRTYPE, cuni +from ..const import GRAMPS_LOCALE as glocale LOG = logging.getLogger(DBLOGNAME) LOG = logging.getLogger(".citation") @@ -1642,7 +1642,7 @@ class DbBsddbRead(DbReadBase, Callback): def __sortbyperson_key(self, handle): if isinstance(handle, UNITYPE): handle = handle.encode('utf-8') - return locale.strxfrm(find_surname(handle, + return glocale.sort_key(find_surname(handle, self.person_map.get(handle))) def __sortbyplace(self, first, second): @@ -1650,13 +1650,13 @@ class DbBsddbRead(DbReadBase, Callback): first = first.encode('utf-8') if isinstance(second, UNITYPE): second = second.encode('utf-8') - return locale.strcoll(self.place_map.get(first)[2], + return glocale.strcoll(self.place_map.get(first)[2], self.place_map.get(second)[2]) def __sortbyplace_key(self, place): if isinstance(place, UNITYPE): place = place.encode('utf-8') - return locale.strxfrm(self.place_map.get(place)[2]) + return glocale.sort_key(self.place_map.get(place)[2]) def __sortbysource(self, first, second): if isinstance(first, UNITYPE): @@ -1665,13 +1665,13 @@ class DbBsddbRead(DbReadBase, Callback): second = second.encode('utf-8') source1 = cuni(self.source_map[first][2]) source2 = cuni(self.source_map[second][2]) - return locale.strcoll(source1, source2) + return glocale.strcoll(source1, source2) def __sortbysource_key(self, key): if isinstance(key, UNITYPE): key = key.encode('utf-8') source = cuni(self.source_map[key][2]) - return locale.strxfrm(source) + return glocale.sort_key(source) def __sortbycitation(self, first, second): if isinstance(first, UNITYPE): @@ -1680,13 +1680,13 @@ class DbBsddbRead(DbReadBase, Callback): second = second.encode('utf-8') citation1 = cuni(self.citation_map[first][3]) citation2 = cuni(self.citation_map[second][3]) - return locale.strcoll(citation1, citation2) + return glocale.strcoll(citation1, citation2) def __sortbycitation_key(self, key): if isinstance(key, UNITYPE): key = key.encode('utf-8') citation = cuni(self.citation_map[key][3]) - return locale.strxfrm(citation) + return glocale.sort_key(citation) def __sortbymedia(self, first, second): if isinstance(first, UNITYPE): @@ -1695,13 +1695,13 @@ class DbBsddbRead(DbReadBase, Callback): second = second.encode('utf-8') media1 = self.media_map[first][4] media2 = self.media_map[second][4] - return locale.strcoll(media1, media2) + return glocale.strcoll(media1, media2) def __sortbymedia_key(self, key): if isinstance(key, UNITYPE): key = key.encode('utf-8') media = self.media_map[key][4] - return locale.strxfrm(media) + return glocale.sort_key(media) def __sortbytag(self, first, second): if isinstance(first, UNITYPE): @@ -1710,13 +1710,13 @@ class DbBsddbRead(DbReadBase, Callback): second = second.encode('utf-8') tag1 = self.tag_map[first][1] tag2 = self.tag_map[second][1] - return locale.strcoll(tag1, tag2) + return glocale.strcoll(tag1, tag2) def __sortbytag_key(self, key): if isinstance(key, UNITYPE): key = key.encode('utf-8') tag = self.tag_map[key][1] - return locale.strxfrm(tag) + return glocale.sort_key(tag) def set_mediapath(self, path): """Set the default media path for database, path should be utf-8.""" diff --git a/gramps/gen/db/write.py b/gramps/gen/db/write.py index 417bb557c..8e4b29afd 100644 --- a/gramps/gen/db/write.py +++ b/gramps/gen/db/write.py @@ -40,14 +40,11 @@ else: import pickle import os import time -import locale import bisect from functools import wraps import logging from sys import maxsize -from ..const import GRAMPS_LOCALE as glocale -_ = glocale.get_translation().gettext from ..config import config if config.get('preferences.use-bsddb3') or sys.version_info[0] >= 3: from bsddb3 import dbshelve, db @@ -78,10 +75,12 @@ from . import (DbBsddbRead, DbWriteBase, BSDDBTxn, find_byte_surname, find_surname_name, DbUndoBSDDB as DbUndo) from .dbconst import * from ..utils.callback import Callback -from ..utils.cast import (conv_unicode_tosrtkey, conv_dbstr_to_unicode) +from ..utils.cast import conv_dbstr_to_unicode from ..updatecallback import UpdateCallback from ..errors import DbError from ..constfunc import win, conv_to_unicode, cuni, UNITYPE, handle2internal +from ..const import GRAMPS_LOCALE as glocale +_ = glocale.get_translation().gettext _LOG = logging.getLogger(DBLOGNAME) LOG = logging.getLogger(".citation") @@ -1499,7 +1498,7 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback): self.emit('person-groupname-rebuild', (name, grouppar)) def sort_surname_list(self): - self.surname_list.sort(key=conv_unicode_tosrtkey) + self.surname_list.sort(key=glocale.sort_key) @catch_db_error def build_surname_list(self): @@ -1511,7 +1510,7 @@ class DbBsddb(DbBsddbRead, DbWriteBase, UpdateCallback): #TODO GTK3: Why double conversion? Convert to a list of str objects! self.surname_list = sorted( map(conv_dbstr_to_unicode, set(self.surnames.keys())), - key=conv_unicode_tosrtkey) + key=glocale.sort_key) def add_to_surname_list(self, person, batch_transaction): """ diff --git a/gramps/gen/sort.py b/gramps/gen/sort.py index 14dd635f4..ceb3f9e2b 100644 --- a/gramps/gen/sort.py +++ b/gramps/gen/sort.py @@ -32,7 +32,6 @@ to make sure these remain in sync with the rest of the design. # Standard python modules # #------------------------------------------------------------------------- -import locale #------------------------------------------------------------------------- # @@ -42,6 +41,7 @@ import locale from .lib import Date from .utils.db import get_birth_or_fallback from .display.name import displayer as _nd +from .const import GRAMPS_LOCALE as glocale #------------------------------------------------------------------------- # @@ -70,11 +70,11 @@ class Sort(object): ## ffn = name1.get_first_name() ## sfn = name2.get_first_name() ## if ffn == sfn: -## return locale.strcoll(name1.get_suffix(), name2.get_suffix()) +## return glocale.strcoll(name1.get_suffix(), name2.get_suffix()) ## else: -## return locale.strcoll(ffn, sfn) +## return glocale.strcoll(ffn, sfn) ## else: -## return locale.strcoll(fsn, ssn) +## return glocale.strcoll(fsn, ssn) def by_last_name_key(self, first_id): """Sort routine for comparing two last names. If last names are equal, @@ -86,7 +86,7 @@ class Sort(object): fsn = name1.get_surname() ffn = name1.get_first_name() fsu = name1.get_suffix() - return locale.strxfrm(fsn + ffn + fsu) + return glocale.sort_key(fsn + ffn + fsu) ## def by_sorted_name(self, first_id, second_id): ## """ @@ -99,7 +99,7 @@ class Sort(object): ## name1 = _nd.sorted(first) ## name2 = _nd.sorted(second) ## -## return locale.strcoll(name1, name2) +## return glocale.strcoll(name1, name2) def by_sorted_name_key(self, first_id): """ @@ -110,7 +110,7 @@ class Sort(object): name1 = _nd.sorted(first) - return locale.strxfrm(name1) + return glocale.sort_key(name1) ## def by_birthdate(self, first_id, second_id): ## """Sort routine for comparing two people by birth dates. If the birth dates @@ -175,14 +175,14 @@ class Sort(object): ## return 0 ## a_obj = self.database.get_place_from_handle(a_id) ## b_obj = self.database.get_place_from_handle(b_id) -## return locale.strcoll(a_obj.title, b_obj.title) +## return glocale.strcoll(a_obj.title, b_obj.title) def by_place_title_key(self, a_id): """Sort routine for comparing two places. """ if not a_id: return 0 a_obj = self.database.get_place_from_handle(a_id) - return locale.strxfrm(a_obj.title) + return glocale.sort_key(a_obj.title) ## def by_event_place(self, a_id, b_id): ## """Sort routine for comparing two events by their places. """ @@ -198,7 +198,7 @@ class Sort(object): ## plc_a_title = plc_a.title ## if plc_b: ## plc_b_title = plc_b.title -## return locale.strcoll(plc_a_title, plc_b_title) +## return glocale.strcoll(plc_a_title, plc_b_title) def by_event_place_key(self, a_id): """Sort routine for comparing two events by their places. """ @@ -207,7 +207,7 @@ class Sort(object): evt_a = self.database.get_event_from_handle(a_id) plc_a = self.database.get_place_from_handle(evt_a.get_place_handle()) plc_a_title = plc_a.title if plc_a else "" - return locale.strxfrm(plc_a_title) + return glocale.sort_key(plc_a_title) ## def by_event_description(self, a_id, b_id): ## """Sort routine for comparing two events by their descriptions. """ @@ -215,14 +215,14 @@ class Sort(object): ## return 0 ## evt_a = self.database.get_event_from_handle(a_id) ## evt_b = self.database.get_event_from_handle(b_id) -## return locale.strcoll(evt_a.get_description(), evt_b.get_description()) +## return glocale.strcoll(evt_a.get_description(), evt_b.get_description()) def by_event_description_key(self, a_id): """Sort routine for comparing two events by their descriptions. """ if not a_id: return 0 evt_a = self.database.get_event_from_handle(a_id) - return locale.strxfrm(evt_a.get_description()) + return glocale.sort_key(evt_a.get_description()) ## def by_event_id(self, a_id, b_id): ## """Sort routine for comparing two events by their ID. """ @@ -230,14 +230,14 @@ class Sort(object): ## return 0 ## evt_a = self.database.get_event_from_handle(a_id) ## evt_b = self.database.get_event_from_handle(b_id) -## return locale.strcoll(evt_a.get_gramps_id(), evt_b.get_gramps_id()) +## return glocale.strcoll(evt_a.get_gramps_id(), evt_b.get_gramps_id()) def by_event_id_key(self, a_id): """Sort routine for comparing two events by their ID. """ if not a_id: return 0 evt_a = self.database.get_event_from_handle(a_id) - return locale.strxfrm(evt_a.get_gramps_id()) + return glocale.sort_key(evt_a.get_gramps_id()) ## def by_event_type(self, a_id, b_id): ## """Sort routine for comparing two events by their type. """ @@ -245,14 +245,14 @@ class Sort(object): ## return 0 ## evt_a = self.database.get_event_from_handle(a_id) ## evt_b = self.database.get_event_from_handle(b_id) -## return locale.strcoll(str(evt_a.get_type()), str(evt_b.get_type())) +## return glocale.strcoll(str(evt_a.get_type()), str(evt_b.get_type())) def by_event_type_key(self, a_id): """Sort routine for comparing two events by their type. """ if not a_id: return 0 evt_a = self.database.get_event_from_handle(a_id) - return locale.strxfrm(str(evt_a.get_type())) + return glocale.sort_key(str(evt_a.get_type())) ## def by_media_title(self,a_id,b_id): ## """Sort routine for comparing two media objects by their title. """ @@ -260,11 +260,11 @@ class Sort(object): ## return False ## a = self.database.get_object_from_handle(a_id) ## b = self.database.get_object_from_handle(b_id) -## return locale.strcoll(a.desc, b.desc) +## return glocale.strcoll(a.desc, b.desc) def by_media_title_key(self, a_id): """Sort routine for comparing two media objects by their title. """ if not a_id: return False a = self.database.get_object_from_handle(a_id) - return locale.strxfrm(a.desc) + return glocale.sort_key(a.desc) diff --git a/gramps/gen/utils/cast.py b/gramps/gen/utils/cast.py index 697af3751..684137b24 100644 --- a/gramps/gen/utils/cast.py +++ b/gramps/gen/utils/cast.py @@ -45,56 +45,6 @@ LOG = logging.getLogger(".") from ..datehandler import codeset from ..constfunc import conv_to_unicode, conv_to_unicode_direct, UNITYPE, STRTYPE -try: - import PyICU - if os.environ.has_key("LC_COLLATE"): - collation = os.environ['LC_COLLATE'] - else: - collation = os.environ["LANG"] - language_and_country = collation.rsplit('.', 1)[0] - if language_and_country in PyICU.Collator.getAvailableLocales().keys(): - loc = language_and_country - else: - language = collation.rsplit('_', 1)[0] - if language in PyICU.Collator.getAvailableLocales().keys(): - LOG.warn(_("Language and country %s not supported by ICU: " - "but language %s is supported and will be used" % - (language_and_country, language))) - loc = language - else: - LOG.warn(_("Neither Language and country %s nor language %s " - "supported by ICU: using en_GB" % - (language_and_country, language))) - loc = "en_GB" - - collator = PyICU.Collator.createInstance(PyICU.Locale(loc)) - # on ICU, the functions need to receive unicode - conv_unicode_tosrtkey = lambda x: collator.getCollationKey( - x).getByteArray() - conv_str_tosrtkey = lambda x: collator.getCollationKey( - x.decode("UTF-8")).getByteArray() -except: - """ - strxfrm needs it's unicode argument correctly cast before used. - """ - if sys.version_info[0] < 3: - conv_unicode_tosrtkey = lambda x: locale.strxfrm(x.encode(codeset, 'replace')) - else: - conv_unicode_tosrtkey = lambda x: locale.strxfrm(x) - - if codeset == 'UTF-8': - conv_str_tosrtkey = lambda x: locale.strxfrm(x) - else: - conv_str_tosrtkey = lambda x: locale.strxfrm( - conv_to_unicode(x,'UTF-8').encode(codeset, 'replace')) - -def conv_tosrtkey(value): - if isinstance(value, UNITYPE): - return conv_unicode_tosrtkey(value) - elif not isinstance(value, STRTYPE): - return conv_str_tosrtkey(str(value)) - return conv_str_tosrtkey(value) - #strings in database are utf-8 conv_dbstr_to_unicode = lambda x: conv_to_unicode(x, 'UTF-8') diff --git a/gramps/gen/utils/grampslocale.py b/gramps/gen/utils/grampslocale.py index c8b549e6d..5108f0058 100644 --- a/gramps/gen/utils/grampslocale.py +++ b/gramps/gen/utils/grampslocale.py @@ -32,6 +32,13 @@ import os import locale import logging LOG = logging.getLogger("gramps.gen.util.grampslocale") +LOG.addHandler(logging.StreamHandler()) +HAVE_ICU = False +try: + from icu import Locale, Collator + HAVE_ICU = True +except ImportError as err: + LOG.warning("ICU is not installed because %s, localization will be impaired", str(err)) #------------------------------------------------------------------------- # # gramps modules @@ -239,6 +246,19 @@ class GrampsLocale(object): if len(self.language) == 0: self.language = self._GrampsLocale__first_instance.language + self.icu_locales = {} + self.collator = None + if HAVE_ICU: + self.icu_locales["default"] = Locale.createFromName(self.lang) + if self.collation != self.lang: + self.icu_locales["collation"] = Locale.createFromName(self.collation) + else: + self.icu_locales["collation"] = self.icu_locales["default"] + try: + self.collator = Collator.createInstance(self.icu_locales["collation"]) + except ICUError as err: + LOG.warning("Unable to create collator: %s", str(err)) + self.collator = None self.translation = self._get_translation(self.localedomain, self.localedir, self.language) @@ -513,6 +533,36 @@ class GrampsLocale(object): return "utf-8" + def sort_key(self, string): + """ + Return a value suitable to pass to the "key" parameter of sorted() + """ + + if HAVE_ICU and self.collator: + #ICU can digest strings and unicode + return self.collator.getCollationKey(string).getByteArray() + else: + base_locale = locale.getlocale(locale.LC_COLLATE) + locale.setlocale(locale.LC_COLLATE, self.collation) + #locale in Python2 can't. + if sys.version_info[0] < 3 and isinstance(string, unicode): + key = locale.strxfrm(string.encode("utf-8", "replace")) + else: + key = locale.strxfrm(string) + + locale.setlocale(locale.LC_COLLATE, base_locale) + return key + + def strcoll(self, string1, string2): + """ + Given two localized strings, compare them and return -1 if + string1 would sort first, 1 if string2 would, and 0 if + they are the same. + """ + key1 = self.sort_key(string1) + key2 = self.sort_key(string2) + return (-1 if key1 < key2 else (1 if key1 > key2 else 0)) + #------------------------------------------------------------------------- # # Translations Classes diff --git a/gramps/gui/autocomp.py b/gramps/gui/autocomp.py index 7dacdd6ca..200d3ccbb 100644 --- a/gramps/gui/autocomp.py +++ b/gramps/gui/autocomp.py @@ -31,8 +31,6 @@ Provide autocompletion functionality. #------------------------------------------------------------------------- from __future__ import print_function -import locale - #------------------------------------------------------------------------- # # GNOME modules @@ -41,8 +39,8 @@ import locale from gi.repository import Gtk from gi.repository import GObject - from gramps.gen.constfunc import STRTYPE +from gramps.gen.const import GRAMPS_LOCALE as glocale def fill_combo(combo, data_list): """ @@ -194,7 +192,7 @@ class StandardCustomSelector(object): """ Method for sorting keys based on the values. """ - return locale.strxfrm(self.mapping[val]) + return glocale.sort_key(self.mapping[val]) def get_values(self): """ diff --git a/gramps/gui/editors/displaytabs/surnametab.py b/gramps/gui/editors/displaytabs/surnametab.py index c36954755..93da8fd99 100644 --- a/gramps/gui/editors/displaytabs/surnametab.py +++ b/gramps/gui/editors/displaytabs/surnametab.py @@ -28,7 +28,6 @@ #------------------------------------------------------------------------- from gramps.gen.const import GRAMPS_LOCALE as glocale _ = glocale.get_translation().sgettext -import locale #------------------------------------------------------------------------- # @@ -116,7 +115,7 @@ class SurnameTab(EmbeddedList): self.cmborig = Gtk.ListStore(GObject.TYPE_INT, GObject.TYPE_STRING) self.cmborigmap = no.get_map().copy() #sort the keys based on the value - keys = sorted(self.cmborigmap, key=lambda x: locale.strxfrm(self.cmborigmap[x])) + keys = sorted(self.cmborigmap, key=lambda x: glocale.sort_key(self.cmborigmap[x])) for key in keys: if key != no.get_custom(): self.cmborig.append(row=[key, self.cmborigmap[key]]) @@ -162,7 +161,7 @@ class SurnameTab(EmbeddedList): ## """ ## fvalue = self.cmborigmap[first] ## svalue = self.cmborigmap[second] -## return locale.strcoll(fvalue, svalue) +## return glocale.strcoll(fvalue, svalue) def get_data(self): return self.obj.get_surname_list() diff --git a/gramps/gui/editors/filtereditor.py b/gramps/gui/editors/filtereditor.py index 9e963d5bd..68187183f 100644 --- a/gramps/gui/editors/filtereditor.py +++ b/gramps/gui/editors/filtereditor.py @@ -30,7 +30,6 @@ Custom Filter Editor tool. # Python modules # #------------------------------------------------------------------------- -import locale #------------------------------------------------------------------------ # @@ -903,7 +902,7 @@ class ShowResults(ManagedWindow): new_list = sorted( (self.sort_val_from_handle(h) for h in handle_list), - key=lambda x: locale.strxfrm(x[0]) + key=lambda x: glocale.sort_key(x[0]) ) for s_, handle in new_list: diff --git a/gramps/gui/views/treemodels/citationbasemodel.py b/gramps/gui/views/treemodels/citationbasemodel.py index abbf7a0fe..6782a8c0c 100644 --- a/gramps/gui/views/treemodels/citationbasemodel.py +++ b/gramps/gui/views/treemodels/citationbasemodel.py @@ -44,6 +44,7 @@ from gramps.gen.lib import Citation from gramps.gen.utils.string import confidence from gramps.gen.config import config from gramps.gen.constfunc import cuni +from gramps.gen.const import GRAMPS_LOCALE as glocale #------------------------------------------------------------------------- # diff --git a/gramps/gui/views/treemodels/eventmodel.py b/gramps/gui/views/treemodels/eventmodel.py index c35332a31..2dd057b4a 100644 --- a/gramps/gui/views/treemodels/eventmodel.py +++ b/gramps/gui/views/treemodels/eventmodel.py @@ -46,6 +46,7 @@ from gramps.gen.utils.db import get_participant_from_event from gramps.gen.config import config from gramps.gen.constfunc import cuni from .flatbasemodel import FlatBaseModel +from gramps.gen.const import GRAMPS_LOCALE as glocale #------------------------------------------------------------------------- # diff --git a/gramps/gui/views/treemodels/familymodel.py b/gramps/gui/views/treemodels/familymodel.py index 9d658ca66..dcfa42d59 100644 --- a/gramps/gui/views/treemodels/familymodel.py +++ b/gramps/gui/views/treemodels/familymodel.py @@ -27,7 +27,6 @@ #------------------------------------------------------------------------- import logging log = logging.getLogger(".") -import locale #------------------------------------------------------------------------- # @@ -48,6 +47,7 @@ from .flatbasemodel import FlatBaseModel from gramps.gen.utils.db import get_marriage_or_fallback from gramps.gen.config import config from gramps.gen.constfunc import cuni +from gramps.gen.const import GRAMPS_LOCALE as glocale invalid_date_format = config.get('preferences.invalid-date-format') @@ -200,4 +200,4 @@ class FamilyModel(FlatBaseModel): Return the sorted list of tags. """ tag_list = list(map(self.get_tag_name, data[13])) - return ', '.join(sorted(tag_list, key=locale.strxfrm)) + return ', '.join(sorted(tag_list, key=glocale.sort_key)) diff --git a/gramps/gui/views/treemodels/flatbasemodel.py b/gramps/gui/views/treemodels/flatbasemodel.py index 0bf1993da..8551426d8 100644 --- a/gramps/gui/views/treemodels/flatbasemodel.py +++ b/gramps/gui/views/treemodels/flatbasemodel.py @@ -75,9 +75,9 @@ from gi.repository import Gtk # #------------------------------------------------------------------------- from gramps.gen.filters import SearchFilter, ExactSearchFilter -from gramps.gen.utils.cast import conv_unicode_tosrtkey, conv_tosrtkey from gramps.gen.constfunc import cuni, UNITYPE, conv_to_unicode, handle2internal - +from gramps.gen.const import GRAMPS_LOCALE as glocale + #------------------------------------------------------------------------- # # FlatNodeMap @@ -112,7 +112,7 @@ class FlatNodeMap(object): the path, and a dictionary mapping hndl to index. To obtain index given a path, method real_index() is available - ..Note: conv_unicode_tosrtkey is applied to the underlying sort key, + ..Note: glocale.sort_key is applied to the underlying sort key, so as to have localized sort """ @@ -456,7 +456,7 @@ class FlatBaseModel(GObject.Object, Gtk.TreeModel): """ The base class for all flat treeview models. It keeps a FlatNodeMap, and obtains data from database as needed - ..Note: conv_unicode_tosrtkey is applied to the underlying sort key, + ..Note: glocale.sort_key is applied to the underlying sort key, so as to have localized sort """ @@ -482,7 +482,7 @@ class FlatBaseModel(GObject.Object, Gtk.TreeModel): col = self.sort_map[scol][1] else: col = scol - self.sort_func = lambda x: conv_unicode_tosrtkey(self.smap[col](x)) + self.sort_func = lambda x: glocale.sort_key(self.smap[col](x)) self.sort_col = scol self.skip = skip self._in_build = False diff --git a/gramps/gui/views/treemodels/mediamodel.py b/gramps/gui/views/treemodels/mediamodel.py index f4cc84098..a7e0306a9 100644 --- a/gramps/gui/views/treemodels/mediamodel.py +++ b/gramps/gui/views/treemodels/mediamodel.py @@ -29,7 +29,6 @@ from gramps.gen.const import GRAMPS_LOCALE as glocale _ = glocale.get_translation().gettext import logging log = logging.getLogger(".") -import locale #------------------------------------------------------------------------- # @@ -46,6 +45,7 @@ from gi.repository import Gtk from gramps.gen.datehandler import displayer, format_time from gramps.gen.lib import Date, MediaObject from gramps.gen.constfunc import cuni, conv_to_unicode, UNITYPE +from gramps.gen.const import GRAMPS_LOCALE as glocale from .flatbasemodel import FlatBaseModel #------------------------------------------------------------------------- @@ -196,4 +196,4 @@ class MediaModel(FlatBaseModel): Return the sorted list of tags. """ tag_list = list(map(self.get_tag_name, data[10])) - return ', '.join(sorted(tag_list, key=locale.strxfrm)) + return ', '.join(sorted(tag_list, key=glocale.sort_key)) diff --git a/gramps/gui/views/treemodels/notemodel.py b/gramps/gui/views/treemodels/notemodel.py index 29290537f..0188beb29 100644 --- a/gramps/gui/views/treemodels/notemodel.py +++ b/gramps/gui/views/treemodels/notemodel.py @@ -27,7 +27,6 @@ #------------------------------------------------------------------------- import logging _LOG = logging.getLogger(".gui.notemodel") -import locale #------------------------------------------------------------------------- # @@ -43,6 +42,7 @@ from gi.repository import Gtk #------------------------------------------------------------------------- from gramps.gen.datehandler import format_time from gramps.gen.constfunc import cuni +from gramps.gen.const import GRAMPS_LOCALE as glocale from .flatbasemodel import FlatBaseModel from gramps.gen.lib import (Note, NoteType, StyledText) @@ -161,4 +161,4 @@ class NoteModel(FlatBaseModel): Return the sorted list of tags. """ tag_list = list(map(self.get_tag_name, data[Note.POS_TAGS])) - return ', '.join(sorted(tag_list, key=locale.strxfrm)) + return ', '.join(sorted(tag_list, key=glocale.sort_key)) diff --git a/gramps/gui/views/treemodels/peoplemodel.py b/gramps/gui/views/treemodels/peoplemodel.py index 9b7228dc3..1948312be 100644 --- a/gramps/gui/views/treemodels/peoplemodel.py +++ b/gramps/gui/views/treemodels/peoplemodel.py @@ -33,7 +33,6 @@ TreeModel for the GRAMPS Person tree. # #------------------------------------------------------------------------- import cgi -import locale #------------------------------------------------------------------------- # @@ -65,6 +64,7 @@ from .flatbasemodel import FlatBaseModel from .treebasemodel import TreeBaseModel from gramps.gen.config import config from gramps.gen.constfunc import cuni, UNITYPE +from gramps.gen.const import GRAMPS_LOCALE as glocale #------------------------------------------------------------------------- # @@ -460,7 +460,7 @@ class PeopleBaseModel(object): Return the sorted list of tags. """ tag_list = list(map(self.get_tag_name, data[COLUMN_TAGS])) - return ', '.join(sorted(tag_list, key=locale.strxfrm)) + return ', '.join(sorted(tag_list, key=glocale.sort_key)) class PersonListModel(PeopleBaseModel, FlatBaseModel): """ diff --git a/gramps/gui/views/treemodels/repomodel.py b/gramps/gui/views/treemodels/repomodel.py index 975189711..142cac4ea 100644 --- a/gramps/gui/views/treemodels/repomodel.py +++ b/gramps/gui/views/treemodels/repomodel.py @@ -43,7 +43,7 @@ from gramps.gen.lib import Address, RepositoryType, Url, UrlType from gramps.gen.datehandler import format_time from gramps.gen.constfunc import cuni from .flatbasemodel import FlatBaseModel - +from gramps.gen.const import GRAMPS_LOCALE as glocale #------------------------------------------------------------------------- # # RepositoryModel diff --git a/gramps/gui/views/treemodels/sourcemodel.py b/gramps/gui/views/treemodels/sourcemodel.py index 25a5ace49..42f5fcc8a 100644 --- a/gramps/gui/views/treemodels/sourcemodel.py +++ b/gramps/gui/views/treemodels/sourcemodel.py @@ -42,6 +42,7 @@ from gi.repository import Gtk from gramps.gen.datehandler import format_time from gramps.gen.constfunc import cuni from .flatbasemodel import FlatBaseModel +from gramps.gen.const import GRAMPS_LOCALE as glocale #------------------------------------------------------------------------- # diff --git a/gramps/gui/views/treemodels/treebasemodel.py b/gramps/gui/views/treemodels/treebasemodel.py index daa943e83..71db3b19a 100644 --- a/gramps/gui/views/treemodels/treebasemodel.py +++ b/gramps/gui/views/treemodels/treebasemodel.py @@ -57,7 +57,7 @@ from gi.repository import Gtk # GRAMPS modules # #------------------------------------------------------------------------- -from gramps.gen.utils.cast import conv_str_tosrtkey, conv_unicode_tosrtkey +from gramps.gen.const import GRAMPS_LOCALE as glocale import gramps.gui.widgets.progressdialog as progressdlg from gramps.gen.constfunc import cuni, UNITYPE from .lru import LRU @@ -91,17 +91,9 @@ class Node(object): def __init__(self, ref, parent, sortkey, handle, secondary): if sortkey: - if isinstance(sortkey, UNITYPE): - self.name = sortkey - #sortkey must be localized sort, so - self.sortkey = conv_unicode_tosrtkey(sortkey) - else: - self.name = sortkey.decode('utf-8') - #sortkey must be localized sort, so - if sys.version_info[0] < 3: - self.sortkey = conv_str_tosrtkey(sortkey) - else: - self.sortkey = conv_unicode_tosrtkey(self.name) + self.name = sortkey + #sortkey must be localized sort, so + self.sortkey = glocale.sort_key(sortkey) else: self.name = '' self.sortkey = '' diff --git a/gramps/gui/widgets/monitoredwidgets.py b/gramps/gui/widgets/monitoredwidgets.py index 643e5fb72..0aec13ae3 100644 --- a/gramps/gui/widgets/monitoredwidgets.py +++ b/gramps/gui/widgets/monitoredwidgets.py @@ -34,7 +34,6 @@ __all__ = ["MonitoredCheckbox", "MonitoredEntry", #------------------------------------------------------------------------- import logging _LOG = logging.getLogger(".widgets.monitoredwidgets") -import locale import sys #------------------------------------------------------------------------- @@ -749,13 +748,13 @@ class MonitoredComboSelectedEntry(object): """ fvalue = self.mapping[first] svalue = self.mapping[second] - return locale.strcoll(fvalue, svalue) + return glocale.strcoll(fvalue, svalue) def __by_value_key(self, first): """ Method for sorting keys based on the values. """ - return locale.strxfrm(self.mapping[first]) + return glocale.sort_key(self.mapping[first]) def on_combochange(self, obj): """ diff --git a/gramps/plugins/lib/libgrdb.py b/gramps/plugins/lib/libgrdb.py index 0a7944199..470c9e826 100644 --- a/gramps/plugins/lib/libgrdb.py +++ b/gramps/plugins/lib/libgrdb.py @@ -37,7 +37,6 @@ else: import pickle import time import random -import locale import os from sys import maxsize from gramps.gen.config import config @@ -60,6 +59,7 @@ from gramps.gen.lib import (MediaObject, Person, Family, Source, Event, Place, Repository, Note, GenderStats, Researcher) from gramps.gen.utils.callback import Callback from gramps.gen.constfunc import STRTYPE, cuni +from gramps.gen.const import GRAMPS_LOCALE as glocale #------------------------------------------------------------------------- # @@ -1888,7 +1888,7 @@ class DbGrdb(Callback): raise NotImplementedError def sort_surname_list(self): - self.surname_list.sort(key=locale.strxfrm) + self.surname_list.sort(key=glocale.sort_key) def add_to_surname_list(self, person, batch_transaction): if batch_transaction: @@ -2267,29 +2267,29 @@ class DbGrdb(Callback): return str(handle) in self.note_map def __sortbyplace(self, first, second): - return locale.strcoll(self.place_map.get(str(first))[2], + return glocale.strcoll(self.place_map.get(str(first))[2], self.place_map.get(str(second))[2]) def __sortbyplace_key(self, place): - return locale.strxfrm(self.place_map.get(str(place))[2]) + return glocale.sort_key(self.place_map.get(str(place))[2]) def __sortbysource(self, first, second): source1 = cuni(self.source_map[str(first)][2]) source2 = cuni(self.source_map[str(second)][2]) - return locale.strcoll(source1, source2) + return glocale.strcoll(source1, source2) def __sortbysource_key(self, key): source = cuni(self.source_map[str(key)][2]) - return locale.strxfrm(source) + return glocale.sort_key(source) def __sortbymedia(self, first, second): media1 = self.media_map[str(first)][4] media2 = self.media_map[str(second)][4] - return locale.strcoll(media1, media2) + return glocale.strcoll(media1, media2) def __sortbymedia_key(self, key): media = self.media_map[str(key)][4] - return locale.strxfrm(media) + return glocale.sort_key(media) def set_mediapath(self, path): """Set the default media path for database, path should be utf-8.""" diff --git a/gramps/plugins/textreport/ancestorreport.py b/gramps/plugins/textreport/ancestorreport.py index c5ea761dc..089459b16 100644 --- a/gramps/plugins/textreport/ancestorreport.py +++ b/gramps/plugins/textreport/ancestorreport.py @@ -301,7 +301,7 @@ class AncestorOptions(MenuReportOptions): Translator.DEFAULT_TRANSLATION_STR) trans.add_item(Translator.DEFAULT_TRANSLATION_STR, _("Default")) languages = glocale.get_language_dict() - for language in sorted(languages): + for language in sorted(languages, key=glocale.sort_key): trans.add_item(languages[language], language) trans.set_help(_("The translation to be used for the report.")) menu.add_option(category_name, "trans", trans) diff --git a/gramps/plugins/textreport/detancestralreport.py b/gramps/plugins/textreport/detancestralreport.py index 0d1e51040..b5291b2de 100644 --- a/gramps/plugins/textreport/detancestralreport.py +++ b/gramps/plugins/textreport/detancestralreport.py @@ -755,7 +755,7 @@ class DetAncestorOptions(MenuReportOptions): Translator.DEFAULT_TRANSLATION_STR) trans.add_item(Translator.DEFAULT_TRANSLATION_STR, _("Default")) languages = glocale.get_language_dict() - for language in sorted(languages): + for language in sorted(languages, key=glocale.sort_key): trans.add_item(languages[language], language) trans.set_help(_("The translation to be used for the report.")) addopt("trans", trans) diff --git a/gramps/plugins/textreport/detdescendantreport.py b/gramps/plugins/textreport/detdescendantreport.py index 160028270..b536737aa 100644 --- a/gramps/plugins/textreport/detdescendantreport.py +++ b/gramps/plugins/textreport/detdescendantreport.py @@ -930,7 +930,7 @@ class DetDescendantOptions(MenuReportOptions): Translator.DEFAULT_TRANSLATION_STR) trans.add_item(Translator.DEFAULT_TRANSLATION_STR, _("Default")) languages = glocale.get_language_dict() - for language in sorted(languages): + for language in sorted(languages, key=glocale.sort_key): trans.add_item(languages[language], language) trans.set_help(_("The translation to be used for the report.")) add_option("trans", trans) diff --git a/gramps/plugins/tool/changetypes.py b/gramps/plugins/tool/changetypes.py index 20f06a7f2..20365749e 100644 --- a/gramps/plugins/tool/changetypes.py +++ b/gramps/plugins/tool/changetypes.py @@ -31,16 +31,14 @@ #------------------------------------------------------------------------ from __future__ import print_function -from gramps.gen.const import GRAMPS_LOCALE as glocale -_ = glocale.get_translation().gettext - #------------------------------------------------------------------------ # # GRAMPS modules # #------------------------------------------------------------------------ from gramps.gui.utils import ProgressMeter -import locale +from gramps.gen.const import GRAMPS_LOCALE as glocale +_ = glocale.get_translation().gettext from gramps.gui.managedwindow import ManagedWindow from gramps.gui.autocomp import fill_combo from gramps.gen.lib import EventType @@ -80,7 +78,7 @@ class ChangeTypes(tool.BatchTool, ManagedWindow): # Need to display localized event names etype = EventType() - event_names = sorted(etype.get_standard_names(), key=locale.strxfrm) + event_names = sorted(etype.get_standard_names(), key=glocale.sort_key) fill_combo(self.auto1,event_names) fill_combo(self.auto2,event_names) diff --git a/gramps/plugins/tool/notrelated.py b/gramps/plugins/tool/notrelated.py index e1e799abe..18ea718ab 100644 --- a/gramps/plugins/tool/notrelated.py +++ b/gramps/plugins/tool/notrelated.py @@ -25,13 +25,6 @@ "Find people who are not related to the selected person" -#------------------------------------------------------------------------ -# -# Python modules -# -#------------------------------------------------------------------------ -import locale - #------------------------------------------------------------------------ # # GNOME/GTK modules @@ -472,7 +465,7 @@ class NotRelated(tool.ActivePersonTool, ManagedWindow) : for handle in person.get_tag_list(): tag = self.db.get_tag_from_handle(handle) tags.append(tag.get_name()) - tags.sort(key=locale.strxfrm) + tags.sort(key=glocale.sort_key) return ', '.join(tags) #------------------------------------------------------------------------ diff --git a/gramps/plugins/webreport/narrativeweb.py b/gramps/plugins/webreport/narrativeweb.py index bc0980588..8ff9d9c78 100644 --- a/gramps/plugins/webreport/narrativeweb.py +++ b/gramps/plugins/webreport/narrativeweb.py @@ -125,7 +125,6 @@ from gramps.gen.utils.string import confidence from gramps.gen.utils.file import media_path_full from gramps.gen.utils.alive import probably_alive from gramps.gen.utils.db import get_source_and_citation_referents -from gramps.gen.utils.cast import conv_unicode_tosrtkey, conv_tosrtkey from gramps.gen.constfunc import win, cuni, conv_to_unicode, UNITYPE from gramps.gen.config import config from gramps.gui.thumbnails import get_thumbnail_path, run_thumbnailer @@ -154,7 +153,7 @@ from gramps.gen.relationship import get_relationship_calculator # the language for translation. import locale COLLATE_LANG = locale.getlocale()[0] -SORT_KEY = conv_unicode_tosrtkey +SORT_KEY = glocale.sort_key #------------------------------------------------ # Everything below this point is identical for gramps34 (post 3.4.2), gramps40 and trunk #------------------------------------------------ @@ -8464,8 +8463,6 @@ def sort_people(dbase, handle_list): sname_sub[surname].append(person_handle) sorted_lists = [] - # According to the comment in flatbasemodel: This list is sorted - # ascending, via localized string sort. SORT_KEY temp_list = sorted(sname_sub, key=SORT_KEY) for name in temp_list: