From 38be0d13830efd2d98281c645c3a60afe05ffece Mon Sep 17 00:00:00 2001 From: Qt by Nokia Date: Wed, 27 Apr 2011 12:05:43 +0200 Subject: Initial import from the monolithic Qt. This is the beginning of revision history for this module. If you want to look at revision history older than this, please refer to the Qt Git wiki for how to use Git history grafting. At the time of writing, this wiki is located here: http://qt.gitorious.org/qt/pages/GitIntroductionWithQt If you have already performed the grafting and you don't see any history beyond this commit, try running "git log" with the "--follow" argument. Branched from the monolithic repo, Qt master branch, at commit 896db169ea224deb96c59ce8af800d019de63f12 --- util/local_database/README | 1 + util/local_database/cldr2qlocalexml.py | 810 +++++++++++++++++++++ util/local_database/dateconverter.py | 120 ++++ util/local_database/enumdata.py | 544 ++++++++++++++ util/local_database/formattags.txt | 23 + util/local_database/qlocalexml2cpp.py | 877 +++++++++++++++++++++++ util/local_database/testlocales/localemodel.cpp | 462 ++++++++++++ util/local_database/testlocales/localemodel.h | 69 ++ util/local_database/testlocales/localewidget.cpp | 89 +++ util/local_database/testlocales/localewidget.h | 59 ++ util/local_database/testlocales/main.cpp | 51 ++ util/local_database/testlocales/testlocales.pro | 4 + util/local_database/xpathlite.py | 249 +++++++ 13 files changed, 3358 insertions(+) create mode 100644 util/local_database/README create mode 100755 util/local_database/cldr2qlocalexml.py create mode 100755 util/local_database/dateconverter.py create mode 100644 util/local_database/enumdata.py create mode 100644 util/local_database/formattags.txt create mode 100755 util/local_database/qlocalexml2cpp.py create mode 100644 util/local_database/testlocales/localemodel.cpp create mode 100644 util/local_database/testlocales/localemodel.h create mode 100644 util/local_database/testlocales/localewidget.cpp create mode 100644 util/local_database/testlocales/localewidget.h create mode 100644 util/local_database/testlocales/main.cpp create mode 100644 util/local_database/testlocales/testlocales.pro create mode 100644 util/local_database/xpathlite.py (limited to 'util/local_database') diff --git a/util/local_database/README b/util/local_database/README new file mode 100644 index 0000000000..23b6a33ad8 --- /dev/null +++ b/util/local_database/README @@ -0,0 +1 @@ +local_database is used to generate qlocale data from the Common Locale Data Repository (The database for localized names (like date formats, country names etc)). diff --git a/util/local_database/cldr2qlocalexml.py b/util/local_database/cldr2qlocalexml.py new file mode 100755 index 0000000000..f0f9cb1ead --- /dev/null +++ b/util/local_database/cldr2qlocalexml.py @@ -0,0 +1,810 @@ +#!/usr/bin/env python +############################################################################# +## +## Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +## All rights reserved. +## Contact: Nokia Corporation (qt-info@nokia.com) +## +## This file is part of the test suite of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:LGPL$ +## No Commercial Usage +## This file contains pre-release code and may not be distributed. +## You may use this file in accordance with the terms and conditions +## contained in the Technology Preview License Agreement accompanying +## this package. +## +## GNU Lesser General Public License Usage +## Alternatively, this file may be used under the terms of the GNU Lesser +## General Public License version 2.1 as published by the Free Software +## Foundation and appearing in the file LICENSE.LGPL included in the +## packaging of this file. Please review the following information to +## ensure the GNU Lesser General Public License version 2.1 requirements +## will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +## +## In addition, as a special exception, Nokia gives you certain additional +## rights. These rights are described in the Nokia Qt LGPL Exception +## version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +## +## If you have questions regarding the use of this file, please contact +## Nokia at qt-info@nokia.com. +## +## +## +## +## +## +## +## +## $QT_END_LICENSE$ +## +############################################################################# + +import os +import sys +import enumdata +import xpathlite +from xpathlite import DraftResolution +from dateconverter import convert_date +import re + +findEntry = xpathlite.findEntry +findEntryInFile = xpathlite._findEntryInFile +findTagsInFile = xpathlite.findTagsInFile + +def parse_number_format(patterns, data): + # this is a very limited parsing of the number format for currency only. + def skip_repeating_pattern(x): + p = x.replace('0', '#').replace(',', '').replace('.', '') + seen = False + result = '' + for c in p: + if c == '#': + if seen: + continue + seen = True + else: + seen = False + result = result + c + return result + patterns = patterns.split(';') + result = [] + for pattern in patterns: + pattern = skip_repeating_pattern(pattern) + pattern = pattern.replace('#', "%1") + # according to http://www.unicode.org/reports/tr35/#Number_Format_Patterns + # there can be doubled or trippled currency sign, however none of the + # locales use that. + pattern = pattern.replace(u'\xa4', "%2") + pattern = pattern.replace("''", "###").replace("'", '').replace("###", "'") + pattern = pattern.replace('-', data['minus']) + pattern = pattern.replace('+', data['plus']) + result.append(pattern) + return result + +def parse_list_pattern_part_format(pattern): + # this is a very limited parsing of the format for list pattern part only. + result = "" + result = pattern.replace("{0}", "%1") + result = result.replace("{1}", "%2") + result = result.replace("{2}", "%3") + return result + +def ordStr(c): + if len(c) == 1: + return str(ord(c)) + return "##########" + +# the following functions are supposed to fix the problem with QLocale +# returning a character instead of strings for QLocale::exponential() +# and others. So we fallback to default values in these cases. +def fixOrdStrExp(c): + if len(c) == 1: + return str(ord(c)) + return str(ord('e')) +def fixOrdStrPercent(c): + if len(c) == 1: + return str(ord(c)) + return str(ord('%')) +def fixOrdStrList(c): + if len(c) == 1: + return str(ord(c)) + return str(ord(';')) + +def generateLocaleInfo(path): + (dir_name, file_name) = os.path.split(path) + + if not path.endswith(".xml"): + return {} + language_code = findEntryInFile(path, "identity/language", attribute="type")[0] + if language_code == 'root': + # just skip it + return {} + country_code = findEntryInFile(path, "identity/territory", attribute="type")[0] + script_code = findEntryInFile(path, "identity/script", attribute="type")[0] + variant_code = findEntryInFile(path, "identity/variant", attribute="type")[0] + + # we should handle fully qualified names with the territory + if not country_code: + return {} + + # we do not support variants + # ### actually there is only one locale with variant: en_US_POSIX + # does anybody care about it at all? + if variant_code: + return {} + + language_id = enumdata.languageCodeToId(language_code) + if language_id == -1: + sys.stderr.write("unnknown language code \"" + language_code + "\"\n") + return {} + language = enumdata.language_list[language_id][0] + + script_id = enumdata.scriptCodeToId(script_code) + if script_code == -1: + sys.stderr.write("unnknown script code \"" + script_code + "\"\n") + return {} + script = "AnyScript" + if script_id != -1: + script = enumdata.script_list[script_id][0] + + country_id = enumdata.countryCodeToId(country_code) + country = "" + if country_id != -1: + country = enumdata.country_list[country_id][0] + if country == "": + sys.stderr.write("unnknown country code \"" + country_code + "\"\n") + return {} + + # So we say we accept only those values that have "contributed" or + # "approved" resolution. see http://www.unicode.org/cldr/process.html + # But we only respect the resolution for new datas for backward + # compatibility. + draft = DraftResolution.contributed + + result = {} + result['language'] = language + result['script'] = script + result['country'] = country + result['language_code'] = language_code + result['country_code'] = country_code + result['script_code'] = script_code + result['variant_code'] = variant_code + result['language_id'] = language_id + result['script_id'] = script_id + result['country_id'] = country_id + + supplementalPath = dir_name + "/../supplemental/supplementalData.xml" + currencies = findTagsInFile(supplementalPath, "currencyData/region[iso3166=%s]"%country_code); + result['currencyIsoCode'] = '' + result['currencyDigits'] = 2 + result['currencyRounding'] = 1 + if currencies: + for e in currencies: + if e[0] == 'currency': + tender = True + t = filter(lambda x: x[0] == 'tender', e[1]) + if t and t[0][1] == 'false': + tender = False; + if tender and not filter(lambda x: x[0] == 'to', e[1]): + result['currencyIsoCode'] = filter(lambda x: x[0] == 'iso4217', e[1])[0][1] + break + if result['currencyIsoCode']: + t = findTagsInFile(supplementalPath, "currencyData/fractions/info[iso4217=%s]"%result['currencyIsoCode']); + if t and t[0][0] == 'info': + result['currencyDigits'] = int(filter(lambda x: x[0] == 'digits', t[0][1])[0][1]) + result['currencyRounding'] = int(filter(lambda x: x[0] == 'rounding', t[0][1])[0][1]) + numbering_system = None + try: + numbering_system = findEntry(path, "numbers/defaultNumberingSystem") + except: + pass + def findEntryDef(path, xpath, value=''): + try: + return findEntry(path, xpath) + except xpathlite.Error: + return value + def get_number_in_system(path, xpath, numbering_system): + if numbering_system: + try: + return findEntry(path, xpath + "[numberSystem=" + numbering_system + "]") + except xpathlite.Error: + pass + return findEntry(path, xpath) + result['decimal'] = get_number_in_system(path, "numbers/symbols/decimal", numbering_system) + result['group'] = get_number_in_system(path, "numbers/symbols/group", numbering_system) + result['list'] = get_number_in_system(path, "numbers/symbols/list", numbering_system) + result['percent'] = get_number_in_system(path, "numbers/symbols/percentSign", numbering_system) + result['zero'] = get_number_in_system(path, "numbers/symbols/nativeZeroDigit", numbering_system) + result['minus'] = get_number_in_system(path, "numbers/symbols/minusSign", numbering_system) + result['plus'] = get_number_in_system(path, "numbers/symbols/plusSign", numbering_system) + result['exp'] = get_number_in_system(path, "numbers/symbols/exponential", numbering_system).lower() + result['quotationStart'] = findEntry(path, "delimiters/quotationStart") + result['quotationEnd'] = findEntry(path, "delimiters/quotationEnd") + result['alternateQuotationStart'] = findEntry(path, "delimiters/alternateQuotationStart") + result['alternateQuotationEnd'] = findEntry(path, "delimiters/alternateQuotationEnd") + result['listPatternPartStart'] = parse_list_pattern_part_format(findEntry(path, "listPatterns/listPattern/listPatternPart[start]")) + result['listPatternPartMiddle'] = parse_list_pattern_part_format(findEntry(path, "listPatterns/listPattern/listPatternPart[middle]")) + result['listPatternPartEnd'] = parse_list_pattern_part_format(findEntry(path, "listPatterns/listPattern/listPatternPart[end]")) + result['listPatternPartTwo'] = parse_list_pattern_part_format(findEntry(path, "listPatterns/listPattern/listPatternPart[2]")) + result['am'] = findEntry(path, "dates/calendars/calendar[gregorian]/dayPeriods/dayPeriodContext[format]/dayPeriodWidth[wide]/dayPeriod[am]", draft) + result['pm'] = findEntry(path, "dates/calendars/calendar[gregorian]/dayPeriods/dayPeriodContext[format]/dayPeriodWidth[wide]/dayPeriod[pm]", draft) + result['longDateFormat'] = convert_date(findEntry(path, "dates/calendars/calendar[gregorian]/dateFormats/dateFormatLength[full]/dateFormat/pattern")) + result['shortDateFormat'] = convert_date(findEntry(path, "dates/calendars/calendar[gregorian]/dateFormats/dateFormatLength[short]/dateFormat/pattern")) + result['longTimeFormat'] = convert_date(findEntry(path, "dates/calendars/calendar[gregorian]/timeFormats/timeFormatLength[full]/timeFormat/pattern")) + result['shortTimeFormat'] = convert_date(findEntry(path, "dates/calendars/calendar[gregorian]/timeFormats/timeFormatLength[short]/timeFormat/pattern")) + + endonym = None + if country_code and script_code: + endonym = findEntryDef(path, "localeDisplayNames/languages/language[type=%s_%s_%s]" % (language_code, script_code, country_code)) + if not endonym and script_code: + endonym = findEntryDef(path, "localeDisplayNames/languages/language[type=%s_%s]" % (language_code, script_code)) + if not endonym and country_code: + endonym = findEntryDef(path, "localeDisplayNames/languages/language[type=%s_%s]" % (language_code, country_code)) + if not endonym: + endonym = findEntryDef(path, "localeDisplayNames/languages/language[type=%s]" % (language_code)) + result['language_endonym'] = endonym + result['country_endonym'] = findEntryDef(path, "localeDisplayNames/territories/territory[type=%s]" % (country_code)) + + currency_format = get_number_in_system(path, "numbers/currencyFormats/currencyFormatLength/currencyFormat/pattern", numbering_system) + currency_format = parse_number_format(currency_format, result) + result['currencyFormat'] = currency_format[0] + result['currencyNegativeFormat'] = '' + if len(currency_format) > 1: + result['currencyNegativeFormat'] = currency_format[1] + + result['currencySymbol'] = '' + result['currencyDisplayName'] = '' + if result['currencyIsoCode']: + result['currencySymbol'] = findEntryDef(path, "numbers/currencies/currency[%s]/symbol" % result['currencyIsoCode']) + display_name_path = "numbers/currencies/currency[%s]/displayName" % result['currencyIsoCode'] + result['currencyDisplayName'] \ + = findEntryDef(path, display_name_path) + ";" \ + + findEntryDef(path, display_name_path + "[count=zero]") + ";" \ + + findEntryDef(path, display_name_path + "[count=one]") + ";" \ + + findEntryDef(path, display_name_path + "[count=two]") + ";" \ + + findEntryDef(path, display_name_path + "[count=few]") + ";" \ + + findEntryDef(path, display_name_path + "[count=many]") + ";" \ + + findEntryDef(path, display_name_path + "[count=other]") + ";" + + standalone_long_month_path = "dates/calendars/calendar[gregorian]/months/monthContext[stand-alone]/monthWidth[wide]/month" + result['standaloneLongMonths'] \ + = findEntry(path, standalone_long_month_path + "[1]") + ";" \ + + findEntry(path, standalone_long_month_path + "[2]") + ";" \ + + findEntry(path, standalone_long_month_path + "[3]") + ";" \ + + findEntry(path, standalone_long_month_path + "[4]") + ";" \ + + findEntry(path, standalone_long_month_path + "[5]") + ";" \ + + findEntry(path, standalone_long_month_path + "[6]") + ";" \ + + findEntry(path, standalone_long_month_path + "[7]") + ";" \ + + findEntry(path, standalone_long_month_path + "[8]") + ";" \ + + findEntry(path, standalone_long_month_path + "[9]") + ";" \ + + findEntry(path, standalone_long_month_path + "[10]") + ";" \ + + findEntry(path, standalone_long_month_path + "[11]") + ";" \ + + findEntry(path, standalone_long_month_path + "[12]") + ";" + + standalone_short_month_path = "dates/calendars/calendar[gregorian]/months/monthContext[stand-alone]/monthWidth[abbreviated]/month" + result['standaloneShortMonths'] \ + = findEntry(path, standalone_short_month_path + "[1]") + ";" \ + + findEntry(path, standalone_short_month_path + "[2]") + ";" \ + + findEntry(path, standalone_short_month_path + "[3]") + ";" \ + + findEntry(path, standalone_short_month_path + "[4]") + ";" \ + + findEntry(path, standalone_short_month_path + "[5]") + ";" \ + + findEntry(path, standalone_short_month_path + "[6]") + ";" \ + + findEntry(path, standalone_short_month_path + "[7]") + ";" \ + + findEntry(path, standalone_short_month_path + "[8]") + ";" \ + + findEntry(path, standalone_short_month_path + "[9]") + ";" \ + + findEntry(path, standalone_short_month_path + "[10]") + ";" \ + + findEntry(path, standalone_short_month_path + "[11]") + ";" \ + + findEntry(path, standalone_short_month_path + "[12]") + ";" + + standalone_narrow_month_path = "dates/calendars/calendar[gregorian]/months/monthContext[stand-alone]/monthWidth[narrow]/month" + result['standaloneNarrowMonths'] \ + = findEntry(path, standalone_narrow_month_path + "[1]") + ";" \ + + findEntry(path, standalone_narrow_month_path + "[2]") + ";" \ + + findEntry(path, standalone_narrow_month_path + "[3]") + ";" \ + + findEntry(path, standalone_narrow_month_path + "[4]") + ";" \ + + findEntry(path, standalone_narrow_month_path + "[5]") + ";" \ + + findEntry(path, standalone_narrow_month_path + "[6]") + ";" \ + + findEntry(path, standalone_narrow_month_path + "[7]") + ";" \ + + findEntry(path, standalone_narrow_month_path + "[8]") + ";" \ + + findEntry(path, standalone_narrow_month_path + "[9]") + ";" \ + + findEntry(path, standalone_narrow_month_path + "[10]") + ";" \ + + findEntry(path, standalone_narrow_month_path + "[11]") + ";" \ + + findEntry(path, standalone_narrow_month_path + "[12]") + ";" + + long_month_path = "dates/calendars/calendar[gregorian]/months/monthContext[format]/monthWidth[wide]/month" + result['longMonths'] \ + = findEntry(path, long_month_path + "[1]") + ";" \ + + findEntry(path, long_month_path + "[2]") + ";" \ + + findEntry(path, long_month_path + "[3]") + ";" \ + + findEntry(path, long_month_path + "[4]") + ";" \ + + findEntry(path, long_month_path + "[5]") + ";" \ + + findEntry(path, long_month_path + "[6]") + ";" \ + + findEntry(path, long_month_path + "[7]") + ";" \ + + findEntry(path, long_month_path + "[8]") + ";" \ + + findEntry(path, long_month_path + "[9]") + ";" \ + + findEntry(path, long_month_path + "[10]") + ";" \ + + findEntry(path, long_month_path + "[11]") + ";" \ + + findEntry(path, long_month_path + "[12]") + ";" + + short_month_path = "dates/calendars/calendar[gregorian]/months/monthContext[format]/monthWidth[abbreviated]/month" + result['shortMonths'] \ + = findEntry(path, short_month_path + "[1]") + ";" \ + + findEntry(path, short_month_path + "[2]") + ";" \ + + findEntry(path, short_month_path + "[3]") + ";" \ + + findEntry(path, short_month_path + "[4]") + ";" \ + + findEntry(path, short_month_path + "[5]") + ";" \ + + findEntry(path, short_month_path + "[6]") + ";" \ + + findEntry(path, short_month_path + "[7]") + ";" \ + + findEntry(path, short_month_path + "[8]") + ";" \ + + findEntry(path, short_month_path + "[9]") + ";" \ + + findEntry(path, short_month_path + "[10]") + ";" \ + + findEntry(path, short_month_path + "[11]") + ";" \ + + findEntry(path, short_month_path + "[12]") + ";" + + narrow_month_path = "dates/calendars/calendar[gregorian]/months/monthContext[format]/monthWidth[narrow]/month" + result['narrowMonths'] \ + = findEntry(path, narrow_month_path + "[1]") + ";" \ + + findEntry(path, narrow_month_path + "[2]") + ";" \ + + findEntry(path, narrow_month_path + "[3]") + ";" \ + + findEntry(path, narrow_month_path + "[4]") + ";" \ + + findEntry(path, narrow_month_path + "[5]") + ";" \ + + findEntry(path, narrow_month_path + "[6]") + ";" \ + + findEntry(path, narrow_month_path + "[7]") + ";" \ + + findEntry(path, narrow_month_path + "[8]") + ";" \ + + findEntry(path, narrow_month_path + "[9]") + ";" \ + + findEntry(path, narrow_month_path + "[10]") + ";" \ + + findEntry(path, narrow_month_path + "[11]") + ";" \ + + findEntry(path, narrow_month_path + "[12]") + ";" + + long_day_path = "dates/calendars/calendar[gregorian]/days/dayContext[format]/dayWidth[wide]/day" + result['longDays'] \ + = findEntry(path, long_day_path + "[sun]") + ";" \ + + findEntry(path, long_day_path + "[mon]") + ";" \ + + findEntry(path, long_day_path + "[tue]") + ";" \ + + findEntry(path, long_day_path + "[wed]") + ";" \ + + findEntry(path, long_day_path + "[thu]") + ";" \ + + findEntry(path, long_day_path + "[fri]") + ";" \ + + findEntry(path, long_day_path + "[sat]") + ";" + + short_day_path = "dates/calendars/calendar[gregorian]/days/dayContext[format]/dayWidth[abbreviated]/day" + result['shortDays'] \ + = findEntry(path, short_day_path + "[sun]") + ";" \ + + findEntry(path, short_day_path + "[mon]") + ";" \ + + findEntry(path, short_day_path + "[tue]") + ";" \ + + findEntry(path, short_day_path + "[wed]") + ";" \ + + findEntry(path, short_day_path + "[thu]") + ";" \ + + findEntry(path, short_day_path + "[fri]") + ";" \ + + findEntry(path, short_day_path + "[sat]") + ";" + + narrow_day_path = "dates/calendars/calendar[gregorian]/days/dayContext[format]/dayWidth[narrow]/day" + result['narrowDays'] \ + = findEntry(path, narrow_day_path + "[sun]") + ";" \ + + findEntry(path, narrow_day_path + "[mon]") + ";" \ + + findEntry(path, narrow_day_path + "[tue]") + ";" \ + + findEntry(path, narrow_day_path + "[wed]") + ";" \ + + findEntry(path, narrow_day_path + "[thu]") + ";" \ + + findEntry(path, narrow_day_path + "[fri]") + ";" \ + + findEntry(path, narrow_day_path + "[sat]") + ";" + + standalone_long_day_path = "dates/calendars/calendar[gregorian]/days/dayContext[stand-alone]/dayWidth[wide]/day" + result['standaloneLongDays'] \ + = findEntry(path, standalone_long_day_path + "[sun]") + ";" \ + + findEntry(path, standalone_long_day_path + "[mon]") + ";" \ + + findEntry(path, standalone_long_day_path + "[tue]") + ";" \ + + findEntry(path, standalone_long_day_path + "[wed]") + ";" \ + + findEntry(path, standalone_long_day_path + "[thu]") + ";" \ + + findEntry(path, standalone_long_day_path + "[fri]") + ";" \ + + findEntry(path, standalone_long_day_path + "[sat]") + ";" + + standalone_short_day_path = "dates/calendars/calendar[gregorian]/days/dayContext[stand-alone]/dayWidth[abbreviated]/day" + result['standaloneShortDays'] \ + = findEntry(path, standalone_short_day_path + "[sun]") + ";" \ + + findEntry(path, standalone_short_day_path + "[mon]") + ";" \ + + findEntry(path, standalone_short_day_path + "[tue]") + ";" \ + + findEntry(path, standalone_short_day_path + "[wed]") + ";" \ + + findEntry(path, standalone_short_day_path + "[thu]") + ";" \ + + findEntry(path, standalone_short_day_path + "[fri]") + ";" \ + + findEntry(path, standalone_short_day_path + "[sat]") + ";" + + standalone_narrow_day_path = "dates/calendars/calendar[gregorian]/days/dayContext[stand-alone]/dayWidth[narrow]/day" + result['standaloneNarrowDays'] \ + = findEntry(path, standalone_narrow_day_path + "[sun]") + ";" \ + + findEntry(path, standalone_narrow_day_path + "[mon]") + ";" \ + + findEntry(path, standalone_narrow_day_path + "[tue]") + ";" \ + + findEntry(path, standalone_narrow_day_path + "[wed]") + ";" \ + + findEntry(path, standalone_narrow_day_path + "[thu]") + ";" \ + + findEntry(path, standalone_narrow_day_path + "[fri]") + ";" \ + + findEntry(path, standalone_narrow_day_path + "[sat]") + ";" + + return result + +def addEscapes(s): + result = '' + for c in s: + n = ord(c) + if n < 128: + result += c + else: + result += "\\x" + result += "%02x" % (n) + return result + +def unicodeStr(s): + utf8 = s.encode('utf-8') + return "" + str(len(utf8)) + "" + addEscapes(utf8) + "" + +def usage(): + print "Usage: cldr2qlocalexml.py " + sys.exit() + +def integrateWeekData(filePath): + if not filePath.endswith(".xml"): + return {} + monFirstDayIn = findEntryInFile(filePath, "weekData/firstDay[day=mon]", attribute="territories")[0].split(" ") + tueFirstDayIn = findEntryInFile(filePath, "weekData/firstDay[day=tue]", attribute="territories")[0].split(" ") + wedFirstDayIn = findEntryInFile(filePath, "weekData/firstDay[day=wed]", attribute="territories")[0].split(" ") + thuFirstDayIn = findEntryInFile(filePath, "weekData/firstDay[day=thu]", attribute="territories")[0].split(" ") + friFirstDayIn = findEntryInFile(filePath, "weekData/firstDay[day=fri]", attribute="territories")[0].split(" ") + satFirstDayIn = findEntryInFile(filePath, "weekData/firstDay[day=sat]", attribute="territories")[0].split(" ") + sunFirstDayIn = findEntryInFile(filePath, "weekData/firstDay[day=sun]", attribute="territories")[0].split(" ") + + monWeekendStart = findEntryInFile(filePath, "weekData/weekendStart[day=mon]", attribute="territories")[0].split(" ") + tueWeekendStart = findEntryInFile(filePath, "weekData/weekendStart[day=tue]", attribute="territories")[0].split(" ") + wedWeekendStart = findEntryInFile(filePath, "weekData/weekendStart[day=wed]", attribute="territories")[0].split(" ") + thuWeekendStart = findEntryInFile(filePath, "weekData/weekendStart[day=thu]", attribute="territories")[0].split(" ") + friWeekendStart = findEntryInFile(filePath, "weekData/weekendStart[day=fri]", attribute="territories")[0].split(" ") + satWeekendStart = findEntryInFile(filePath, "weekData/weekendStart[day=sat]", attribute="territories")[0].split(" ") + sunWeekendStart = findEntryInFile(filePath, "weekData/weekendStart[day=sun]", attribute="territories")[0].split(" ") + + monWeekendEnd = findEntryInFile(filePath, "weekData/weekendEnd[day=mon]", attribute="territories")[0].split(" ") + tueWeekendEnd = findEntryInFile(filePath, "weekData/weekendEnd[day=tue]", attribute="territories")[0].split(" ") + wedWeekendEnd = findEntryInFile(filePath, "weekData/weekendEnd[day=wed]", attribute="territories")[0].split(" ") + thuWeekendEnd = findEntryInFile(filePath, "weekData/weekendEnd[day=thu]", attribute="territories")[0].split(" ") + friWeekendEnd = findEntryInFile(filePath, "weekData/weekendEnd[day=fri]", attribute="territories")[0].split(" ") + satWeekendEnd = findEntryInFile(filePath, "weekData/weekendEnd[day=sat]", attribute="territories")[0].split(" ") + sunWeekendEnd = findEntryInFile(filePath, "weekData/weekendEnd[day=sun]", attribute="territories")[0].split(" ") + + firstDayByCountryCode = {} + for countryCode in monFirstDayIn: + firstDayByCountryCode[countryCode] = "mon" + for countryCode in tueFirstDayIn: + firstDayByCountryCode[countryCode] = "tue" + for countryCode in wedFirstDayIn: + firstDayByCountryCode[countryCode] = "wed" + for countryCode in thuFirstDayIn: + firstDayByCountryCode[countryCode] = "thu" + for countryCode in friFirstDayIn: + firstDayByCountryCode[countryCode] = "fri" + for countryCode in satFirstDayIn: + firstDayByCountryCode[countryCode] = "sat" + for countryCode in sunFirstDayIn: + firstDayByCountryCode[countryCode] = "sun" + + weekendStartByCountryCode = {} + for countryCode in monWeekendStart: + weekendStartByCountryCode[countryCode] = "mon" + for countryCode in tueWeekendStart: + weekendStartByCountryCode[countryCode] = "tue" + for countryCode in wedWeekendStart: + weekendStartByCountryCode[countryCode] = "wed" + for countryCode in thuWeekendStart: + weekendStartByCountryCode[countryCode] = "thu" + for countryCode in friWeekendStart: + weekendStartByCountryCode[countryCode] = "fri" + for countryCode in satWeekendStart: + weekendStartByCountryCode[countryCode] = "sat" + for countryCode in sunWeekendStart: + weekendStartByCountryCode[countryCode] = "sun" + + weekendEndByCountryCode = {} + for countryCode in monWeekendEnd: + weekendEndByCountryCode[countryCode] = "mon" + for countryCode in tueWeekendEnd: + weekendEndByCountryCode[countryCode] = "tue" + for countryCode in wedWeekendEnd: + weekendEndByCountryCode[countryCode] = "wed" + for countryCode in thuWeekendEnd: + weekendEndByCountryCode[countryCode] = "thu" + for countryCode in friWeekendEnd: + weekendEndByCountryCode[countryCode] = "fri" + for countryCode in satWeekendEnd: + weekendEndByCountryCode[countryCode] = "sat" + for countryCode in sunWeekendEnd: + weekendEndByCountryCode[countryCode] = "sun" + + for (key,locale) in locale_database.iteritems(): + countryCode = locale['country_code'] + if countryCode in firstDayByCountryCode: + locale_database[key]['firstDayOfWeek'] = firstDayByCountryCode[countryCode] + else: + locale_database[key]['firstDayOfWeek'] = firstDayByCountryCode["001"] + + if countryCode in weekendStartByCountryCode: + locale_database[key]['weekendStart'] = weekendStartByCountryCode[countryCode] + else: + locale_database[key]['weekendStart'] = weekendStartByCountryCode["001"] + + if countryCode in weekendEndByCountryCode: + locale_database[key]['weekendEnd'] = weekendEndByCountryCode[countryCode] + else: + locale_database[key]['weekendEnd'] = weekendEndByCountryCode["001"] + +if len(sys.argv) != 2: + usage() + +cldr_dir = sys.argv[1] + +if not os.path.isdir(cldr_dir): + usage() + +cldr_files = os.listdir(cldr_dir) + +locale_database = {} +for file in cldr_files: + l = generateLocaleInfo(cldr_dir + "/" + file) + if not l: + sys.stderr.write("skipping file \"" + file + "\"\n") + continue + + locale_database[(l['language_id'], l['script_id'], l['country_id'], l['variant_code'])] = l + +integrateWeekData(cldr_dir+"/../supplemental/supplementalData.xml") +locale_keys = locale_database.keys() +locale_keys.sort() + +cldr_version = 'unknown' +ldml = open(cldr_dir+"/../dtd/ldml.dtd", "r") +for line in ldml: + if 'version cldrVersion CDATA #FIXED' in line: + cldr_version = line.split('"')[1] + +print "" +print " " + cldr_version + "" +print " " +for id in enumdata.language_list: + l = enumdata.language_list[id] + print " " + print " " + l[0] + "" + print " " + str(id) + "" + print " " + l[1] + "" + print " " +print " " + +print " " +for id in enumdata.script_list: + l = enumdata.script_list[id] + print " " +print " " + +print " " +for id in enumdata.country_list: + l = enumdata.country_list[id] + print " " + print " " + l[0] + "" + print " " + str(id) + "" + print " " + l[1] + "" + print " " +print " " + +print \ +" \n\ + \n\ + Afrikaans\n\ + SouthAfrica\n\ + \n\ + \n\ + Afan\n\ + Ethiopia\n\ + \n\ + \n\ + Afar\n\ + Djibouti\n\ + \n\ + \n\ + Arabic\n\ + SaudiArabia\n\ + \n\ + \n\ + Chinese\n\ + China\n\ + \n\ + \n\ + Dutch\n\ + Netherlands\n\ + \n\ + \n\ + English\n\ + UnitedStates\n\ + \n\ + \n\ + French\n\ + France\n\ + \n\ + \n\ + German\n\ + Germany\n\ + \n\ + \n\ + Greek\n\ + Greece\n\ + \n\ + \n\ + Italian\n\ + Italy\n\ + \n\ + \n\ + Malay\n\ + Malaysia\n\ + \n\ + \n\ + Portuguese\n\ + Portugal\n\ + \n\ + \n\ + Russian\n\ + RussianFederation\n\ + \n\ + \n\ + Serbian\n\ + SerbiaAndMontenegro\n\ + \n\ + \n\ + SerboCroatian\n\ + SerbiaAndMontenegro\n\ + \n\ + \n\ + Somali\n\ + Somalia\n\ + \n\ + \n\ + Spanish\n\ + Spain\n\ + \n\ + \n\ + Swahili\n\ + Kenya\n\ + \n\ + \n\ + Swedish\n\ + Sweden\n\ + \n\ + \n\ + Tigrinya\n\ + Eritrea\n\ + \n\ + \n\ + Uzbek\n\ + Uzbekistan\n\ + \n\ + \n\ + Persian\n\ + Iran\n\ + \n\ + \n\ + Mongolian\n\ + Mongolia\n\ + \n\ + \n\ + Nepali\n\ + Nepal\n\ + \n\ + " + +print " " +print \ +" \n\ + C\n\ + \n\ + \n\ + AnyCountry\n\ + \n\ + 46\n\ + 44\n\ + 59\n\ + 37\n\ + 48\n\ + 45\n\ + 43\n\ + 101\n\ + \"\n\ + \"\n\ + \'\n\ + \'\n\ + %1, %2\n\ + %1, %2\n\ + %1, %2\n\ + %1, %2\n\ + AM\n\ + PM\n\ + mon\n\ + sat\n\ + sun\n\ + EEEE, d MMMM yyyy\n\ + d MMM yyyy\n\ + HH:mm:ss z\n\ + HH:mm:ss\n\ + January;February;March;April;May;June;July;August;September;October;November;December;\n\ + Jan;Feb;Mar;Apr;May;Jun;Jul;Aug;Sep;Oct;Nov;Dec;\n\ + J;F;M;A;M;J;J;A;S;O;N;D;\n\ + January;February;March;April;May;June;July;August;September;October;November;December;\n\ + Jan;Feb;Mar;Apr;May;Jun;Jul;Aug;Sep;Oct;Nov;Dec;\n\ + 1;2;3;4;5;6;7;8;9;10;11;12;\n\ + Sunday;Monday;Tuesday;Wednesday;Thursday;Friday;Saturday;\n\ + Sun;Mon;Tue;Wed;Thu;Fri;Sat;\n\ + 7;1;2;3;4;5;6;\n\ + Sunday;Monday;Tuesday;Wednesday;Thursday;Friday;Saturday;\n\ + Sun;Mon;Tue;Wed;Thu;Fri;Sat;\n\ + S;M;T;W;T;F;S;\n\ + \n\ + \n\ + ;;;;;;;\n\ + 2\n\ + 1\n\ + %1%2\n\ + \n\ + " + +for key in locale_keys: + l = locale_database[key] + + print " " + print " " + l['language'] + "" + print " " + l['language_endonym'].encode('utf-8') + "" + print " " + print " " + l['country'] + "" + print " " + l['country_endonym'].encode('utf-8') + "" + print " " + l['language_code'] + "" + print " " + l['script_code'] + "" + print " " + l['country_code'] + "" + print " " + ordStr(l['decimal']) + "" + print " " + ordStr(l['group']) + "" + print " " + fixOrdStrList(l['list']) + "" + print " " + fixOrdStrPercent(l['percent']) + "" + print " " + ordStr(l['zero']) + "" + print " " + ordStr(l['minus']) + "" + print " " + ordStr(l['plus']) + "" + print " " + fixOrdStrExp(l['exp']) + "" + print " " + l['quotationStart'].encode('utf-8') + "" + print " " + l['quotationEnd'].encode('utf-8') + "" + print " " + l['alternateQuotationStart'].encode('utf-8') + "" + print " " + l['alternateQuotationEnd'].encode('utf-8') + "" + print " " + l['listPatternPartStart'].encode('utf-8') + "" + print " " + l['listPatternPartMiddle'].encode('utf-8') + "" + print " " + l['listPatternPartEnd'].encode('utf-8') + "" + print " " + l['listPatternPartTwo'].encode('utf-8') + "" + print " " + l['am'].encode('utf-8') + "" + print " " + l['pm'].encode('utf-8') + "" + print " " + l['firstDayOfWeek'].encode('utf-8') + "" + print " " + l['weekendStart'].encode('utf-8') + "" + print " " + l['weekendEnd'].encode('utf-8') + "" + print " " + l['longDateFormat'].encode('utf-8') + "" + print " " + l['shortDateFormat'].encode('utf-8') + "" + print " " + l['longTimeFormat'].encode('utf-8') + "" + print " " + l['shortTimeFormat'].encode('utf-8') + "" + print " " + l['standaloneLongMonths'].encode('utf-8') + "" + print " "+ l['standaloneShortMonths'].encode('utf-8') + "" + print " "+ l['standaloneNarrowMonths'].encode('utf-8') + "" + print " " + l['longMonths'].encode('utf-8') + "" + print " " + l['shortMonths'].encode('utf-8') + "" + print " " + l['narrowMonths'].encode('utf-8') + "" + print " " + l['longDays'].encode('utf-8') + "" + print " " + l['shortDays'].encode('utf-8') + "" + print " " + l['narrowDays'].encode('utf-8') + "" + print " " + l['standaloneLongDays'].encode('utf-8') + "" + print " " + l['standaloneShortDays'].encode('utf-8') + "" + print " " + l['standaloneNarrowDays'].encode('utf-8') + "" + print " " + l['currencyIsoCode'].encode('utf-8') + "" + print " " + l['currencySymbol'].encode('utf-8') + "" + print " " + l['currencyDisplayName'].encode('utf-8') + "" + print " " + str(l['currencyDigits']) + "" + print " " + str(l['currencyRounding']) + "" + print " " + l['currencyFormat'].encode('utf-8') + "" + print " " + l['currencyNegativeFormat'].encode('utf-8') + "" + print " " +print " " +print "" diff --git a/util/local_database/dateconverter.py b/util/local_database/dateconverter.py new file mode 100755 index 0000000000..1b3db58196 --- /dev/null +++ b/util/local_database/dateconverter.py @@ -0,0 +1,120 @@ +#!/usr/bin/env python +############################################################################# +## +## Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +## All rights reserved. +## Contact: Nokia Corporation (qt-info@nokia.com) +## +## This file is part of the test suite of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:LGPL$ +## No Commercial Usage +## This file contains pre-release code and may not be distributed. +## You may use this file in accordance with the terms and conditions +## contained in the Technology Preview License Agreement accompanying +## this package. +## +## GNU Lesser General Public License Usage +## Alternatively, this file may be used under the terms of the GNU Lesser +## General Public License version 2.1 as published by the Free Software +## Foundation and appearing in the file LICENSE.LGPL included in the +## packaging of this file. Please review the following information to +## ensure the GNU Lesser General Public License version 2.1 requirements +## will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +## +## In addition, as a special exception, Nokia gives you certain additional +## rights. These rights are described in the Nokia Qt LGPL Exception +## version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +## +## If you have questions regarding the use of this file, please contact +## Nokia at qt-info@nokia.com. +## +## +## +## +## +## +## +## +## $QT_END_LICENSE$ +## +############################################################################# + +import re + +def _convert_pattern(pattern): + # patterns from http://www.unicode.org/reports/tr35/#Date_Format_Patterns + qt_regexps = { + r"yyy{3,}" : "yyyy", # more that three digits hence convert to four-digit year + r"L" : "M", # stand-alone month names. not supported. + r"g{1,}": "", # modified julian day. not supported. + r"S{1,}" : "", # fractional seconds. not supported. + r"A{1,}" : "" # milliseconds in day. not supported. + } + qt_patterns = { + "G" : "", "GG" : "", "GGG" : "", "GGGG" : "", "GGGGG" : "", # Era. not supported. + "y" : "yyyy", # four-digit year without leading zeroes + "Q" : "", "QQ" : "", "QQQ" : "", "QQQQ" : "", # quarter. not supported. + "q" : "", "qq" : "", "qqq" : "", "qqqq" : "", # quarter. not supported. + "MMMMM" : "MMM", # narrow month name. + "LLLLL" : "MMM", # stand-alone narrow month name. + "l" : "", # special symbol for chinese leap month. not supported. + "w" : "", "W" : "", # week of year/month. not supported. + "D" : "", "DD" : "", "DDD" : "", # day of year. not supported. + "F" : "", # day of week in month. not supported. + "E" : "ddd", "EE" : "ddd", "EEE" : "ddd", "EEEEE" : "ddd", "EEEE" : "dddd", # day of week + "e" : "ddd", "ee" : "ddd", "eee" : "ddd", "eeeee" : "ddd", "eeee" : "dddd", # local day of week + "c" : "ddd", "cc" : "ddd", "ccc" : "ddd", "ccccc" : "ddd", "cccc" : "dddd", # stand-alone local day of week + "a" : "AP", # AM/PM + "K" : "h", # Hour 0-11 + "k" : "H", # Hour 1-24 + "j" : "", # special reserved symbol. + "z" : "t", "zz" : "t", "zzz" : "t", "zzzz" : "t", # timezone + "Z" : "t", "ZZ" : "t", "ZZZ" : "t", "ZZZZ" : "t", # timezone + "v" : "t", "vv" : "t", "vvv" : "t", "vvvv" : "t", # timezone + "V" : "t", "VV" : "t", "VVV" : "t", "VVVV" : "t" # timezone + } + if qt_patterns.has_key(pattern): + return qt_patterns[pattern] + for r,v in qt_regexps.items(): + pattern = re.sub(r, v, pattern) + return pattern + +def convert_date(input): + result = "" + patterns = "GyYuQqMLlwWdDFgEecahHKkjmsSAzZvV" + last = "" + inquote = 0 + chars_to_strip = " -" + for c in input: + if c == "'": + inquote = inquote + 1 + if inquote % 2 == 0: + if c in patterns: + if not last: + last = c + else: + if c in last: + last += c + else: + # pattern changed + converted = _convert_pattern(last) + result += converted + if not converted: + result = result.rstrip(chars_to_strip) + last = c + continue + if last: + # pattern ended + converted = _convert_pattern(last) + result += converted + if not converted: + result = result.rstrip(chars_to_strip) + last = "" + result += c + if last: + converted = _convert_pattern(last) + result += converted + if not converted: + result = result.rstrip(chars_to_strip) + return result.lstrip(chars_to_strip) diff --git a/util/local_database/enumdata.py b/util/local_database/enumdata.py new file mode 100644 index 0000000000..9e0d7d8ddd --- /dev/null +++ b/util/local_database/enumdata.py @@ -0,0 +1,544 @@ +#!/usr/bin/env python +############################################################################# +## +## Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +## All rights reserved. +## Contact: Nokia Corporation (qt-info@nokia.com) +## +## This file is part of the test suite of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:LGPL$ +## No Commercial Usage +## This file contains pre-release code and may not be distributed. +## You may use this file in accordance with the terms and conditions +## contained in the Technology Preview License Agreement accompanying +## this package. +## +## GNU Lesser General Public License Usage +## Alternatively, this file may be used under the terms of the GNU Lesser +## General Public License version 2.1 as published by the Free Software +## Foundation and appearing in the file LICENSE.LGPL included in the +## packaging of this file. Please review the following information to +## ensure the GNU Lesser General Public License version 2.1 requirements +## will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +## +## In addition, as a special exception, Nokia gives you certain additional +## rights. These rights are described in the Nokia Qt LGPL Exception +## version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +## +## If you have questions regarding the use of this file, please contact +## Nokia at qt-info@nokia.com. +## +## +## +## +## +## +## +## +## $QT_END_LICENSE$ +## +############################################################################# + +# langugae_list and country_list reflect the current values of enums in qlocale.h +# If new xml language files are available in CLDR, these languages and countries +# need to be *appended* to this list. + +language_list = { + 0 : [ "AnyLanguage", " " ], + 1 : [ "C", " " ], + 2 : [ "Abkhazian", "ab" ], + 3 : [ "Afan", "om" ], + 4 : [ "Afar", "aa" ], + 5 : [ "Afrikaans", "af" ], + 6 : [ "Albanian", "sq" ], + 7 : [ "Amharic", "am" ], + 8 : [ "Arabic", "ar" ], + 9 : [ "Armenian", "hy" ], + 10 : [ "Assamese", "as" ], + 11 : [ "Aymara", "ay" ], + 12 : [ "Azerbaijani", "az" ], + 13 : [ "Bashkir", "ba" ], + 14 : [ "Basque", "eu" ], + 15 : [ "Bengali", "bn" ], + 16 : [ "Bhutani", "dz" ], + 17 : [ "Bihari", "bh" ], + 18 : [ "Bislama", "bi" ], + 19 : [ "Breton", "br" ], + 20 : [ "Bulgarian", "bg" ], + 21 : [ "Burmese", "my" ], + 22 : [ "Byelorussian", "be" ], + 23 : [ "Cambodian", "km" ], + 24 : [ "Catalan", "ca" ], + 25 : [ "Chinese", "zh" ], + 26 : [ "Corsican", "co" ], + 27 : [ "Croatian", "hr" ], + 28 : [ "Czech", "cs" ], + 29 : [ "Danish", "da" ], + 30 : [ "Dutch", "nl" ], + 31 : [ "English", "en" ], + 32 : [ "Esperanto", "eo" ], + 33 : [ "Estonian", "et" ], + 34 : [ "Faroese", "fo" ], + 35 : [ "Fiji", "fj" ], + 36 : [ "Finnish", "fi" ], + 37 : [ "French", "fr" ], + 38 : [ "Frisian", "fy" ], + 39 : [ "Gaelic", "gd" ], + 40 : [ "Galician", "gl" ], + 41 : [ "Georgian", "ka" ], + 42 : [ "German", "de" ], + 43 : [ "Greek", "el" ], + 44 : [ "Greenlandic", "kl" ], + 45 : [ "Guarani", "gn" ], + 46 : [ "Gujarati", "gu" ], + 47 : [ "Hausa", "ha" ], + 48 : [ "Hebrew", "he" ], + 49 : [ "Hindi", "hi" ], + 50 : [ "Hungarian", "hu" ], + 51 : [ "Icelandic", "is" ], + 52 : [ "Indonesian", "id" ], + 53 : [ "Interlingua", "ia" ], + 54 : [ "Interlingue", "ie" ], + 55 : [ "Inuktitut", "iu" ], + 56 : [ "Inupiak", "ik" ], + 57 : [ "Irish", "ga" ], + 58 : [ "Italian", "it" ], + 59 : [ "Japanese", "ja" ], + 60 : [ "Javanese", "jv" ], + 61 : [ "Kannada", "kn" ], + 62 : [ "Kashmiri", "ks" ], + 63 : [ "Kazakh", "kk" ], + 64 : [ "Kinyarwanda", "rw" ], + 65 : [ "Kirghiz", "ky" ], + 66 : [ "Korean", "ko" ], + 67 : [ "Kurdish", "ku" ], + 68 : [ "Kurundi", "rn" ], + 69 : [ "Laothian", "lo" ], + 70 : [ "Latin", "la" ], + 71 : [ "Latvian", "lv" ], + 72 : [ "Lingala", "ln" ], + 73 : [ "Lithuanian", "lt" ], + 74 : [ "Macedonian", "mk" ], + 75 : [ "Malagasy", "mg" ], + 76 : [ "Malay", "ms" ], + 77 : [ "Malayalam", "ml" ], + 78 : [ "Maltese", "mt" ], + 79 : [ "Maori", "mi" ], + 80 : [ "Marathi", "mr" ], + 81 : [ "Moldavian", "mo" ], + 82 : [ "Mongolian", "mn" ], + 83 : [ "Nauru", "na" ], + 84 : [ "Nepali", "ne" ], + 85 : [ "Norwegian", "nb" ], + 86 : [ "Occitan", "oc" ], + 87 : [ "Oriya", "or" ], + 88 : [ "Pashto", "ps" ], + 89 : [ "Persian", "fa" ], + 90 : [ "Polish", "pl" ], + 91 : [ "Portuguese", "pt" ], + 92 : [ "Punjabi", "pa" ], + 93 : [ "Quechua", "qu" ], + 94 : [ "RhaetoRomance", "rm" ], + 95 : [ "Romanian", "ro" ], + 96 : [ "Russian", "ru" ], + 97 : [ "Samoan", "sm" ], + 98 : [ "Sangho", "sg" ], + 99 : [ "Sanskrit", "sa" ], + 100 : [ "Serbian", "sr" ], + 101 : [ "SerboCroatian", "sh" ], + 102 : [ "Sesotho", "st" ], + 103 : [ "Setswana", "tn" ], + 104 : [ "Shona", "sn" ], + 105 : [ "Sindhi", "sd" ], + 106 : [ "Singhalese", "si" ], + 107 : [ "Siswati", "ss" ], + 108 : [ "Slovak", "sk" ], + 109 : [ "Slovenian", "sl" ], + 110 : [ "Somali", "so" ], + 111 : [ "Spanish", "es" ], + 112 : [ "Sundanese", "su" ], + 113 : [ "Swahili", "sw" ], + 114 : [ "Swedish", "sv" ], + 115 : [ "Tagalog", "tl" ], + 116 : [ "Tajik", "tg" ], + 117 : [ "Tamil", "ta" ], + 118 : [ "Tatar", "tt" ], + 119 : [ "Telugu", "te" ], + 120 : [ "Thai", "th" ], + 121 : [ "Tibetan", "bo" ], + 122 : [ "Tigrinya", "ti" ], + 123 : [ "Tonga", "to" ], + 124 : [ "Tsonga", "ts" ], + 125 : [ "Turkish", "tr" ], + 126 : [ "Turkmen", "tk" ], + 127 : [ "Twi", "tw" ], + 128 : [ "Uigur", "ug" ], + 129 : [ "Ukrainian", "uk" ], + 130 : [ "Urdu", "ur" ], + 131 : [ "Uzbek", "uz" ], + 132 : [ "Vietnamese", "vi" ], + 133 : [ "Volapuk", "vo" ], + 134 : [ "Welsh", "cy" ], + 135 : [ "Wolof", "wo" ], + 136 : [ "Xhosa", "xh" ], + 137 : [ "Yiddish", "yi" ], + 138 : [ "Yoruba", "yo" ], + 139 : [ "Zhuang", "za" ], + 140 : [ "Zulu", "zu" ], + 141 : [ "Nynorsk", "nn" ], + 142 : [ "Bosnian", "bs" ], + 143 : [ "Divehi", "dv" ], + 144 : [ "Manx", "gv" ], + 145 : [ "Cornish", "kw" ], + 146 : [ "Akan", "ak" ], + 147 : [ "Konkani", "kok" ], + 148 : [ "Ga", "gaa" ], + 149 : [ "Igbo", "ig" ], + 150 : [ "Kamba", "kam" ], + 151 : [ "Syriac", "syr" ], + 152 : [ "Blin", "byn" ], + 153 : [ "Geez", "gez" ], + 154 : [ "Koro", "kfo" ], + 155 : [ "Sidamo", "sid" ], + 156 : [ "Atsam", "cch" ], + 157 : [ "Tigre", "tig" ], + 158 : [ "Jju", "kaj" ], + 159 : [ "Friulian", "fur" ], + 160 : [ "Venda", "ve" ], + 161 : [ "Ewe", "ee" ], + 162 : [ "Walamo", "wal" ], + 163 : [ "Hawaiian", "haw" ], + 164 : [ "Tyap", "kcg" ], + 165 : [ "Chewa", "ny" ], + 166 : [ "Filipino", "fil" ], + 167 : [ "Swiss German", "gsw" ], + 168 : [ "Sichuan Yi", "ii" ], + 169 : [ "Kpelle", "kpe" ], + 170 : [ "Low German", "nds" ], + 171 : [ "South Ndebele", "nr" ], + 172 : [ "Northern Sotho", "nso" ], + 173 : [ "Northern Sami", "se" ], + 174 : [ "Taroko", "trv" ], + 175 : [ "Gusii", "guz" ], + 176 : [ "Taita", "dav" ], + 177 : [ "Fulah", "ff" ], + 178 : [ "Kikuyu", "ki" ], + 179 : [ "Samburu", "saq" ], + 180 : [ "Sena", "seh" ], + 181 : [ "North Ndebele", "nd" ], + 182 : [ "Rombo", "rof" ], + 183 : [ "Tachelhit", "shi" ], + 184 : [ "Kabyle", "kab" ], + 185 : [ "Nyankole", "nyn" ], + 186 : [ "Bena", "bez" ], + 187 : [ "Vunjo", "vun" ], + 188 : [ "Bambara", "bm" ], + 189 : [ "Embu", "ebu" ], + 190 : [ "Cherokee", "chr" ], + 191 : [ "Morisyen", "mfe" ], + 192 : [ "Makonde", "kde" ], + 193 : [ "Langi", "lag" ], + 194 : [ "Ganda", "lg" ], + 195 : [ "Bemba", "bem" ], + 196 : [ "Kabuverdianu", "kea" ], + 197 : [ "Meru", "mer" ], + 198 : [ "Kalenjin", "kln" ], + 199 : [ "Nama", "naq" ], + 200 : [ "Machame", "jmc" ], + 201 : [ "Colognian", "ksh" ], + 202 : [ "Masai", "mas" ], + 203 : [ "Soga", "xog" ], + 204 : [ "Luyia", "luy" ], + 205 : [ "Asu", "asa" ], + 206 : [ "Teso", "teo" ], + 207 : [ "Saho", "ssy" ], + 208 : [ "Koyra Chiini", "khq" ], + 209 : [ "Rwa", "rwk" ], + 210 : [ "Luo", "luo" ], + 211 : [ "Chiga", "cgg" ], + 212 : [ "Central Morocco Tamazight", "tzm" ], + 213 : [ "Koyraboro Senni", "ses" ], + 214 : [ "Shambala", "ksb" ] +} + +country_list = { + 0 : [ "AnyCountry", " " ], + 1 : [ "Afghanistan", "AF" ], + 2 : [ "Albania", "AL" ], + 3 : [ "Algeria", "DZ" ], + 4 : [ "AmericanSamoa", "AS" ], + 5 : [ "Andorra", "AD" ], + 6 : [ "Angola", "AO" ], + 7 : [ "Anguilla", "AI" ], + 8 : [ "Antarctica", "AQ" ], + 9 : [ "AntiguaAndBarbuda", "AG" ], + 10 : [ "Argentina", "AR" ], + 11 : [ "Armenia", "AM" ], + 12 : [ "Aruba", "AW" ], + 13 : [ "Australia", "AU" ], + 14 : [ "Austria", "AT" ], + 15 : [ "Azerbaijan", "AZ" ], + 16 : [ "Bahamas", "BS" ], + 17 : [ "Bahrain", "BH" ], + 18 : [ "Bangladesh", "BD" ], + 19 : [ "Barbados", "BB" ], + 20 : [ "Belarus", "BY" ], + 21 : [ "Belgium", "BE" ], + 22 : [ "Belize", "BZ" ], + 23 : [ "Benin", "BJ" ], + 24 : [ "Bermuda", "BM" ], + 25 : [ "Bhutan", "BT" ], + 26 : [ "Bolivia", "BO" ], + 27 : [ "BosniaAndHerzegowina", "BA" ], + 28 : [ "Botswana", "BW" ], + 29 : [ "BouvetIsland", "BV" ], + 30 : [ "Brazil", "BR" ], + 31 : [ "BritishIndianOceanTerritory", "IO" ], + 32 : [ "BruneiDarussalam", "BN" ], + 33 : [ "Bulgaria", "BG" ], + 34 : [ "BurkinaFaso", "BF" ], + 35 : [ "Burundi", "BI" ], + 36 : [ "Cambodia", "KH" ], + 37 : [ "Cameroon", "CM" ], + 38 : [ "Canada", "CA" ], + 39 : [ "CapeVerde", "CV" ], + 40 : [ "CaymanIslands", "KY" ], + 41 : [ "CentralAfricanRepublic", "CF" ], + 42 : [ "Chad", "TD" ], + 43 : [ "Chile", "CL" ], + 44 : [ "China", "CN" ], + 45 : [ "ChristmasIsland", "CX" ], + 46 : [ "CocosIslands", "CC" ], + 47 : [ "Colombia", "CO" ], + 48 : [ "Comoros", "KM" ], + 49 : [ "DemocraticRepublicOfCongo", "CD" ], + 50 : [ "PeoplesRepublicOfCongo", "CG" ], + 51 : [ "CookIslands", "CK" ], + 52 : [ "CostaRica", "CR" ], + 53 : [ "IvoryCoast", "CI" ], + 54 : [ "Croatia", "HR" ], + 55 : [ "Cuba", "CU" ], + 56 : [ "Cyprus", "CY" ], + 57 : [ "CzechRepublic", "CZ" ], + 58 : [ "Denmark", "DK" ], + 59 : [ "Djibouti", "DJ" ], + 60 : [ "Dominica", "DM" ], + 61 : [ "DominicanRepublic", "DO" ], + 62 : [ "EastTimor", "TL" ], + 63 : [ "Ecuador", "EC" ], + 64 : [ "Egypt", "EG" ], + 65 : [ "ElSalvador", "SV" ], + 66 : [ "EquatorialGuinea", "GQ" ], + 67 : [ "Eritrea", "ER" ], + 68 : [ "Estonia", "EE" ], + 69 : [ "Ethiopia", "ET" ], + 70 : [ "FalklandIslands", "FK" ], + 71 : [ "FaroeIslands", "FO" ], + 72 : [ "Fiji", "FJ" ], + 73 : [ "Finland", "FI" ], + 74 : [ "France", "FR" ], + 75 : [ "MetropolitanFrance", "FX" ], + 76 : [ "FrenchGuiana", "GF" ], + 77 : [ "FrenchPolynesia", "PF" ], + 78 : [ "FrenchSouthernTerritories", "TF" ], + 79 : [ "Gabon", "GA" ], + 80 : [ "Gambia", "GM" ], + 81 : [ "Georgia", "GE" ], + 82 : [ "Germany", "DE" ], + 83 : [ "Ghana", "GH" ], + 84 : [ "Gibraltar", "GI" ], + 85 : [ "Greece", "GR" ], + 86 : [ "Greenland", "GL" ], + 87 : [ "Grenada", "GD" ], + 88 : [ "Guadeloupe", "GP" ], + 89 : [ "Guam", "GU" ], + 90 : [ "Guatemala", "GT" ], + 91 : [ "Guinea", "GN" ], + 92 : [ "GuineaBissau", "GW" ], + 93 : [ "Guyana", "GY" ], + 94 : [ "Haiti", "HT" ], + 95 : [ "HeardAndMcDonaldIslands", "HM" ], + 96 : [ "Honduras", "HN" ], + 97 : [ "HongKong", "HK" ], + 98 : [ "Hungary", "HU" ], + 99 : [ "Iceland", "IS" ], + 100 : [ "India", "IN" ], + 101 : [ "Indonesia", "ID" ], + 102 : [ "Iran", "IR" ], + 103 : [ "Iraq", "IQ" ], + 104 : [ "Ireland", "IE" ], + 105 : [ "Israel", "IL" ], + 106 : [ "Italy", "IT" ], + 107 : [ "Jamaica", "JM" ], + 108 : [ "Japan", "JP" ], + 109 : [ "Jordan", "JO" ], + 110 : [ "Kazakhstan", "KZ" ], + 111 : [ "Kenya", "KE" ], + 112 : [ "Kiribati", "KI" ], + 113 : [ "DemocraticRepublicOfKorea", "KP" ], + 114 : [ "RepublicOfKorea", "KR" ], + 115 : [ "Kuwait", "KW" ], + 116 : [ "Kyrgyzstan", "KG" ], + 117 : [ "Lao", "LA" ], + 118 : [ "Latvia", "LV" ], + 119 : [ "Lebanon", "LB" ], + 120 : [ "Lesotho", "LS" ], + 121 : [ "Liberia", "LR" ], + 122 : [ "LibyanArabJamahiriya", "LY" ], + 123 : [ "Liechtenstein", "LI" ], + 124 : [ "Lithuania", "LT" ], + 125 : [ "Luxembourg", "LU" ], + 126 : [ "Macau", "MO" ], + 127 : [ "Macedonia", "MK" ], + 128 : [ "Madagascar", "MG" ], + 129 : [ "Malawi", "MW" ], + 130 : [ "Malaysia", "MY" ], + 131 : [ "Maldives", "MV" ], + 132 : [ "Mali", "ML" ], + 133 : [ "Malta", "MT" ], + 134 : [ "MarshallIslands", "MH" ], + 135 : [ "Martinique", "MQ" ], + 136 : [ "Mauritania", "MR" ], + 137 : [ "Mauritius", "MU" ], + 138 : [ "Mayotte", "YT" ], + 139 : [ "Mexico", "MX" ], + 140 : [ "Micronesia", "FM" ], + 141 : [ "Moldova", "MD" ], + 142 : [ "Monaco", "MC" ], + 143 : [ "Mongolia", "MN" ], + 144 : [ "Montserrat", "MS" ], + 145 : [ "Morocco", "MA" ], + 146 : [ "Mozambique", "MZ" ], + 147 : [ "Myanmar", "MM" ], + 148 : [ "Namibia", "NA" ], + 149 : [ "Nauru", "NR" ], + 150 : [ "Nepal", "NP" ], + 151 : [ "Netherlands", "NL" ], + 152 : [ "NetherlandsAntilles", "AN" ], + 153 : [ "NewCaledonia", "NC" ], + 154 : [ "NewZealand", "NZ" ], + 155 : [ "Nicaragua", "NI" ], + 156 : [ "Niger", "NE" ], + 157 : [ "Nigeria", "NG" ], + 158 : [ "Niue", "NU" ], + 159 : [ "NorfolkIsland", "NF" ], + 160 : [ "NorthernMarianaIslands", "MP" ], + 161 : [ "Norway", "NO" ], + 162 : [ "Oman", "OM" ], + 163 : [ "Pakistan", "PK" ], + 164 : [ "Palau", "PW" ], + 165 : [ "PalestinianTerritory", "PS" ], + 166 : [ "Panama", "PA" ], + 167 : [ "PapuaNewGuinea", "PG" ], + 168 : [ "Paraguay", "PY" ], + 169 : [ "Peru", "PE" ], + 170 : [ "Philippines", "PH" ], + 171 : [ "Pitcairn", "PN" ], + 172 : [ "Poland", "PL" ], + 173 : [ "Portugal", "PT" ], + 174 : [ "PuertoRico", "PR" ], + 175 : [ "Qatar", "QA" ], + 176 : [ "Reunion", "RE" ], + 177 : [ "Romania", "RO" ], + 178 : [ "RussianFederation", "RU" ], + 179 : [ "Rwanda", "RW" ], + 180 : [ "SaintKittsAndNevis", "KN" ], + 181 : [ "StLucia", "LC" ], + 182 : [ "StVincentAndTheGrenadines", "VC" ], + 183 : [ "Samoa", "WS" ], + 184 : [ "SanMarino", "SM" ], + 185 : [ "SaoTomeAndPrincipe", "ST" ], + 186 : [ "SaudiArabia", "SA" ], + 187 : [ "Senegal", "SN" ], + 188 : [ "Seychelles", "SC" ], + 189 : [ "SierraLeone", "SL" ], + 190 : [ "Singapore", "SG" ], + 191 : [ "Slovakia", "SK" ], + 192 : [ "Slovenia", "SI" ], + 193 : [ "SolomonIslands", "SB" ], + 194 : [ "Somalia", "SO" ], + 195 : [ "SouthAfrica", "ZA" ], + 196 : [ "SouthGeorgiaAndTheSouthSandwichIslands", "GS" ], + 197 : [ "Spain", "ES" ], + 198 : [ "SriLanka", "LK" ], + 199 : [ "StHelena", "SH" ], + 200 : [ "StPierreAndMiquelon", "PM" ], + 201 : [ "Sudan", "SD" ], + 202 : [ "Suriname", "SR" ], + 203 : [ "SvalbardAndJanMayenIslands", "SJ" ], + 204 : [ "Swaziland", "SZ" ], + 205 : [ "Sweden", "SE" ], + 206 : [ "Switzerland", "CH" ], + 207 : [ "SyrianArabRepublic", "SY" ], + 208 : [ "Taiwan", "TW" ], + 209 : [ "Tajikistan", "TJ" ], + 210 : [ "Tanzania", "TZ" ], + 211 : [ "Thailand", "TH" ], + 212 : [ "Togo", "TG" ], + 213 : [ "Tokelau", "TK" ], + 214 : [ "Tonga", "TO" ], + 215 : [ "TrinidadAndTobago", "TT" ], + 216 : [ "Tunisia", "TN" ], + 217 : [ "Turkey", "TR" ], + 218 : [ "Turkmenistan", "TM" ], + 219 : [ "TurksAndCaicosIslands", "TC" ], + 220 : [ "Tuvalu", "TV" ], + 221 : [ "Uganda", "UG" ], + 222 : [ "Ukraine", "UA" ], + 223 : [ "UnitedArabEmirates", "AE" ], + 224 : [ "UnitedKingdom", "GB" ], + 225 : [ "UnitedStates", "US" ], + 226 : [ "UnitedStatesMinorOutlyingIslands", "UM" ], + 227 : [ "Uruguay", "UY" ], + 228 : [ "Uzbekistan", "UZ" ], + 229 : [ "Vanuatu", "VU" ], + 230 : [ "VaticanCityState", "VA" ], + 231 : [ "Venezuela", "VE" ], + 232 : [ "VietNam", "VN" ], + 233 : [ "BritishVirginIslands", "VG" ], + 234 : [ "USVirginIslands", "VI" ], + 235 : [ "WallisAndFutunaIslands", "WF" ], + 236 : [ "WesternSahara", "EH" ], + 237 : [ "Yemen", "YE" ], + 238 : [ "Yugoslavia", "YU" ], + 239 : [ "Zambia", "ZM" ], + 240 : [ "Zimbabwe", "ZW" ], + 241 : [ "SerbiaAndMontenegro", "CS" ], + 242 : [ "Montenegro", "ME" ], + 243 : [ "Serbia", "RS" ], + 244 : [ "Saint Barthelemy", "BL" ], + 245 : [ "Saint Martin", "MF" ], + 246 : [ "LatinAmericaAndTheCaribbean", "419" ] +} + +script_list = { + 0 : [ "AnyScript", "" ], + 1 : [ "Arabic", "Arab" ], + 2 : [ "Cyrillic", "Cyrl" ], + 3 : [ "Deseret", "Dsrt" ], + 4 : [ "Gurmukhi", "Guru" ], + 5 : [ "Simplified Han", "Hans" ], + 6 : [ "Traditional Han", "Hant" ], + 7 : [ "Latin", "Latn" ], + 8 : [ "Mongolian", "Mong" ], + 9 : [ "Tifinagh", "Tfng" ] +} + +def countryCodeToId(code): + for country_id in country_list: + if country_list[country_id][1] == code: + return country_id + return -1 + +def languageCodeToId(code): + for language_id in language_list: + if language_list[language_id][1] == code: + return language_id + return -1 + +def scriptCodeToId(code): + for script_id in script_list: + if script_list[script_id][1] == code: + return script_id + return -1 diff --git a/util/local_database/formattags.txt b/util/local_database/formattags.txt new file mode 100644 index 0000000000..5138c37a81 --- /dev/null +++ b/util/local_database/formattags.txt @@ -0,0 +1,23 @@ +d +dd +ddd +dddd +M +MM +MMM +MMMM +yy +yyyy +h the hour without a leading zero (0 to 23 or 1 to 12 if AM/PM display) +hh the hour with a leading zero (00 to 23 or 01 to 12 if AM/PM display) +H the hour without a leading zero (0 to 23, even with AM/PM display) +HH the hour with a leading zero (00 to 23, even with AM/PM display) +m +mm +s +ss +z the milliseconds without leading zeroes (0 to 999) +zzz the milliseconds with leading zeroes (000 to 999) +AP or A interpret as an AM/PM time. AP must be either "AM" or "PM" +ap or a Interpret as an AM/PM time. ap must be either "am" or "pm" +t time zone diff --git a/util/local_database/qlocalexml2cpp.py b/util/local_database/qlocalexml2cpp.py new file mode 100755 index 0000000000..89074351e9 --- /dev/null +++ b/util/local_database/qlocalexml2cpp.py @@ -0,0 +1,877 @@ +#!/usr/bin/env python +############################################################################# +## +## Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +## All rights reserved. +## Contact: Nokia Corporation (qt-info@nokia.com) +## +## This file is part of the test suite of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:LGPL$ +## No Commercial Usage +## This file contains pre-release code and may not be distributed. +## You may use this file in accordance with the terms and conditions +## contained in the Technology Preview License Agreement accompanying +## this package. +## +## GNU Lesser General Public License Usage +## Alternatively, this file may be used under the terms of the GNU Lesser +## General Public License version 2.1 as published by the Free Software +## Foundation and appearing in the file LICENSE.LGPL included in the +## packaging of this file. Please review the following information to +## ensure the GNU Lesser General Public License version 2.1 requirements +## will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +## +## In addition, as a special exception, Nokia gives you certain additional +## rights. These rights are described in the Nokia Qt LGPL Exception +## version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +## +## If you have questions regarding the use of this file, please contact +## Nokia at qt-info@nokia.com. +## +## +## +## +## +## +## +## +## $QT_END_LICENSE$ +## +############################################################################# + +import os +import sys +import tempfile +import datetime +import xml.dom.minidom + +class Error: + def __init__(self, msg): + self.msg = msg + def __str__(self): + return self.msg + +def check_static_char_array_length(name, array): + # some compilers like VC6 doesn't allow static arrays more than 64K bytes size. + size = reduce(lambda x, y: x+len(escapedString(y)), array, 0) + if size > 65535: + print "\n\n\n#error Array %s is too long! " % name + sys.stderr.write("\n\n\nERROR: the content of the array '%s' is too long: %d > 65535 " % (name, size)) + sys.exit(1) + +def wrap_list(lst): + def split(lst, size): + for i in range(len(lst)/size+1): + yield lst[i*size:(i+1)*size] + return ",\n".join(map(lambda x: ", ".join(x), split(lst, 20))) + +def firstChildElt(parent, name): + child = parent.firstChild + while child: + if child.nodeType == parent.ELEMENT_NODE \ + and (not name or child.nodeName == name): + return child + child = child.nextSibling + return False + +def nextSiblingElt(sibling, name): + sib = sibling.nextSibling + while sib: + if sib.nodeType == sibling.ELEMENT_NODE \ + and (not name or sib.nodeName == name): + return sib + sib = sib.nextSibling + return False + +def eltText(elt): + result = "" + child = elt.firstChild + while child: + if child.nodeType == elt.TEXT_NODE: + if result: + result += " " + result += child.nodeValue + child = child.nextSibling + return result + +def loadLanguageMap(doc): + result = {} + + language_list_elt = firstChildElt(doc.documentElement, "languageList") + language_elt = firstChildElt(language_list_elt, "language") + while language_elt: + language_id = int(eltText(firstChildElt(language_elt, "id"))) + language_name = eltText(firstChildElt(language_elt, "name")) + language_code = eltText(firstChildElt(language_elt, "code")) + result[language_id] = (language_name, language_code) + language_elt = nextSiblingElt(language_elt, "language") + + return result + +def loadScriptMap(doc): + result = {} + + script_list_elt = firstChildElt(doc.documentElement, "scriptList") + script_elt = firstChildElt(script_list_elt, "script") + while script_elt: + script_id = int(eltText(firstChildElt(script_elt, "id"))) + script_name = eltText(firstChildElt(script_elt, "name")) + script_code = eltText(firstChildElt(script_elt, "code")) + result[script_id] = (script_name, script_code) + script_elt = nextSiblingElt(script_elt, "script") + + return result + +def loadCountryMap(doc): + result = {} + + country_list_elt = firstChildElt(doc.documentElement, "countryList") + country_elt = firstChildElt(country_list_elt, "country") + while country_elt: + country_id = int(eltText(firstChildElt(country_elt, "id"))) + country_name = eltText(firstChildElt(country_elt, "name")) + country_code = eltText(firstChildElt(country_elt, "code")) + result[country_id] = (country_name, country_code) + country_elt = nextSiblingElt(country_elt, "country") + + return result + +def loadDefaultMap(doc): + result = {} + + list_elt = firstChildElt(doc.documentElement, "defaultCountryList") + elt = firstChildElt(list_elt, "defaultCountry") + while elt: + country = eltText(firstChildElt(elt, "country")); + language = eltText(firstChildElt(elt, "language")); + result[language] = country; + elt = nextSiblingElt(elt, "defaultCountry"); + return result + +def fixedScriptName(name, dupes): + name = name.replace(" ", "") + if name[-6:] != "Script": + name = name + "Script"; + if name in dupes: + sys.stderr.write("\n\n\nERROR: The script name '%s' is messy" % name) + sys.exit(1); + return name + +def fixedCountryName(name, dupes): + if name in dupes: + return name.replace(" ", "") + "Country" + return name.replace(" ", "") + +def fixedLanguageName(name, dupes): + if name in dupes: + return name.replace(" ", "") + "Language" + return name.replace(" ", "") + +def findDupes(country_map, language_map): + country_set = set([ v[0] for a, v in country_map.iteritems() ]) + language_set = set([ v[0] for a, v in language_map.iteritems() ]) + return country_set & language_set + +def languageNameToId(name, language_map): + for key in language_map.keys(): + if language_map[key][0] == name: + return key + return -1 + +def scriptNameToId(name, script_map): + for key in script_map.keys(): + if script_map[key][0] == name: + return key + return -1 + +def countryNameToId(name, country_map): + for key in country_map.keys(): + if country_map[key][0] == name: + return key + return -1 + +def convertFormat(format): + result = "" + i = 0 + while i < len(format): + if format[i] == "'": + result += "'" + i += 1 + while i < len(format) and format[i] != "'": + result += format[i] + i += 1 + if i < len(format): + result += "'" + i += 1 + else: + s = format[i:] + if s.startswith("EEEE"): + result += "dddd" + i += 4 + elif s.startswith("EEE"): + result += "ddd" + i += 3 + elif s.startswith("a"): + result += "AP" + i += 1 + elif s.startswith("z"): + result += "t" + i += 1 + elif s.startswith("v"): + i += 1 + else: + result += format[i] + i += 1 + + return result + +def convertToQtDayOfWeek(firstDay): + qtDayOfWeek = {"mon":1, "tue":2, "wed":3, "thu":4, "fri":5, "sat":6, "sun":7} + return qtDayOfWeek[firstDay] + +def assertSingleChar(string): + assert len(string) == 1, "This string is not allowed to be longer than 1 character" + return string + +class Locale: + def __init__(self, elt): + self.language = eltText(firstChildElt(elt, "language")) + self.languageEndonym = eltText(firstChildElt(elt, "languageEndonym")) + self.script = eltText(firstChildElt(elt, "script")) + self.country = eltText(firstChildElt(elt, "country")) + self.countryEndonym = eltText(firstChildElt(elt, "countryEndonym")) + self.decimal = int(eltText(firstChildElt(elt, "decimal"))) + self.group = int(eltText(firstChildElt(elt, "group"))) + self.listDelim = int(eltText(firstChildElt(elt, "list"))) + self.percent = int(eltText(firstChildElt(elt, "percent"))) + self.zero = int(eltText(firstChildElt(elt, "zero"))) + self.minus = int(eltText(firstChildElt(elt, "minus"))) + self.plus = int(eltText(firstChildElt(elt, "plus"))) + self.exp = int(eltText(firstChildElt(elt, "exp"))) + self.quotationStart = ord(assertSingleChar(eltText(firstChildElt(elt, "quotationStart")))) + self.quotationEnd = ord(assertSingleChar(eltText(firstChildElt(elt, "quotationEnd")))) + self.alternateQuotationStart = ord(assertSingleChar(eltText(firstChildElt(elt, "alternateQuotationStart")))) + self.alternateQuotationEnd = ord(assertSingleChar(eltText(firstChildElt(elt, "alternateQuotationEnd")))) + self.listPatternPartStart = eltText(firstChildElt(elt, "listPatternPartStart")) + self.listPatternPartMiddle = eltText(firstChildElt(elt, "listPatternPartMiddle")) + self.listPatternPartEnd = eltText(firstChildElt(elt, "listPatternPartEnd")) + self.listPatternPartTwo = eltText(firstChildElt(elt, "listPatternPartTwo")) + self.am = eltText(firstChildElt(elt, "am")) + self.pm = eltText(firstChildElt(elt, "pm")) + self.firstDayOfWeek = convertToQtDayOfWeek(eltText(firstChildElt(elt, "firstDayOfWeek"))) + self.weekendStart = convertToQtDayOfWeek(eltText(firstChildElt(elt, "weekendStart"))) + self.weekendEnd = convertToQtDayOfWeek(eltText(firstChildElt(elt, "weekendEnd"))) + self.longDateFormat = convertFormat(eltText(firstChildElt(elt, "longDateFormat"))) + self.shortDateFormat = convertFormat(eltText(firstChildElt(elt, "shortDateFormat"))) + self.longTimeFormat = convertFormat(eltText(firstChildElt(elt, "longTimeFormat"))) + self.shortTimeFormat = convertFormat(eltText(firstChildElt(elt, "shortTimeFormat"))) + self.standaloneLongMonths = eltText(firstChildElt(elt, "standaloneLongMonths")) + self.standaloneShortMonths = eltText(firstChildElt(elt, "standaloneShortMonths")) + self.standaloneNarrowMonths = eltText(firstChildElt(elt, "standaloneNarrowMonths")) + self.longMonths = eltText(firstChildElt(elt, "longMonths")) + self.shortMonths = eltText(firstChildElt(elt, "shortMonths")) + self.narrowMonths = eltText(firstChildElt(elt, "narrowMonths")) + self.standaloneLongDays = eltText(firstChildElt(elt, "standaloneLongDays")) + self.standaloneShortDays = eltText(firstChildElt(elt, "standaloneShortDays")) + self.standaloneNarrowDays = eltText(firstChildElt(elt, "standaloneNarrowDays")) + self.longDays = eltText(firstChildElt(elt, "longDays")) + self.shortDays = eltText(firstChildElt(elt, "shortDays")) + self.narrowDays = eltText(firstChildElt(elt, "narrowDays")) + self.currencyIsoCode = eltText(firstChildElt(elt, "currencyIsoCode")) + self.currencySymbol = eltText(firstChildElt(elt, "currencySymbol")) + self.currencyDisplayName = eltText(firstChildElt(elt, "currencyDisplayName")) + self.currencyDigits = int(eltText(firstChildElt(elt, "currencyDigits"))) + self.currencyRounding = int(eltText(firstChildElt(elt, "currencyRounding"))) + self.currencyFormat = eltText(firstChildElt(elt, "currencyFormat")) + self.currencyNegativeFormat = eltText(firstChildElt(elt, "currencyNegativeFormat")) + +def loadLocaleMap(doc, language_map, script_map, country_map): + result = {} + + locale_list_elt = firstChildElt(doc.documentElement, "localeList") + locale_elt = firstChildElt(locale_list_elt, "locale") + while locale_elt: + locale = Locale(locale_elt) + language_id = languageNameToId(locale.language, language_map) + if language_id == -1: + sys.stderr.write("Cannot find a language id for '%s'\n" % locale.language) + script_id = scriptNameToId(locale.script, script_map) + if script_id == -1: + sys.stderr.write("Cannot find a script id for '%s'\n" % locale.script) + country_id = countryNameToId(locale.country, country_map) + if country_id == -1: + sys.stderr.write("Cannot find a country id for '%s'\n" % locale.country) + result[(language_id, script_id, country_id)] = locale + + locale_elt = nextSiblingElt(locale_elt, "locale") + + return result + +def compareLocaleKeys(key1, key2): + if key1 == key2: + return 0 + + if key1[0] == key2[0]: + l1 = compareLocaleKeys.locale_map[key1] + l2 = compareLocaleKeys.locale_map[key2] + + if l1.language in compareLocaleKeys.default_map: + default = compareLocaleKeys.default_map[l1.language] + if l1.country == default and key1[1] == 0: + return -1 + if l2.country == default and key2[1] == 0: + return 1 + + if key1[1] != key2[1]: + return key1[1] - key2[1] + else: + return key1[0] - key2[0] + + return key1[2] - key2[2] + + +def languageCount(language_id, locale_map): + result = 0 + for key in locale_map.keys(): + if key[0] == language_id: + result += 1 + return result + +def unicode2hex(s): + lst = [] + for x in s: + v = ord(x) + if v > 0xFFFF: + # make a surrogate pair + # copied from qchar.h + high = (v >> 10) + 0xd7c0 + low = (v % 0x400 + 0xdc00) + lst.append(hex(high)) + lst.append(hex(low)) + else: + lst.append(hex(v)) + return lst + +class StringDataToken: + def __init__(self, index, length): + if index > 0xFFFF or length > 0xFFFF: + raise Error("Position exceeds ushort range: %d,%d " % (index, length)) + self.index = index + self.length = length + def __str__(self): + return " %d,%d " % (self.index, self.length) + +class StringData: + def __init__(self): + self.data = [] + self.hash = {} + def append(self, s): + if s in self.hash: + return self.hash[s] + + lst = unicode2hex(s) + index = len(self.data) + if index > 65535: + print "\n\n\n#error Data index is too big!" + sys.stderr.write ("\n\n\nERROR: index exceeds the uint16 range! index = %d\n" % index) + sys.exit(1) + size = len(lst) + if size >= 65535: + print "\n\n\n#error Data is too big!" + sys.stderr.write ("\n\n\nERROR: data size exceeds the uint16 range! size = %d\n" % size) + sys.exit(1) + token = None + try: + token = StringDataToken(index, size) + except Error as e: + sys.stderr.write("\n\n\nERROR: %s: on data '%s'" % (e, s)) + sys.exit(1) + self.hash[s] = token + self.data += lst + return token + +def escapedString(s): + result = "" + i = 0 + while i < len(s): + if s[i] == '"': + result += '\\"' + i += 1 + else: + result += s[i] + i += 1 + s = result + + line = "" + need_escape = False + result = "" + for c in s: + if ord(c) < 128 and (not need_escape or ord(c.lower()) < ord('a') or ord(c.lower()) > ord('f')): + line += c + need_escape = False + else: + line += "\\x%02x" % (ord(c)) + need_escape = True + if len(line) > 80: + result = result + "\n" + "\"" + line + "\"" + line = "" + line += "\\0" + result = result + "\n" + "\"" + line + "\"" + if result[0] == "\n": + result = result[1:] + return result + +def printEscapedString(s): + print escapedString(s); + + +def currencyIsoCodeData(s): + if s: + return ",".join(map(lambda x: str(ord(x)), s)) + return "0,0,0" + +def usage(): + print "Usage: qlocalexml2cpp.py " + sys.exit(1) + +GENERATED_BLOCK_START = "// GENERATED PART STARTS HERE\n" +GENERATED_BLOCK_END = "// GENERATED PART ENDS HERE\n" + +def main(): + if len(sys.argv) != 3: + usage() + + localexml = sys.argv[1] + qtsrcdir = sys.argv[2] + + if not os.path.exists(qtsrcdir) or not os.path.exists(qtsrcdir): + usage() + if not os.path.isfile(qtsrcdir + "/src/corelib/tools/qlocale_data_p.h"): + usage() + if not os.path.isfile(qtsrcdir + "/src/corelib/tools/qlocale.h"): + usage() + if not os.path.isfile(qtsrcdir + "/src/corelib/tools/qlocale.qdoc"): + usage() + + (data_temp_file, data_temp_file_path) = tempfile.mkstemp("qlocale_data_p", dir=qtsrcdir) + data_temp_file = os.fdopen(data_temp_file, "w") + qlocaledata_file = open(qtsrcdir + "/src/corelib/tools/qlocale_data_p.h", "r") + s = qlocaledata_file.readline() + while s and s != GENERATED_BLOCK_START: + data_temp_file.write(s) + s = qlocaledata_file.readline() + data_temp_file.write(GENERATED_BLOCK_START) + + doc = xml.dom.minidom.parse(localexml) + language_map = loadLanguageMap(doc) + script_map = loadScriptMap(doc) + country_map = loadCountryMap(doc) + default_map = loadDefaultMap(doc) + locale_map = loadLocaleMap(doc, language_map, script_map, country_map) + dupes = findDupes(language_map, country_map) + + cldr_version = eltText(firstChildElt(doc.documentElement, "version")) + + data_temp_file.write("\n\ +/*\n\ + This part of the file was generated on %s from the\n\ + Common Locale Data Repository v%s\n\ +\n\ + http://www.unicode.org/cldr/\n\ +\n\ + Do not change it, instead edit CLDR data and regenerate this file using\n\ + cldr2qlocalexml.py and qlocalexml2cpp.py.\n\ +*/\n\n\n\ +" % (str(datetime.date.today()), cldr_version) ) + + # Locale index + data_temp_file.write("static const quint16 locale_index[] = {\n") + index = 0 + for key in language_map.keys(): + i = 0 + count = languageCount(key, locale_map) + if count > 0: + i = index + index += count + data_temp_file.write("%6d, // %s\n" % (i, language_map[key][0])) + data_temp_file.write(" 0 // trailing 0\n") + data_temp_file.write("};\n") + + data_temp_file.write("\n") + + list_pattern_part_data = StringData() + date_format_data = StringData() + time_format_data = StringData() + months_data = StringData() + standalone_months_data = StringData() + days_data = StringData() + am_data = StringData() + pm_data = StringData() + currency_symbol_data = StringData() + currency_display_name_data = StringData() + currency_format_data = StringData() + endonyms_data = StringData() + + # Locale data + data_temp_file.write("static const QLocalePrivate locale_data[] = {\n") + data_temp_file.write("// lang script terr dec group list prcnt zero minus plus exp quotStart quotEnd altQuotStart altQuotEnd lpStart lpMid lpEnd lpTwo sDtFmt lDtFmt sTmFmt lTmFmt ssMonth slMonth sMonth lMonth sDays lDays am,len pm,len\n") + + locale_keys = locale_map.keys() + compareLocaleKeys.default_map = default_map + compareLocaleKeys.locale_map = locale_map + locale_keys.sort(compareLocaleKeys) + + for key in locale_keys: + l = locale_map[key] + data_temp_file.write(" { %6d,%6d,%6d,%6d,%6d,%6d,%6d,%6d,%6d,%6d,%6d,%6d,%6d,%6d,%6d,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s, {%s}, %s,%s,%s,%s,%s,%s,%6d,%6d,%6d,%6d,%6d }, // %s/%s/%s\n" \ + % (key[0], key[1], key[2], + l.decimal, + l.group, + l.listDelim, + l.percent, + l.zero, + l.minus, + l.plus, + l.exp, + l.quotationStart, + l.quotationEnd, + l.alternateQuotationStart, + l.alternateQuotationEnd, + list_pattern_part_data.append(l.listPatternPartStart), + list_pattern_part_data.append(l.listPatternPartMiddle), + list_pattern_part_data.append(l.listPatternPartEnd), + list_pattern_part_data.append(l.listPatternPartTwo), + date_format_data.append(l.shortDateFormat), + date_format_data.append(l.longDateFormat), + time_format_data.append(l.shortTimeFormat), + time_format_data.append(l.longTimeFormat), + standalone_months_data.append(l.standaloneShortMonths), + standalone_months_data.append(l.standaloneLongMonths), + standalone_months_data.append(l.standaloneNarrowMonths), + months_data.append(l.shortMonths), + months_data.append(l.longMonths), + months_data.append(l.narrowMonths), + days_data.append(l.standaloneShortDays), + days_data.append(l.standaloneLongDays), + days_data.append(l.standaloneNarrowDays), + days_data.append(l.shortDays), + days_data.append(l.longDays), + days_data.append(l.narrowDays), + am_data.append(l.am), + pm_data.append(l.pm), + currencyIsoCodeData(l.currencyIsoCode), + currency_symbol_data.append(l.currencySymbol), + currency_display_name_data.append(l.currencyDisplayName), + currency_format_data.append(l.currencyFormat), + currency_format_data.append(l.currencyNegativeFormat), + endonyms_data.append(l.languageEndonym), + endonyms_data.append(l.countryEndonym), + l.currencyDigits, + l.currencyRounding, + l.firstDayOfWeek, + l.weekendStart, + l.weekendEnd, + l.language, + l.script, + l.country)) + data_temp_file.write(" { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, {0,0,0}, 0,0, 0,0, 0,0, 0,0, 0, 0, 0, 0, 0, 0,0, 0,0 } // trailing 0s\n") + data_temp_file.write("};\n") + + data_temp_file.write("\n") + + # List patterns data + #check_static_char_array_length("list_pattern_part", list_pattern_part_data.data) + data_temp_file.write("static const ushort list_pattern_part_data[] = {\n") + data_temp_file.write(wrap_list(list_pattern_part_data.data)) + data_temp_file.write("\n};\n") + + data_temp_file.write("\n") + + # Date format data + #check_static_char_array_length("date_format", date_format_data.data) + data_temp_file.write("static const ushort date_format_data[] = {\n") + data_temp_file.write(wrap_list(date_format_data.data)) + data_temp_file.write("\n};\n") + + data_temp_file.write("\n") + + # Time format data + #check_static_char_array_length("time_format", time_format_data.data) + data_temp_file.write("static const ushort time_format_data[] = {\n") + data_temp_file.write(wrap_list(time_format_data.data)) + data_temp_file.write("\n};\n") + + data_temp_file.write("\n") + + # Months data + #check_static_char_array_length("months", months_data.data) + data_temp_file.write("static const ushort months_data[] = {\n") + data_temp_file.write(wrap_list(months_data.data)) + data_temp_file.write("\n};\n") + + data_temp_file.write("\n") + + # Standalone months data + #check_static_char_array_length("standalone_months", standalone_months_data.data) + data_temp_file.write("static const ushort standalone_months_data[] = {\n") + data_temp_file.write(wrap_list(standalone_months_data.data)) + data_temp_file.write("\n};\n") + + data_temp_file.write("\n") + + # Days data + #check_static_char_array_length("days", days_data.data) + data_temp_file.write("static const ushort days_data[] = {\n") + data_temp_file.write(wrap_list(days_data.data)) + data_temp_file.write("\n};\n") + + data_temp_file.write("\n") + + # AM data + #check_static_char_array_length("am", am_data.data) + data_temp_file.write("static const ushort am_data[] = {\n") + data_temp_file.write(wrap_list(am_data.data)) + data_temp_file.write("\n};\n") + + data_temp_file.write("\n") + + # PM data + #check_static_char_array_length("pm", am_data.data) + data_temp_file.write("static const ushort pm_data[] = {\n") + data_temp_file.write(wrap_list(pm_data.data)) + data_temp_file.write("\n};\n") + + data_temp_file.write("\n") + + # Currency symbol data + #check_static_char_array_length("currency_symbol", currency_symbol_data.data) + data_temp_file.write("static const ushort currency_symbol_data[] = {\n") + data_temp_file.write(wrap_list(currency_symbol_data.data)) + data_temp_file.write("\n};\n") + + data_temp_file.write("\n") + + # Currency display name data + #check_static_char_array_length("currency_display_name", currency_display_name_data.data) + data_temp_file.write("static const ushort currency_display_name_data[] = {\n") + data_temp_file.write(wrap_list(currency_display_name_data.data)) + data_temp_file.write("\n};\n") + + data_temp_file.write("\n") + + # Currency format data + #check_static_char_array_length("currency_format", currency_format_data.data) + data_temp_file.write("static const ushort currency_format_data[] = {\n") + data_temp_file.write(wrap_list(currency_format_data.data)) + data_temp_file.write("\n};\n") + + # Endonyms data + #check_static_char_array_length("endonyms", endonyms_data.data) + data_temp_file.write("static const ushort endonyms_data[] = {\n") + data_temp_file.write(wrap_list(endonyms_data.data)) + data_temp_file.write("\n};\n") + + data_temp_file.write("\n") + + # Language name list + data_temp_file.write("static const char language_name_list[] =\n") + data_temp_file.write("\"Default\\0\"\n") + for key in language_map.keys(): + if key == 0: + continue + data_temp_file.write("\"" + language_map[key][0] + "\\0\"\n") + data_temp_file.write(";\n") + + data_temp_file.write("\n") + + # Language name index + data_temp_file.write("static const quint16 language_name_index[] = {\n") + data_temp_file.write(" 0, // AnyLanguage\n") + index = 8 + for key in language_map.keys(): + if key == 0: + continue + language = language_map[key][0] + data_temp_file.write("%6d, // %s\n" % (index, language)) + index += len(language) + 1 + data_temp_file.write("};\n") + + data_temp_file.write("\n") + + # Script name list + data_temp_file.write("static const char script_name_list[] =\n") + data_temp_file.write("\"Default\\0\"\n") + for key in script_map.keys(): + if key == 0: + continue + data_temp_file.write("\"" + script_map[key][0] + "\\0\"\n") + data_temp_file.write(";\n") + + data_temp_file.write("\n") + + # Script name index + data_temp_file.write("static const quint16 script_name_index[] = {\n") + data_temp_file.write(" 0, // AnyScript\n") + index = 8 + for key in script_map.keys(): + if key == 0: + continue + script = script_map[key][0] + data_temp_file.write("%6d, // %s\n" % (index, script)) + index += len(script) + 1 + data_temp_file.write("};\n") + + data_temp_file.write("\n") + + # Country name list + data_temp_file.write("static const char country_name_list[] =\n") + data_temp_file.write("\"Default\\0\"\n") + for key in country_map.keys(): + if key == 0: + continue + data_temp_file.write("\"" + country_map[key][0] + "\\0\"\n") + data_temp_file.write(";\n") + + data_temp_file.write("\n") + + # Country name index + data_temp_file.write("static const quint16 country_name_index[] = {\n") + data_temp_file.write(" 0, // AnyCountry\n") + index = 8 + for key in country_map.keys(): + if key == 0: + continue + country = country_map[key][0] + data_temp_file.write("%6d, // %s\n" % (index, country)) + index += len(country) + 1 + data_temp_file.write("};\n") + + data_temp_file.write("\n") + + # Language code list + data_temp_file.write("static const unsigned char language_code_list[] =\n") + for key in language_map.keys(): + code = language_map[key][1] + if len(code) == 2: + code += r"\0" + data_temp_file.write("\"%2s\" // %s\n" % (code, language_map[key][0])) + data_temp_file.write(";\n") + + data_temp_file.write("\n") + + # Script code list + data_temp_file.write("static const unsigned char script_code_list[] =\n") + for key in script_map.keys(): + code = script_map[key][1] + for i in range(4 - len(code)): + code += "\\0" + data_temp_file.write("\"%2s\" // %s\n" % (code, script_map[key][0])) + data_temp_file.write(";\n") + + # Country code list + data_temp_file.write("static const unsigned char country_code_list[] =\n") + for key in country_map.keys(): + code = country_map[key][1] + if len(code) == 2: + code += "\\0" + data_temp_file.write("\"%2s\" // %s\n" % (code, country_map[key][0])) + data_temp_file.write(";\n") + + data_temp_file.write("\n") + data_temp_file.write(GENERATED_BLOCK_END) + s = qlocaledata_file.readline() + # skip until end of the block + while s and s != GENERATED_BLOCK_END: + s = qlocaledata_file.readline() + + s = qlocaledata_file.readline() + while s: + data_temp_file.write(s) + s = qlocaledata_file.readline() + data_temp_file.close() + qlocaledata_file.close() + + os.rename(data_temp_file_path, qtsrcdir + "/src/corelib/tools/qlocale_data_p.h") + + # qlocale.h + + (qlocaleh_temp_file, qlocaleh_temp_file_path) = tempfile.mkstemp("qlocale.h", dir=qtsrcdir) + qlocaleh_temp_file = os.fdopen(qlocaleh_temp_file, "w") + qlocaleh_file = open(qtsrcdir + "/src/corelib/tools/qlocale.h", "r") + s = qlocaleh_file.readline() + while s and s != GENERATED_BLOCK_START: + qlocaleh_temp_file.write(s) + s = qlocaleh_file.readline() + qlocaleh_temp_file.write(GENERATED_BLOCK_START) + qlocaleh_temp_file.write("// see qlocale_data_p.h for more info on generated data\n") + + # Language enum + qlocaleh_temp_file.write(" enum Language {\n") + language = "" + for key in language_map.keys(): + language = fixedLanguageName(language_map[key][0], dupes) + qlocaleh_temp_file.write(" " + language + " = " + str(key) + ",\n") + # special cases for norwegian. we really need to make it right at some point. + qlocaleh_temp_file.write(" NorwegianBokmal = Norwegian,\n") + qlocaleh_temp_file.write(" NorwegianNynorsk = Nynorsk,\n") + qlocaleh_temp_file.write(" LastLanguage = " + language + "\n") + qlocaleh_temp_file.write(" };\n") + + qlocaleh_temp_file.write("\n") + + # Script enum + qlocaleh_temp_file.write(" enum Script {\n") + script = "" + for key in script_map.keys(): + script = fixedScriptName(script_map[key][0], dupes) + qlocaleh_temp_file.write(" " + script + " = " + str(key) + ",\n") + qlocaleh_temp_file.write(" SimplifiedChineseScript = SimplifiedHanScript,\n") + qlocaleh_temp_file.write(" TraditionalChineseScript = TraditionalHanScript,\n") + qlocaleh_temp_file.write(" LastScript = " + script + "\n") + qlocaleh_temp_file.write(" };\n") + + # Country enum + qlocaleh_temp_file.write(" enum Country {\n") + country = "" + for key in country_map.keys(): + country = fixedCountryName(country_map[key][0], dupes) + qlocaleh_temp_file.write(" " + country + " = " + str(key) + ",\n") + qlocaleh_temp_file.write(" LastCountry = " + country + "\n") + qlocaleh_temp_file.write(" };\n") + + qlocaleh_temp_file.write(GENERATED_BLOCK_END) + s = qlocaleh_file.readline() + # skip until end of the block + while s and s != GENERATED_BLOCK_END: + s = qlocaleh_file.readline() + + s = qlocaleh_file.readline() + while s: + qlocaleh_temp_file.write(s) + s = qlocaleh_file.readline() + qlocaleh_temp_file.close() + qlocaleh_file.close() + + os.rename(qlocaleh_temp_file_path, qtsrcdir + "/src/corelib/tools/qlocale.h") + + # qlocale.qdoc + + (qlocaleqdoc_temp_file, qlocaleqdoc_temp_file_path) = tempfile.mkstemp("qlocale.qdoc", dir=qtsrcdir) + qlocaleqdoc_temp_file = os.fdopen(qlocaleqdoc_temp_file, "w") + qlocaleqdoc_file = open(qtsrcdir + "/src/corelib/tools/qlocale.qdoc", "r") + s = qlocaleqdoc_file.readline() + DOCSTRING=" QLocale's data is based on Common Locale Data Repository " + while s: + if DOCSTRING in s: + qlocaleqdoc_temp_file.write(DOCSTRING + "v" + cldr_version + ".\n") + else: + qlocaleqdoc_temp_file.write(s) + s = qlocaleqdoc_file.readline() + qlocaleqdoc_temp_file.close() + qlocaleqdoc_file.close() + + os.rename(qlocaleqdoc_temp_file_path, qtsrcdir + "/src/corelib/tools/qlocale.qdoc") + +if __name__ == "__main__": + main() diff --git a/util/local_database/testlocales/localemodel.cpp b/util/local_database/testlocales/localemodel.cpp new file mode 100644 index 0000000000..c1916fc11e --- /dev/null +++ b/util/local_database/testlocales/localemodel.cpp @@ -0,0 +1,462 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the utils of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "localemodel.h" + +#include +#include +#include + +static const int g_model_cols = 6; + +struct LocaleListItem +{ + int language; + int country; +}; + +const LocaleListItem g_locale_list[] = { + { 1, 0 }, // C/AnyCountry + { 3, 69 }, // Afan/Ethiopia + { 3, 111 }, // Afan/Kenya + { 4, 59 }, // Afar/Djibouti + { 4, 67 }, // Afar/Eritrea + { 4, 69 }, // Afar/Ethiopia + { 5, 195 }, // Afrikaans/SouthAfrica + { 5, 148 }, // Afrikaans/Namibia + { 6, 2 }, // Albanian/Albania + { 7, 69 }, // Amharic/Ethiopia + { 8, 186 }, // Arabic/SaudiArabia + { 8, 3 }, // Arabic/Algeria + { 8, 17 }, // Arabic/Bahrain + { 8, 64 }, // Arabic/Egypt + { 8, 103 }, // Arabic/Iraq + { 8, 109 }, // Arabic/Jordan + { 8, 115 }, // Arabic/Kuwait + { 8, 119 }, // Arabic/Lebanon + { 8, 122 }, // Arabic/LibyanArabJamahiriya + { 8, 145 }, // Arabic/Morocco + { 8, 162 }, // Arabic/Oman + { 8, 175 }, // Arabic/Qatar + { 8, 201 }, // Arabic/Sudan + { 8, 207 }, // Arabic/SyrianArabRepublic + { 8, 216 }, // Arabic/Tunisia + { 8, 223 }, // Arabic/UnitedArabEmirates + { 8, 237 }, // Arabic/Yemen + { 9, 11 }, // Armenian/Armenia + { 10, 100 }, // Assamese/India + { 12, 15 }, // Azerbaijani/Azerbaijan + { 14, 197 }, // Basque/Spain + { 15, 18 }, // Bengali/Bangladesh + { 15, 100 }, // Bengali/India + { 16, 25 }, // Bhutani/Bhutan + { 20, 33 }, // Bulgarian/Bulgaria + { 22, 20 }, // Byelorussian/Belarus + { 23, 36 }, // Cambodian/Cambodia + { 24, 197 }, // Catalan/Spain + { 25, 44 }, // Chinese/China + { 25, 97 }, // Chinese/HongKong + { 25, 126 }, // Chinese/Macau + { 25, 190 }, // Chinese/Singapore + { 25, 208 }, // Chinese/Taiwan + { 27, 54 }, // Croatian/Croatia + { 28, 57 }, // Czech/CzechRepublic + { 29, 58 }, // Danish/Denmark + { 30, 151 }, // Dutch/Netherlands + { 30, 21 }, // Dutch/Belgium + { 31, 225 }, // English/UnitedStates + { 31, 4 }, // English/AmericanSamoa + { 31, 13 }, // English/Australia + { 31, 21 }, // English/Belgium + { 31, 22 }, // English/Belize + { 31, 28 }, // English/Botswana + { 31, 38 }, // English/Canada + { 31, 89 }, // English/Guam + { 31, 97 }, // English/HongKong + { 31, 100 }, // English/India + { 31, 104 }, // English/Ireland + { 31, 107 }, // English/Jamaica + { 31, 133 }, // English/Malta + { 31, 134 }, // English/MarshallIslands + { 31, 148 }, // English/Namibia + { 31, 154 }, // English/NewZealand + { 31, 160 }, // English/NorthernMarianaIslands + { 31, 163 }, // English/Pakistan + { 31, 170 }, // English/Philippines + { 31, 190 }, // English/Singapore + { 31, 195 }, // English/SouthAfrica + { 31, 215 }, // English/TrinidadAndTobago + { 31, 224 }, // English/UnitedKingdom + { 31, 226 }, // English/UnitedStatesMinorOutlyingIslands + { 31, 234 }, // English/USVirginIslands + { 31, 240 }, // English/Zimbabwe + { 33, 68 }, // Estonian/Estonia + { 34, 71 }, // Faroese/FaroeIslands + { 36, 73 }, // Finnish/Finland + { 37, 74 }, // French/France + { 37, 21 }, // French/Belgium + { 37, 38 }, // French/Canada + { 37, 125 }, // French/Luxembourg + { 37, 142 }, // French/Monaco + { 37, 206 }, // French/Switzerland + { 40, 197 }, // Galician/Spain + { 41, 81 }, // Georgian/Georgia + { 42, 82 }, // German/Germany + { 42, 14 }, // German/Austria + { 42, 21 }, // German/Belgium + { 42, 123 }, // German/Liechtenstein + { 42, 125 }, // German/Luxembourg + { 42, 206 }, // German/Switzerland + { 43, 85 }, // Greek/Greece + { 43, 56 }, // Greek/Cyprus + { 44, 86 }, // Greenlandic/Greenland + { 46, 100 }, // Gujarati/India + { 47, 83 }, // Hausa/Ghana + { 47, 156 }, // Hausa/Niger + { 47, 157 }, // Hausa/Nigeria + { 48, 105 }, // Hebrew/Israel + { 49, 100 }, // Hindi/India + { 50, 98 }, // Hungarian/Hungary + { 51, 99 }, // Icelandic/Iceland + { 52, 101 }, // Indonesian/Indonesia + { 57, 104 }, // Irish/Ireland + { 58, 106 }, // Italian/Italy + { 58, 206 }, // Italian/Switzerland + { 59, 108 }, // Japanese/Japan + { 61, 100 }, // Kannada/India + { 63, 110 }, // Kazakh/Kazakhstan + { 64, 179 }, // Kinyarwanda/Rwanda + { 65, 116 }, // Kirghiz/Kyrgyzstan + { 66, 114 }, // Korean/RepublicOfKorea + { 67, 102 }, // Kurdish/Iran + { 67, 103 }, // Kurdish/Iraq + { 67, 207 }, // Kurdish/SyrianArabRepublic + { 67, 217 }, // Kurdish/Turkey + { 69, 117 }, // Laothian/Lao + { 71, 118 }, // Latvian/Latvia + { 72, 49 }, // Lingala/DemocraticRepublicOfCongo + { 72, 50 }, // Lingala/PeoplesRepublicOfCongo + { 73, 124 }, // Lithuanian/Lithuania + { 74, 127 }, // Macedonian/Macedonia + { 76, 130 }, // Malay/Malaysia + { 76, 32 }, // Malay/BruneiDarussalam + { 77, 100 }, // Malayalam/India + { 78, 133 }, // Maltese/Malta + { 80, 100 }, // Marathi/India + { 82, 143 }, // Mongolian/Mongolia + { 84, 150 }, // Nepali/Nepal + { 85, 161 }, // Norwegian/Norway + { 87, 100 }, // Oriya/India + { 88, 1 }, // Pashto/Afghanistan + { 89, 102 }, // Persian/Iran + { 89, 1 }, // Persian/Afghanistan + { 90, 172 }, // Polish/Poland + { 91, 173 }, // Portuguese/Portugal + { 91, 30 }, // Portuguese/Brazil + { 92, 100 }, // Punjabi/India + { 92, 163 }, // Punjabi/Pakistan + { 95, 177 }, // Romanian/Romania + { 96, 178 }, // Russian/RussianFederation + { 96, 222 }, // Russian/Ukraine + { 99, 100 }, // Sanskrit/India + { 100, 241 }, // Serbian/SerbiaAndMontenegro + { 100, 27 }, // Serbian/BosniaAndHerzegowina + { 100, 238 }, // Serbian/Yugoslavia + { 101, 241 }, // SerboCroatian/SerbiaAndMontenegro + { 101, 27 }, // SerboCroatian/BosniaAndHerzegowina + { 101, 238 }, // SerboCroatian/Yugoslavia + { 102, 195 }, // Sesotho/SouthAfrica + { 103, 195 }, // Setswana/SouthAfrica + { 107, 195 }, // Siswati/SouthAfrica + { 108, 191 }, // Slovak/Slovakia + { 109, 192 }, // Slovenian/Slovenia + { 110, 194 }, // Somali/Somalia + { 110, 59 }, // Somali/Djibouti + { 110, 69 }, // Somali/Ethiopia + { 110, 111 }, // Somali/Kenya + { 111, 197 }, // Spanish/Spain + { 111, 10 }, // Spanish/Argentina + { 111, 26 }, // Spanish/Bolivia + { 111, 43 }, // Spanish/Chile + { 111, 47 }, // Spanish/Colombia + { 111, 52 }, // Spanish/CostaRica + { 111, 61 }, // Spanish/DominicanRepublic + { 111, 63 }, // Spanish/Ecuador + { 111, 65 }, // Spanish/ElSalvador + { 111, 90 }, // Spanish/Guatemala + { 111, 96 }, // Spanish/Honduras + { 111, 139 }, // Spanish/Mexico + { 111, 155 }, // Spanish/Nicaragua + { 111, 166 }, // Spanish/Panama + { 111, 168 }, // Spanish/Paraguay + { 111, 169 }, // Spanish/Peru + { 111, 174 }, // Spanish/PuertoRico + { 111, 225 }, // Spanish/UnitedStates + { 111, 227 }, // Spanish/Uruguay + { 111, 231 }, // Spanish/Venezuela + { 113, 111 }, // Swahili/Kenya + { 113, 210 }, // Swahili/Tanzania + { 114, 205 }, // Swedish/Sweden + { 114, 73 }, // Swedish/Finland + { 116, 209 }, // Tajik/Tajikistan + { 117, 100 }, // Tamil/India + { 118, 178 }, // Tatar/RussianFederation + { 119, 100 }, // Telugu/India + { 120, 211 }, // Thai/Thailand + { 122, 67 }, // Tigrinya/Eritrea + { 122, 69 }, // Tigrinya/Ethiopia + { 124, 195 }, // Tsonga/SouthAfrica + { 125, 217 }, // Turkish/Turkey + { 129, 222 }, // Ukrainian/Ukraine + { 130, 100 }, // Urdu/India + { 130, 163 }, // Urdu/Pakistan + { 131, 228 }, // Uzbek/Uzbekistan + { 131, 1 }, // Uzbek/Afghanistan + { 132, 232 }, // Vietnamese/VietNam + { 134, 224 }, // Welsh/UnitedKingdom + { 136, 195 }, // Xhosa/SouthAfrica + { 138, 157 }, // Yoruba/Nigeria + { 140, 195 }, // Zulu/SouthAfrica + { 141, 161 }, // Nynorsk/Norway + { 142, 27 }, // Bosnian/BosniaAndHerzegowina + { 143, 131 }, // Divehi/Maldives + { 144, 224 }, // Manx/UnitedKingdom + { 145, 224 }, // Cornish/UnitedKingdom + { 146, 83 }, // Akan/Ghana + { 147, 100 }, // Konkani/India + { 148, 83 }, // Ga/Ghana + { 149, 157 }, // Igbo/Nigeria + { 150, 111 }, // Kamba/Kenya + { 151, 207 }, // Syriac/SyrianArabRepublic + { 152, 67 }, // Blin/Eritrea + { 153, 67 }, // Geez/Eritrea + { 153, 69 }, // Geez/Ethiopia + { 154, 157 }, // Koro/Nigeria + { 155, 69 }, // Sidamo/Ethiopia + { 156, 157 }, // Atsam/Nigeria + { 157, 67 }, // Tigre/Eritrea + { 158, 157 }, // Jju/Nigeria + { 159, 106 }, // Friulian/Italy + { 160, 195 }, // Venda/SouthAfrica + { 161, 83 }, // Ewe/Ghana + { 161, 212 }, // Ewe/Togo + { 163, 225 }, // Hawaiian/UnitedStates + { 164, 157 }, // Tyap/Nigeria + { 165, 129 }, // Chewa/Malawi +}; +static const int g_locale_list_count = sizeof(g_locale_list)/sizeof(g_locale_list[0]); + +LocaleModel::LocaleModel(QObject *parent) + : QAbstractItemModel(parent) +{ + m_data_list.append(1234.5678); + m_data_list.append(QDate::currentDate()); + m_data_list.append(QDate::currentDate()); + m_data_list.append(QTime::currentTime()); + m_data_list.append(QTime::currentTime()); +} + +QVariant LocaleModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid() + || role != Qt::DisplayRole && role != Qt::EditRole && role != Qt::ToolTipRole + || index.column() >= g_model_cols + || index.row() >= g_locale_list_count + 2) + return QVariant(); + + QVariant data; + if (index.column() < g_model_cols - 1) + data = m_data_list.at(index.column()); + + if (index.row() == 0) { + if (role == Qt::ToolTipRole) + return QVariant(); + switch (index.column()) { + case 0: + return data.toDouble(); + case 1: + return data.toDate(); + case 2: + return data.toDate(); + case 3: + return data.toTime(); + case 4: + return data.toTime(); + case 5: + return QVariant(); + default: + break; + } + } else { + QLocale locale; + if (index.row() == 1) { + locale = QLocale::system(); + } else { + LocaleListItem item = g_locale_list[index.row() - 2]; + locale = QLocale((QLocale::Language)item.language, (QLocale::Country)item.country); + } + + switch (index.column()) { + case 0: + if (role == Qt::ToolTipRole) + return QVariant(); + return locale.toString(data.toDouble()); + case 1: + if (role == Qt::ToolTipRole) + return locale.dateFormat(QLocale::LongFormat); + return locale.toString(data.toDate(), QLocale::LongFormat); + case 2: + if (role == Qt::ToolTipRole) + return locale.dateFormat(QLocale::ShortFormat); + return locale.toString(data.toDate(), QLocale::ShortFormat); + case 3: + if (role == Qt::ToolTipRole) + return locale.timeFormat(QLocale::LongFormat); + return locale.toString(data.toTime(), QLocale::LongFormat); + case 4: + if (role == Qt::ToolTipRole) + return locale.timeFormat(QLocale::ShortFormat); + return locale.toString(data.toTime(), QLocale::ShortFormat); + case 5: + if (role == Qt::ToolTipRole) + return QVariant(); + return locale.name(); + default: + break; + } + } + + return QVariant(); +} + +QVariant LocaleModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if (role != Qt::DisplayRole) + return QVariant(); + + if (orientation == Qt::Horizontal) { + switch (section) { + case 0: + return QLatin1String("Double"); + case 1: + return QLatin1String("Long Date"); + case 2: + return QLatin1String("Short Date"); + case 3: + return QLatin1String("Long Time"); + case 4: + return QLatin1String("Short Time"); + case 5: + return QLatin1String("Name"); + default: + break; + } + } else { + if (section >= g_locale_list_count + 2) + return QVariant(); + if (section == 0) { + return QLatin1String("Input"); + } else if (section == 1) { + return QLatin1String("System"); + } else { + LocaleListItem item = g_locale_list[section - 2]; + return QLocale::languageToString((QLocale::Language)item.language) + + QLatin1Char('/') + + QLocale::countryToString((QLocale::Country)item.country); + } + } + + return QVariant(); +} + +QModelIndex LocaleModel::index(int row, int column, + const QModelIndex &parent) const +{ + if (parent.isValid() + || row >= g_locale_list_count + 2 + || column >= g_model_cols) + return QModelIndex(); + + return createIndex(row, column); +} + +QModelIndex LocaleModel::parent(const QModelIndex&) const +{ + return QModelIndex(); +} + +int LocaleModel::columnCount(const QModelIndex&) const +{ + return g_model_cols; +} + +int LocaleModel::rowCount(const QModelIndex &parent) const +{ + if (parent.isValid()) + return 0; + return g_locale_list_count + 2; +} + +Qt::ItemFlags LocaleModel::flags(const QModelIndex &index) const +{ + if (!index.isValid()) + return 0; + if (index.row() == 0 && index.column() == g_model_cols - 1) + return 0; + if (index.row() == 0) + return Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled; + return Qt::ItemIsSelectable | Qt::ItemIsEnabled; +} + +bool LocaleModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + if (!index.isValid() + || index.row() != 0 + || index.column() >= g_model_cols - 1 + || role != Qt::EditRole + || m_data_list.at(index.column()).type() != value.type()) + return false; + + m_data_list[index.column()] = value; + emit dataChanged(createIndex(1, index.column()), + createIndex(g_locale_list_count, index.column())); + + return true; +} diff --git a/util/local_database/testlocales/localemodel.h b/util/local_database/testlocales/localemodel.h new file mode 100644 index 0000000000..9e569f7f09 --- /dev/null +++ b/util/local_database/testlocales/localemodel.h @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the utils of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef LOCALEMODEL_H +#define LOCALEMODEL_H + +#include +#include +#include + +class LocaleModel : public QAbstractItemModel +{ + Q_OBJECT +public: + LocaleModel(QObject *parent = 0); + + virtual int columnCount(const QModelIndex &parent = QModelIndex()) const; + virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const; + virtual QModelIndex index(int row, int column, + const QModelIndex &parent = QModelIndex()) const; + virtual QModelIndex parent(const QModelIndex &index) const; + virtual int rowCount(const QModelIndex &parent = QModelIndex()) const; + virtual QVariant headerData(int section, Qt::Orientation orientation, + int role = Qt::DisplayRole ) const; + virtual Qt::ItemFlags flags(const QModelIndex &index) const; + virtual bool setData(const QModelIndex &index, const QVariant &value, + int role = Qt::EditRole); +private: + QList m_data_list; +}; + +#endif // LOCALEMODEL_H diff --git a/util/local_database/testlocales/localewidget.cpp b/util/local_database/testlocales/localewidget.cpp new file mode 100644 index 0000000000..d20868f51b --- /dev/null +++ b/util/local_database/testlocales/localewidget.cpp @@ -0,0 +1,89 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the utils of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include +#include +#include +#include +#include + +#include "localewidget.h" +#include "localemodel.h" + +class DoubleEditorCreator : public QItemEditorCreatorBase +{ +public: + QWidget *createWidget(QWidget *parent) const { + QDoubleSpinBox *w = new QDoubleSpinBox(parent); + w->setDecimals(4); + w->setRange(-10000.0, 10000.0); + return w; + } + virtual QByteArray valuePropertyName() const { + return QByteArray("value"); + } +}; + +class EditorFactory : public QItemEditorFactory +{ +public: + EditorFactory() { + static DoubleEditorCreator double_editor_creator; + registerEditor(QVariant::Double, &double_editor_creator); + } +}; + +LocaleWidget::LocaleWidget(QWidget *parent) + : QWidget(parent) +{ + m_model = new LocaleModel(this); + m_view = new QTableView(this); + + QItemDelegate *delegate = qobject_cast(m_view->itemDelegate()); + Q_ASSERT(delegate != 0); + static EditorFactory editor_factory; + delegate->setItemEditorFactory(&editor_factory); + + m_view->setModel(m_model); + + QVBoxLayout *layout = new QVBoxLayout(this); + layout->setMargin(0); + layout->addWidget(m_view); +} diff --git a/util/local_database/testlocales/localewidget.h b/util/local_database/testlocales/localewidget.h new file mode 100644 index 0000000000..b119db043c --- /dev/null +++ b/util/local_database/testlocales/localewidget.h @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the utils of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#ifndef LOCALEWIDGET_H +#define LOCALEWIDGET_H + +#include + +class LocaleModel; +class QTableView; + +class LocaleWidget : public QWidget +{ + Q_OBJECT +public: + LocaleWidget(QWidget *parent = 0); +private: + LocaleModel *m_model; + QTableView *m_view; +}; + +#endif // LOCALEWIDGET_H diff --git a/util/local_database/testlocales/main.cpp b/util/local_database/testlocales/main.cpp new file mode 100644 index 0000000000..08aacd549f --- /dev/null +++ b/util/local_database/testlocales/main.cpp @@ -0,0 +1,51 @@ +/**************************************************************************** +** +** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the utils of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include + +#include "localewidget.h" + +int main(int argc, char *argv[]) +{ + QApplication app(argc, argv); + LocaleWidget wgt; + wgt.show(); + return app.exec(); +} diff --git a/util/local_database/testlocales/testlocales.pro b/util/local_database/testlocales/testlocales.pro new file mode 100644 index 0000000000..a9a6247f96 --- /dev/null +++ b/util/local_database/testlocales/testlocales.pro @@ -0,0 +1,4 @@ +TARGET = testlocales +CONFIG += debug +SOURCES += localemodel.cpp localewidget.cpp main.cpp +HEADERS += localemodel.h localewidget.h \ No newline at end of file diff --git a/util/local_database/xpathlite.py b/util/local_database/xpathlite.py new file mode 100644 index 0000000000..502d85d33a --- /dev/null +++ b/util/local_database/xpathlite.py @@ -0,0 +1,249 @@ +#!/usr/bin/env python +############################################################################# +## +## Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). +## All rights reserved. +## Contact: Nokia Corporation (qt-info@nokia.com) +## +## This file is part of the test suite of the Qt Toolkit. +## +## $QT_BEGIN_LICENSE:LGPL$ +## No Commercial Usage +## This file contains pre-release code and may not be distributed. +## You may use this file in accordance with the terms and conditions +## contained in the Technology Preview License Agreement accompanying +## this package. +## +## GNU Lesser General Public License Usage +## Alternatively, this file may be used under the terms of the GNU Lesser +## General Public License version 2.1 as published by the Free Software +## Foundation and appearing in the file LICENSE.LGPL included in the +## packaging of this file. Please review the following information to +## ensure the GNU Lesser General Public License version 2.1 requirements +## will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +## +## In addition, as a special exception, Nokia gives you certain additional +## rights. These rights are described in the Nokia Qt LGPL Exception +## version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +## +## If you have questions regarding the use of this file, please contact +## Nokia at qt-info@nokia.com. +## +## +## +## +## +## +## +## +## $QT_END_LICENSE$ +## +############################################################################# + +import sys +import os +import xml.dom.minidom + +doc_cache = {} + +class DraftResolution: + # See http://www.unicode.org/cldr/process.html for description + unconfirmed = 'unconfirmed' + provisional = 'provisional' + contributed = 'contributed' + approved = 'approved' + _values = { unconfirmed : 1, provisional : 2, contributed : 3, approved : 4 } + def __init__(self, resolution): + self.resolution = resolution + def toInt(self): + return DraftResolution._values[self.resolution] + +class Error: + def __init__(self, msg): + self.msg = msg + def __str__(self): + return self.msg + +def findChild(parent, tag_name, arg_name=None, arg_value=None, draft=None): + for node in parent.childNodes: + if node.nodeType != node.ELEMENT_NODE: + continue + if node.nodeName != tag_name: + continue + if arg_value: + if not node.attributes.has_key(arg_name): + continue + if node.attributes[arg_name].nodeValue != arg_value: + continue + if draft: + if not node.attributes.has_key('draft'): + # if draft is not specified then it's approved + return node + value = node.attributes['draft'].nodeValue + value = DraftResolution(value).toInt() + exemplar = DraftResolution(draft).toInt() + if exemplar > value: + continue + return node + return False + +def findTagsInFile(file, path): + doc = False + if doc_cache.has_key(file): + doc = doc_cache[file] + else: + doc = xml.dom.minidom.parse(file) + doc_cache[file] = doc + + elt = doc.documentElement + tag_spec_list = path.split("/") + last_entry = None + for i in range(len(tag_spec_list)): + tag_spec = tag_spec_list[i] + tag_name = tag_spec + arg_name = 'type' + arg_value = '' + left_bracket = tag_spec.find('[') + if left_bracket != -1: + tag_name = tag_spec[:left_bracket] + arg_value = tag_spec[left_bracket+1:-1].split("=") + if len(arg_value) == 2: + arg_name = arg_value[0] + arg_value = arg_value[1] + else: + arg_value = arg_value[0] + elt = findChild(elt, tag_name, arg_name, arg_value) + if not elt: + return None + ret = [] + if elt.childNodes: + for node in elt.childNodes: + if node.attributes: + element = [node.nodeName, None] + element[1] = node.attributes.items() + ret.append(element) + else: + if elt.attributes: + element = [elt.nodeName, None] + element[1] = elt.attributes.items() + ret.append(element) + return ret + +def _findEntryInFile(file, path, draft=None, attribute=None): + doc = False + if doc_cache.has_key(file): + doc = doc_cache[file] + else: + doc = xml.dom.minidom.parse(file) + doc_cache[file] = doc + + elt = doc.documentElement + tag_spec_list = path.split("/") + last_entry = None + for i in range(len(tag_spec_list)): + tag_spec = tag_spec_list[i] + tag_name = tag_spec + arg_name = 'type' + arg_value = '' + left_bracket = tag_spec.find('[') + if left_bracket != -1: + tag_name = tag_spec[:left_bracket] + arg_value = tag_spec[left_bracket+1:-1].split("=") + if len(arg_value) == 2: + arg_name = arg_value[0] + arg_value = arg_value[1] + else: + arg_value = arg_value[0] + alias = findChild(elt, 'alias') + if alias and alias.attributes['source'].nodeValue == 'locale': + path = alias.attributes['path'].nodeValue + aliaspath = tag_spec_list[:i] + path.split("/") + def resolve(x, y): + if y == '..': + return x[:-1] + return x + [y] + # resolve all dot-dot parts of the path + aliaspath = reduce(resolve, aliaspath, []) + # remove attribute specification that our xpathlite doesnt support + aliaspath = map(lambda x: x.replace("@type=", "").replace("'", ""), aliaspath) + # append the remaining path + aliaspath = aliaspath + tag_spec_list[i:] + aliaspath = "/".join(aliaspath) + # "locale" aliases are special - we need to start lookup from scratch + return (None, aliaspath) + elt = findChild(elt, tag_name, arg_name, arg_value, draft) + if not elt: + return ("", None) + if attribute is not None: + if elt.attributes.has_key(attribute): + return (elt.attributes[attribute].nodeValue, None) + return (None, None) + return (elt.firstChild.nodeValue, None) + +def findAlias(file): + if not doc_cache.has_key(file): + return False + doc = doc_cache[file] + alias_elt = findChild(doc.documentElement, "alias") + if not alias_elt: + return False + if not alias_elt.attributes.has_key('source'): + return False + return alias_elt.attributes['source'].nodeValue + +def _findEntry(base, path, draft=None, attribute=None): + file = base + if base.endswith(".xml"): + filename = base + base = base[:-4] + else: + file = base + ".xml" + (dirname, filename) = os.path.split(base) + items = filename.split("_") + # split locale name into items and iterate through them from back to front + # example: az_Latn_AZ => [az_Latn_AZ, az_Latn, az] + items = reversed(map(lambda x: "_".join(items[:x+1]), range(len(items)))) + for item in items: + file = dirname + "/" + item + ".xml" + if os.path.isfile(file): + alias = findAlias(file) + if alias: + # if alias is found we should follow it and stop processing current file + # see http://www.unicode.org/reports/tr35/#Common_Elements + aliasfile = os.path.dirname(file) + "/" + alias + ".xml" + if not os.path.isfile(aliasfile): + raise Error("findEntry: fatal error: found an alias '%s' to '%s', but the alias file couldnt be found" % (filename, alias)) + # found an alias, recurse into parsing it + result = _findEntry(aliasfile, path, draft, attribute) + return result + (result, aliaspath) = _findEntryInFile(file, path, draft, attribute) + if aliaspath: + # start lookup again because of the alias source="locale" + return _findEntry(base, aliaspath, draft, attribute) + if result: + return result + return None + +def findEntry(base, path, draft=None, attribute=None): + file = base + if base.endswith(".xml"): + file = base + base = base[:-4] + else: + file = base + ".xml" + (dirname, filename) = os.path.split(base) + + result = None + while path: + result = _findEntry(base, path, draft, attribute) + if result: + return result + (result, aliaspath) = _findEntryInFile(dirname + "/root.xml", path, draft, attribute) + if result: + return result + if not aliaspath: + raise Error("findEntry: fatal error: %s: did not found key %s" % (filename, path)) + path = aliaspath + + return result + -- cgit v1.2.3