[locale] Approach matching from a different angle
- add struct that splits a locale name into parts - add tests that the splitting and joining works
This commit is contained in:
parent
84c0da2186
commit
fd56b5bdc4
@ -22,6 +22,7 @@ calamares_add_plugin(locale
|
|||||||
Config.cpp
|
Config.cpp
|
||||||
LCLocaleDialog.cpp
|
LCLocaleDialog.cpp
|
||||||
LocaleConfiguration.cpp
|
LocaleConfiguration.cpp
|
||||||
|
LocaleNames.cpp
|
||||||
LocalePage.cpp
|
LocalePage.cpp
|
||||||
LocaleViewStep.cpp
|
LocaleViewStep.cpp
|
||||||
SetTimezoneJob.cpp
|
SetTimezoneJob.cpp
|
||||||
@ -39,7 +40,7 @@ calamares_add_plugin(locale
|
|||||||
|
|
||||||
calamares_add_test(
|
calamares_add_test(
|
||||||
localetest
|
localetest
|
||||||
SOURCES Tests.cpp Config.cpp LocaleConfiguration.cpp SetTimezoneJob.cpp timezonewidget/TimeZoneImage.cpp
|
SOURCES Tests.cpp Config.cpp LocaleConfiguration.cpp LocaleNames.cpp SetTimezoneJob.cpp timezonewidget/TimeZoneImage.cpp
|
||||||
DEFINITIONS SOURCE_DIR="${CMAKE_CURRENT_LIST_DIR}/images" DEBUG_TIMEZONES=1
|
DEFINITIONS SOURCE_DIR="${CMAKE_CURRENT_LIST_DIR}/images" DEBUG_TIMEZONES=1
|
||||||
LIBRARIES Qt5::Gui
|
LIBRARIES Qt5::Gui
|
||||||
)
|
)
|
||||||
|
72
src/modules/locale/LocaleNames.cpp
Normal file
72
src/modules/locale/LocaleNames.cpp
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
/* === This file is part of Calamares - <https://calamares.io> ===
|
||||||
|
*
|
||||||
|
* SPDX-FileCopyrightText: 2022 Adriaan de Groot <groot@kde.org>
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
*
|
||||||
|
* Calamares is Free Software: see the License-Identifier above.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "LocaleNames.h"
|
||||||
|
|
||||||
|
#include "utils/Logger.h"
|
||||||
|
|
||||||
|
#include <QRegularExpression>
|
||||||
|
|
||||||
|
LocaleNameParts
|
||||||
|
LocaleNameParts::fromName( const QString& name )
|
||||||
|
{
|
||||||
|
auto requireAndRemoveLeadingChar = []( QChar c, QString s )
|
||||||
|
{
|
||||||
|
if ( s.startsWith( c ) )
|
||||||
|
{
|
||||||
|
return s.remove( 0, 1 );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
auto parts = QRegularExpression( "^([a-zA-Z]+)(_[a-zA-Z]+)?(\\.[-a-zA-Z0-9]+)?(@[a-zA-Z]+)?" ).match( name );
|
||||||
|
const QString calamaresLanguage = parts.captured( 1 );
|
||||||
|
const QString calamaresCountry = requireAndRemoveLeadingChar( '_', parts.captured( 2 ) );
|
||||||
|
const QString calamaresEncoding = requireAndRemoveLeadingChar( '.', parts.captured( 3 ) );
|
||||||
|
const QString calamaresRegion = requireAndRemoveLeadingChar( '@', parts.captured( 4 ) );
|
||||||
|
|
||||||
|
if ( calamaresLanguage.isEmpty() )
|
||||||
|
{
|
||||||
|
return LocaleNameParts {};
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return LocaleNameParts { calamaresLanguage, calamaresCountry, calamaresRegion, calamaresEncoding };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QString
|
||||||
|
LocaleNameParts::name() const
|
||||||
|
{
|
||||||
|
// We don't want QStringView to a temporary; force conversion
|
||||||
|
auto insertLeadingChar = []( QChar c, QString s ) -> QString
|
||||||
|
{
|
||||||
|
if ( s.isEmpty() )
|
||||||
|
{
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return c + s;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if ( !isValid() )
|
||||||
|
{
|
||||||
|
return QString();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return language + insertLeadingChar( '_', country ) + insertLeadingChar( '.', encoding )
|
||||||
|
+ insertLeadingChar( '@', region );
|
||||||
|
}
|
||||||
|
}
|
35
src/modules/locale/LocaleNames.h
Normal file
35
src/modules/locale/LocaleNames.h
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
/* === This file is part of Calamares - <https://calamares.io> ===
|
||||||
|
*
|
||||||
|
* SPDX-FileCopyrightText: 2022 Adriaan de Groot <groot@kde.org>
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
*
|
||||||
|
* Calamares is Free Software: see the License-Identifier above.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef LOCALENAMES_H
|
||||||
|
#define LOCALENAMES_H
|
||||||
|
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
/** @brief parts of a locale-name (e.g. "ar_LY.UTF-8", split apart)
|
||||||
|
*
|
||||||
|
* These are created from lines in `/usr/share/i18n/SUPPORTED`,
|
||||||
|
* which lists all the locales supported by the system (there
|
||||||
|
* are also other sources of the same).
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
struct LocaleNameParts
|
||||||
|
{
|
||||||
|
QString language; // e.g. "ar"
|
||||||
|
QString country; // e.g. "LY" (may be empty)
|
||||||
|
QString region; // e.g. "@valencia" (may be empty)
|
||||||
|
QString encoding; // e.g. "UTF-8" (may be empty)
|
||||||
|
|
||||||
|
bool isValid() const { return !language.isEmpty(); }
|
||||||
|
QString name() const;
|
||||||
|
|
||||||
|
static LocaleNameParts fromName( const QString& name );
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
#include "Config.h"
|
#include "Config.h"
|
||||||
#include "LocaleConfiguration.h"
|
#include "LocaleConfiguration.h"
|
||||||
|
#include "LocaleNames.h"
|
||||||
#include "timezonewidget/TimeZoneImage.h"
|
#include "timezonewidget/TimeZoneImage.h"
|
||||||
|
|
||||||
#include "Settings.h"
|
#include "Settings.h"
|
||||||
@ -49,8 +50,11 @@ private Q_SLOTS:
|
|||||||
void testLanguageDetection();
|
void testLanguageDetection();
|
||||||
void testLanguageDetectionValencia();
|
void testLanguageDetectionValencia();
|
||||||
|
|
||||||
// Check realistic language mapping for issue 2008
|
// Check that the test-data is available and ok
|
||||||
void testKDENeonLanguageData();
|
void testKDENeonLanguageData();
|
||||||
|
void testLocaleNameParts();
|
||||||
|
|
||||||
|
// Check realistic language mapping for issue 2008
|
||||||
void testLanguageMappingNeon_data();
|
void testLanguageMappingNeon_data();
|
||||||
void testLanguageMappingNeon();
|
void testLanguageMappingNeon();
|
||||||
void testLanguageMappingFreeBSD_data();
|
void testLanguageMappingFreeBSD_data();
|
||||||
@ -392,6 +396,10 @@ splitTestFileIntoLines( const QString& filename )
|
|||||||
void
|
void
|
||||||
LocaleTests::testKDENeonLanguageData()
|
LocaleTests::testKDENeonLanguageData()
|
||||||
{
|
{
|
||||||
|
if ( !m_KDEneonLocales.isEmpty() )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
const QStringList neonLocales = splitTestFileIntoLines( QStringLiteral( "locale-data-neon" ) );
|
const QStringList neonLocales = splitTestFileIntoLines( QStringLiteral( "locale-data-neon" ) );
|
||||||
cDebug() << "Loaded KDE neon locales test data" << neonLocales.front() << "to" << neonLocales.back();
|
cDebug() << "Loaded KDE neon locales test data" << neonLocales.front() << "to" << neonLocales.back();
|
||||||
QCOMPARE( neonLocales.length(), 318 ); // wc -l tells me 318 lines
|
QCOMPARE( neonLocales.length(), 318 ); // wc -l tells me 318 lines
|
||||||
@ -412,7 +420,7 @@ LocaleTests::MappingData()
|
|||||||
|
|
||||||
// Tired of writing QString or QStringLiteral all the time.
|
// Tired of writing QString or QStringLiteral all the time.
|
||||||
auto l = []( const char* p ) { return QString::fromUtf8( p ); };
|
auto l = []( const char* p ) { return QString::fromUtf8( p ); };
|
||||||
auto u = [](){ return QString(); };
|
auto u = []() { return QString(); };
|
||||||
|
|
||||||
// The KDEneon columns include the .UTF-8 from the source data
|
// The KDEneon columns include the .UTF-8 from the source data
|
||||||
// The FreeBSD columns may have u() to indicate "same as KDEneon",
|
// The FreeBSD columns may have u() to indicate "same as KDEneon",
|
||||||
@ -442,12 +450,14 @@ LocaleTests::MappingData()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void LocaleTests::testLanguageMappingNeon_data()
|
void
|
||||||
|
LocaleTests::testLanguageMappingNeon_data()
|
||||||
{
|
{
|
||||||
MappingData();
|
MappingData();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LocaleTests::testLanguageMappingFreeBSD_data()
|
void
|
||||||
|
LocaleTests::testLanguageMappingFreeBSD_data()
|
||||||
{
|
{
|
||||||
MappingData();
|
MappingData();
|
||||||
}
|
}
|
||||||
@ -455,6 +465,7 @@ void LocaleTests::testLanguageMappingFreeBSD_data()
|
|||||||
void
|
void
|
||||||
LocaleTests::testLanguageMappingNeon()
|
LocaleTests::testLanguageMappingNeon()
|
||||||
{
|
{
|
||||||
|
testKDENeonLanguageData();
|
||||||
QVERIFY( !m_KDEneonLocales.isEmpty() );
|
QVERIFY( !m_KDEneonLocales.isEmpty() );
|
||||||
|
|
||||||
QFETCH( QString, selectedLanguage );
|
QFETCH( QString, selectedLanguage );
|
||||||
@ -471,6 +482,7 @@ LocaleTests::testLanguageMappingNeon()
|
|||||||
void
|
void
|
||||||
LocaleTests::testLanguageMappingFreeBSD()
|
LocaleTests::testLanguageMappingFreeBSD()
|
||||||
{
|
{
|
||||||
|
testKDENeonLanguageData();
|
||||||
QVERIFY( !m_FreeBSDLocales.isEmpty() );
|
QVERIFY( !m_FreeBSDLocales.isEmpty() );
|
||||||
|
|
||||||
QFETCH( QString, selectedLanguage );
|
QFETCH( QString, selectedLanguage );
|
||||||
@ -485,6 +497,45 @@ LocaleTests::testLanguageMappingFreeBSD()
|
|||||||
QCOMPARE( bsd.language(), expected );
|
QCOMPARE( bsd.language(), expected );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
LocaleTests::testLocaleNameParts()
|
||||||
|
{
|
||||||
|
testKDENeonLanguageData();
|
||||||
|
QVERIFY( !m_FreeBSDLocales.isEmpty() );
|
||||||
|
QVERIFY( !m_KDEneonLocales.isEmpty() );
|
||||||
|
|
||||||
|
// Example constant locales
|
||||||
|
{
|
||||||
|
auto c_parts = LocaleNameParts::fromName( QStringLiteral( "nl_NL.UTF-8" ) );
|
||||||
|
QCOMPARE( c_parts.language, QStringLiteral( "nl" ) );
|
||||||
|
QCOMPARE( c_parts.country, QStringLiteral( "NL" ) );
|
||||||
|
QCOMPARE( c_parts.encoding, QStringLiteral( "UTF-8" ) );
|
||||||
|
QVERIFY( c_parts.region.isEmpty() );
|
||||||
|
}
|
||||||
|
{
|
||||||
|
auto c_parts = LocaleNameParts::fromName( QStringLiteral( "C.UTF-8" ) );
|
||||||
|
QCOMPARE( c_parts.language, QStringLiteral( "C" ) );
|
||||||
|
QVERIFY( c_parts.country.isEmpty() );
|
||||||
|
QCOMPARE( c_parts.encoding, QStringLiteral( "UTF-8" ) );
|
||||||
|
QVERIFY( c_parts.region.isEmpty() );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check all the loaded test locales
|
||||||
|
for ( const auto& s : m_FreeBSDLocales )
|
||||||
|
{
|
||||||
|
auto parts = LocaleNameParts::fromName( s );
|
||||||
|
QVERIFY( parts.isValid() );
|
||||||
|
QCOMPARE( parts.name(), s );
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( const auto& s : m_KDEneonLocales )
|
||||||
|
{
|
||||||
|
auto parts = LocaleNameParts::fromName( s );
|
||||||
|
QVERIFY( parts.isValid() );
|
||||||
|
QCOMPARE( parts.name(), s );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#include "utils/moc-warnings.h"
|
#include "utils/moc-warnings.h"
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user