From 78e216fedbbcdcf4fc40c5a69e075521aa16be80 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Sun, 14 Aug 2022 16:26:46 +0200 Subject: [PATCH] [locale] Introduce a similarity-score for locales --- src/modules/locale/LocaleNames.cpp | 18 ++++++++++++++ src/modules/locale/LocaleNames.h | 8 ++++++ src/modules/locale/Tests.cpp | 40 ++++++++++++++++++++++++++++++ 3 files changed, 66 insertions(+) diff --git a/src/modules/locale/LocaleNames.cpp b/src/modules/locale/LocaleNames.cpp index 148d21472..93e844446 100644 --- a/src/modules/locale/LocaleNames.cpp +++ b/src/modules/locale/LocaleNames.cpp @@ -70,3 +70,21 @@ LocaleNameParts::name() const + insertLeadingChar( '@', region ); } } + + +int +LocaleNameParts::similarity( const LocaleNameParts& other ) const +{ + if ( !isValid() || !other.isValid() ) + { + return 0; + } + if ( language != other.language ) + { + return 0; + } + const auto matched_region = ( region == other.region ? 30 : 0 ); + const auto matched_country = ( country == other.country ? 20 : 0 ); + const auto no_other_country_given = ( ( country != other.country && other.country.isEmpty() ) ? 10 : 0 ); + return 50 + matched_region + matched_country + no_other_country_given; +} diff --git a/src/modules/locale/LocaleNames.h b/src/modules/locale/LocaleNames.h index 976ee20b3..247a8496c 100644 --- a/src/modules/locale/LocaleNames.h +++ b/src/modules/locale/LocaleNames.h @@ -30,6 +30,14 @@ struct LocaleNameParts QString name() const; static LocaleNameParts fromName( const QString& name ); + + /** @brief Compute similarity-score with another locale-name. + * + * Similarity is driven by language and region, then country. + * Returns a number between 0 (no similarity, e.g. the + * language is different) and 100 (complete match). + */ + int similarity( const LocaleNameParts& other ) const; }; #endif diff --git a/src/modules/locale/Tests.cpp b/src/modules/locale/Tests.cpp index 85ec34026..fda58059a 100644 --- a/src/modules/locale/Tests.cpp +++ b/src/modules/locale/Tests.cpp @@ -59,6 +59,7 @@ private Q_SLOTS: void testLanguageMappingNeon(); void testLanguageMappingFreeBSD_data(); void testLanguageMappingFreeBSD(); + void testLanguageSimilarity(); private: QStringList m_KDEneonLocales; @@ -536,6 +537,45 @@ LocaleTests::testLocaleNameParts() } } +void +LocaleTests::testLanguageSimilarity() +{ + // Empty + { + QCOMPARE( LocaleNameParts().similarity( LocaleNameParts() ), 0 ); + } + // Some simple Dutch situations + { + auto nl_parts = LocaleNameParts::fromName( QStringLiteral( "nl_NL.UTF-8" ) ); + auto be_parts = LocaleNameParts::fromName( QStringLiteral( "nl_BE.UTF-8" ) ); + auto nl_short_parts = LocaleNameParts::fromName( QStringLiteral( "nl" ) ); + QCOMPARE( nl_parts.similarity( nl_parts ), 100 ); + QCOMPARE( nl_parts.similarity( LocaleNameParts() ), 0 ); + QCOMPARE( nl_parts.similarity( be_parts ), 80 ); // Language + (empty) region match + QCOMPARE( nl_parts.similarity( nl_short_parts ), 90 ); + } + + // Everything matches itself + { + if ( m_KDEneonLocales.isEmpty() ) + { + testKDENeonLanguageData(); + } + QVERIFY( !m_FreeBSDLocales.isEmpty() ); + QVERIFY( !m_KDEneonLocales.isEmpty() ); + for ( const auto& l : m_KDEneonLocales ) + { + auto locale_name = LocaleNameParts::fromName( l ); + auto self_similarity = locale_name.similarity( locale_name ); + if ( self_similarity != 100 ) + { + cDebug() << "Locale" << l << "is unusual."; + } + QCOMPARE( self_similarity, 100 ); + } + } +} + #include "utils/moc-warnings.h"