Skip to content

Commit

Permalink
[locale] Refactor matching some more
Browse files Browse the repository at this point in the history
- find the best score and match relative to a specific
  set of parts; make it easy to update the country-setting
- look for a complete match, or best match, with three
  country settings
  • Loading branch information
adriaandegroot committed Aug 22, 2022
1 parent 6cbf2d7 commit a422fd8
Showing 1 changed file with 65 additions and 24 deletions.
89 changes: 65 additions & 24 deletions src/modules/locale/LocaleConfiguration.cpp
Expand Up @@ -42,6 +42,34 @@ LocaleConfiguration::setLanguage( const QString& localeName )
m_lang = localeName;
}

static LocaleNameParts
updateCountry( LocaleNameParts p, const QString& country )
{
p.country = country;
return p;
}

static QPair< int, LocaleNameParts >
identifyBestLanguageMatch( const LocaleNameParts& referenceLocale, QVector< LocaleNameParts >& others )
{
std::sort( others.begin(),
others.end(),
[ & ]( const LocaleNameParts& lhs, const LocaleNameParts& rhs )
{ return referenceLocale.similarity( lhs ) < referenceLocale.similarity( rhs ); } );
// The best match is at the end
LocaleNameParts best_match = others.last();
if ( !( referenceLocale.similarity( best_match ) > LocaleNameParts::no_match ) )
{
cDebug() << Logger::SubEntry << "Got no good match for" << referenceLocale.name();
return { LocaleNameParts::no_match, LocaleNameParts {} };
}
else
{
cDebug() << Logger::SubEntry << "Got best match for" << referenceLocale.name() << "as" << best_match.name();
return { referenceLocale.similarity( best_match ), best_match };
}
}

/** @brief Returns the QString from @p availableLocales that best-matches.
*/
static LocaleNameParts
Expand All @@ -57,39 +85,52 @@ identifyBestLanguageMatch( const QString& languageLocale,
QVector< LocaleNameParts > others;
others.resize( availableLocales.length() ); // Makes default structs
std::transform( availableLocales.begin(), availableLocales.end(), others.begin(), LocaleNameParts::fromName );
std::sort( others.begin(),
others.end(),
[ reference = self ]( const LocaleNameParts& lhs, const LocaleNameParts& rhs )
{ return reference.similarity( lhs ) < reference.similarity( rhs ); } );

// The best match is at the end
LocaleNameParts best_match = others.last();
if ( !( self.similarity( best_match ) > LocaleNameParts::no_match ) )

// Keep track of the best match in various attempts
int best_score = LocaleNameParts::no_match;
LocaleNameParts best_match;

// Check with the unmodified language setting
{
cDebug() << Logger::SubEntry << "Got no good match for" << languageLocale;
best_match = LocaleNameParts {};
auto [ score, match ] = identifyBestLanguageMatch( self, others );
if ( score >= LocaleNameParts::complete_match )
{
return match;
}
else if ( score > best_score )
{
best_match = match;
}
}
else


// .. but it might match **better** with the chosen location country Code
{
cDebug() << Logger::SubEntry << "Got best match for" << languageLocale << "as" << best_match.name();
auto [ score, match ] = identifyBestLanguageMatch( updateCountry( self, countryCode ), others );
if ( score >= LocaleNameParts::complete_match )
{
return match;
}
else if ( score > best_score )
{
best_match = match;
}
}

// .. but it might match **better** with the chosen location country Code
if ( self.similarity( best_match ) < LocaleNameParts::complete_match )
// .. or better yet with the QLocale-derived country
{
auto self_other_country( self );
self_other_country.country = countryCode;
std::sort( others.begin(),
others.end(),
[ reference = self_other_country ]( const LocaleNameParts& lhs, const LocaleNameParts& rhs )
{ return reference.similarity( lhs ) < reference.similarity( rhs ); } );
if ( self_other_country.similarity( others.last() ) > self.similarity( best_match ) )
const QString localeCountry = LocaleNameParts::fromName( QLocale( languageLocale ).name() ).country;
auto [ score, match ] = identifyBestLanguageMatch( updateCountry( self, localeCountry ), others );
if ( score >= LocaleNameParts::complete_match )
{
best_match = others.last();
cDebug() << Logger::SubEntry << "Found better match with country" << countryCode << "as"
<< best_match.name();
return match;
}
else if ( score > best_score )
{
best_match = match;
}
}

if ( best_match.isValid() )
{
cDebug() << Logger::SubEntry << "Matched best with" << best_match.name();
Expand Down

0 comments on commit a422fd8

Please sign in to comment.