Merge branch 'master' of https://github.com/calamares/calamares into development

This commit is contained in:
Philip Müller 2019-01-09 13:13:58 +01:00
commit d38db49bc9
11 changed files with 262 additions and 72 deletions

26
CHANGES
View File

@ -3,7 +3,7 @@ contributors are listed. Note that Calamares does not have a historical
changelog -- this log starts with version 3.2.0. The release notes on the changelog -- this log starts with version 3.2.0. The release notes on the
website will have to do for older versions. website will have to do for older versions.
# 3.2.3 (unreleased) # # 3.2.4 (unreleased) #
This release contains contributions from (alphabetically by first name): This release contains contributions from (alphabetically by first name):
- Alf Gaida - Alf Gaida
@ -45,6 +45,30 @@ This release contains contributions from (alphabetically by first name):
for all operations, not just during install (keep in mind that for all operations, not just during install (keep in mind that
these run as three separate shells, though). these run as three separate shells, though).
# 3.2.3 (2019-01-09) #
This release contains contributions from (alphabetically by first name):
- aliveafter1000
## Core ##
There are no core changes in this release.
## Modules ##
* *partition* Fixed bug where, during detection of existing systems, the
existing system partitions may be mounted and then files deleted.
This is a **limited** version of the patch from aliveafter1000
that will be in 3.2.4, which tries harder to mount filesystems
read-only and unmodifiable.
* *locale* It was possible to set the installer and system language
(e.g. to German) while the global storage value for *locale*
remained set to English. Then no localization packages are installed
(see feature `${LOCALE}` in `packages.conf`). Reported downstream
in Netrunner.
# 3.2.2 (2018-09-04) # # 3.2.2 (2018-09-04) #
This release contains contributions from (alphabetically by first name): This release contains contributions from (alphabetically by first name):

View File

@ -75,7 +75,7 @@ set( CALAMARES_DESCRIPTION_SUMMARY
set( CALAMARES_VERSION_MAJOR 3 ) set( CALAMARES_VERSION_MAJOR 3 )
set( CALAMARES_VERSION_MINOR 2 ) set( CALAMARES_VERSION_MINOR 2 )
set( CALAMARES_VERSION_PATCH 3 ) set( CALAMARES_VERSION_PATCH 4 )
set( CALAMARES_VERSION_RC 1 ) set( CALAMARES_VERSION_RC 1 )

View File

@ -1,7 +1,7 @@
/* === This file is part of Calamares - <https://github.com/calamares> === /* === This file is part of Calamares - <https://github.com/calamares> ===
* *
* Copyright 2014-2016, Teo Mrnjavac <teo@kde.org> * Copyright 2014-2016, Teo Mrnjavac <teo@kde.org>
* Copyright 2017-2018, Adriaan de Groot <groot@kde.org> * Copyright 2017-2019, Adriaan de Groot <groot@kde.org>
* *
* Calamares is free software: you can redistribute it and/or modify * Calamares is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -275,16 +275,21 @@ gettext_path()
} }
_add_localedirs( candidatePaths, QDir().canonicalPath() ); // . _add_localedirs( candidatePaths, QDir().canonicalPath() ); // .
cDebug() << "Standard paths" << candidatePaths; cDebug() << "Determining gettext path from" << candidatePaths;
for ( auto lang : _gettext_languages() ) QStringList candidateLanguages = _gettext_languages();
for ( const auto& lang : candidateLanguages )
for ( auto localedir : candidatePaths ) for ( auto localedir : candidatePaths )
{ {
QDir ldir( localedir ); QDir ldir( localedir );
cDebug() << "Checking" << lang << "in" <<ldir.canonicalPath();
if ( ldir.cd( lang ) ) if ( ldir.cd( lang ) )
{
cDebug() << " .. Found" << lang << "in" << ldir.canonicalPath();
return bp::object( localedir.toStdString() ); return bp::object( localedir.toStdString() );
} }
}
cDebug() << " .. None found for" << candidateLanguages;
return bp::object(); // None return bp::object(); // None
} }

View File

@ -53,6 +53,17 @@ if( ECM_FOUND AND BUILD_TESTING )
${YAMLCPP_LIBRARY} ${YAMLCPP_LIBRARY}
) )
set_target_properties( geoiptest PROPERTIES AUTOMOC TRUE ) set_target_properties( geoiptest PROPERTIES AUTOMOC TRUE )
ecm_add_test(
Tests.cpp
LocaleConfiguration.cpp
TEST_NAME
localetest
LINK_LIBRARIES
calamares
Qt5::Test
)
set_target_properties( localetest PROPERTIES AUTOMOC TRUE )
endif() endif()
if( BUILD_TESTING ) if( BUILD_TESTING )

View File

@ -1,7 +1,7 @@
/* === This file is part of Calamares - <https://github.com/calamares> === /* === This file is part of Calamares - <https://github.com/calamares> ===
* *
* Copyright 2016, Teo Mrnjavac <teo@kde.org> * Copyright 2016, Teo Mrnjavac <teo@kde.org>
* Copyright 2017-2018, Adriaan de Groot <groot@kde.org> * Copyright 2017-2019, Adriaan de Groot <groot@kde.org>
* *
* Calamares is free software: you can redistribute it and/or modify * Calamares is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -27,14 +27,23 @@ LocaleConfiguration::LocaleConfiguration()
} }
LocaleConfiguration LocaleConfiguration::LocaleConfiguration( const QString& localeName, const QString& formatsName )
LocaleConfiguration::createDefault() : LocaleConfiguration()
{ {
LocaleConfiguration lc = LocaleConfiguration(); lc_numeric = lc_time = lc_monetary = lc_paper = lc_name
lc.lang = lc.lc_numeric = lc.lc_time = lc.lc_monetary = lc.lc_paper = lc.lc_name = lc_address = lc_telephone = lc_measurement
= lc.lc_address = lc.lc_telephone = lc.lc_measurement = lc_identification = formatsName;
= lc.lc_identification = "en_US.UTF-8";
return lc; (void) setLanguage( localeName );
}
void
LocaleConfiguration::setLanguage(const QString& localeName )
{
QString language = localeName.split( '_' ).first();
m_languageLocaleBcp47 = QLocale( language ).bcp47Name().toLower();
m_lang = localeName;
} }
@ -43,11 +52,7 @@ LocaleConfiguration::fromLanguageAndLocation( const QString& languageLocale,
const QStringList& availableLocales, const QStringList& availableLocales,
const QString& countryCode ) const QString& countryCode )
{ {
LocaleConfiguration lc;
// Note that the documentation how this works is in packages.conf
QString language = languageLocale.split( '_' ).first(); QString language = languageLocale.split( '_' ).first();
lc.myLanguageLocaleBcp47 = QLocale(language).bcp47Name().toLower();
QStringList linesForLanguage; QStringList linesForLanguage;
for ( const QString &line : availableLocales ) for ( const QString &line : availableLocales )
@ -264,19 +269,14 @@ LocaleConfiguration::fromLanguageAndLocation( const QString& languageLocale,
if ( lc_formats.isEmpty() ) if ( lc_formats.isEmpty() )
lc_formats = lang; lc_formats = lang;
lc.lang = lang; return LocaleConfiguration( lang, lc_formats );
lc.lc_address = lc.lc_identification = lc.lc_measurement = lc.lc_monetary
= lc.lc_name = lc.lc_numeric = lc.lc_paper = lc.lc_telephone
= lc.lc_time = lc_formats;
return lc;
} }
bool bool
LocaleConfiguration::isEmpty() const LocaleConfiguration::isEmpty() const
{ {
return lang.isEmpty() && return m_lang.isEmpty() &&
lc_numeric.isEmpty() && lc_numeric.isEmpty() &&
lc_time.isEmpty() && lc_time.isEmpty() &&
lc_monetary.isEmpty() && lc_monetary.isEmpty() &&
@ -294,8 +294,8 @@ LocaleConfiguration::toMap() const
{ {
QMap< QString, QString > map; QMap< QString, QString > map;
if ( !lang.isEmpty() ) if ( !m_lang.isEmpty() )
map.insert( "LANG", lang ); map.insert( "LANG", m_lang );
if ( !lc_numeric.isEmpty() ) if ( !lc_numeric.isEmpty() )
map.insert( "LC_NUMERIC", lc_numeric ); map.insert( "LC_NUMERIC", lc_numeric );
@ -327,8 +327,3 @@ LocaleConfiguration::toMap() const
return map; return map;
} }
QString
LocaleConfiguration::toBcp47() const
{
return myLanguageLocaleBcp47;
}

View File

@ -1,7 +1,7 @@
/* === This file is part of Calamares - <https://github.com/calamares> === /* === This file is part of Calamares - <https://github.com/calamares> ===
* *
* Copyright 2016, Teo Mrnjavac <teo@kde.org> * Copyright 2016, Teo Mrnjavac <teo@kde.org>
* Copyright 2017-2018, Adriaan de Groot <groot@kde.org> * Copyright 2017-2019, Adriaan de Groot <groot@kde.org>
* *
* Calamares is free software: you can redistribute it and/or modify * Calamares is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -20,28 +20,42 @@
#ifndef LOCALECONFIGURATION_H #ifndef LOCALECONFIGURATION_H
#define LOCALECONFIGURATION_H #define LOCALECONFIGURATION_H
#include <QDebug>
#include <QString> #include <QString>
#include <QMap> #include <QMap>
class LocaleConfiguration class LocaleConfiguration
{ {
public: public:
/// @brief Create an empty locale, with nothing set
explicit LocaleConfiguration(); explicit LocaleConfiguration();
/// @brief Create a locale with everything set to the given @p localeName
explicit LocaleConfiguration( const QString& localeName /* "en_US.UTF-8" */ )
: LocaleConfiguration( localeName, localeName ) { };
/// @brief Create a locale with language and formats separate
explicit LocaleConfiguration( const QString& localeName, const QString& formatsName );
static LocaleConfiguration createDefault();
static LocaleConfiguration fromLanguageAndLocation( const QString& language, static LocaleConfiguration fromLanguageAndLocation( const QString& language,
const QStringList& availableLocales, const QStringList& availableLocales,
const QString& countryCode ); const QString& countryCode );
bool isEmpty() const; bool isEmpty() const;
QMap< QString, QString > toMap() const; /** @brief sets lang and the BCP47 representation
*
* Note that the documentation how this works is in packages.conf
*/
void setLanguage( const QString& localeName );
QString language() const { return m_lang; }
// Note that the documentation how this works is in packages.conf // Note that the documentation how this works is in packages.conf
QString toBcp47() const; QString toBcp47() const { return m_languageLocaleBcp47; }
QMap< QString, QString > toMap() const;
// These become all uppercase in locale.conf, but we keep them lowercase here to // These become all uppercase in locale.conf, but we keep them lowercase here to
// avoid confusion with locale.h. // avoid confusion with locale.h.
QString lang, lc_numeric, lc_time, lc_monetary, lc_paper, lc_name, lc_address, QString lc_numeric, lc_time, lc_monetary, lc_paper, lc_name, lc_address,
lc_telephone, lc_measurement, lc_identification; lc_telephone, lc_measurement, lc_identification;
// If the user has explicitly selected language (from the dialog) // If the user has explicitly selected language (from the dialog)
@ -49,7 +63,13 @@ public:
bool explicit_lang, explicit_lc; bool explicit_lang, explicit_lc;
private: private:
QString myLanguageLocaleBcp47; QString m_lang;
QString m_languageLocaleBcp47;
}; };
inline QDebug& operator <<( QDebug& s, const LocaleConfiguration& l )
{
return s << l.language() << '(' << l.toBcp47() << ") +" << l.lc_numeric;
}
#endif // LOCALECONFIGURATION_H #endif // LOCALECONFIGURATION_H

View File

@ -1,7 +1,7 @@
/* === This file is part of Calamares - <https://github.com/calamares> === /* === This file is part of Calamares - <https://github.com/calamares> ===
* *
* Copyright 2014-2016, Teo Mrnjavac <teo@kde.org> * Copyright 2014-2016, Teo Mrnjavac <teo@kde.org>
* Copyright 2017-2018, Adriaan de Groot <groot@kde.org> * Copyright 2017-2019, Adriaan de Groot <groot@kde.org>
* *
* Calamares is free software: you can redistribute it and/or modify * Calamares is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -164,16 +164,17 @@ LocalePage::LocalePage( QWidget* parent )
{ {
LCLocaleDialog* dlg = LCLocaleDialog* dlg =
new LCLocaleDialog( m_selectedLocaleConfiguration.isEmpty() ? new LCLocaleDialog( m_selectedLocaleConfiguration.isEmpty() ?
guessLocaleConfiguration().lang : guessLocaleConfiguration().language() :
m_selectedLocaleConfiguration.lang, m_selectedLocaleConfiguration.language(),
m_localeGenLines, m_localeGenLines,
this ); this );
dlg->exec(); dlg->exec();
if ( dlg->result() == QDialog::Accepted && if ( dlg->result() == QDialog::Accepted &&
!dlg->selectedLCLocale().isEmpty() ) !dlg->selectedLCLocale().isEmpty() )
{ {
m_selectedLocaleConfiguration.lang = dlg->selectedLCLocale(); m_selectedLocaleConfiguration.setLanguage( dlg->selectedLCLocale() );
m_selectedLocaleConfiguration.explicit_lang = true; m_selectedLocaleConfiguration.explicit_lang = true;
this->updateGlobalLocale();
this->updateLocaleLabels(); this->updateLocaleLabels();
} }
@ -317,7 +318,7 @@ LocalePage::init( const QString& initialRegion,
} }
else else
{ {
cDebug() << "Cannot open file" << localeGenPath cWarning() << "Cannot open file" << localeGenPath
<< ". Assuming the supported languages are already built into " << ". Assuming the supported languages are already built into "
"the locale archive."; "the locale archive.";
QProcess localeA; QProcess localeA;
@ -386,7 +387,7 @@ std::pair< QString, QString > LocalePage::prettyLocaleStatus( const LocaleConfig
{ {
using CalamaresUtils::LocaleLabel; using CalamaresUtils::LocaleLabel;
LocaleLabel lang( lc.lang, LocaleLabel::LabelFormat::AlwaysWithCountry ); LocaleLabel lang( lc.language(), LocaleLabel::LabelFormat::AlwaysWithCountry );
LocaleLabel num( lc.lc_numeric, LocaleLabel::LabelFormat::AlwaysWithCountry ); LocaleLabel num( lc.lc_numeric, LocaleLabel::LabelFormat::AlwaysWithCountry );
return std::make_pair< QString, QString >( return std::make_pair< QString, QString >(
@ -443,7 +444,8 @@ LocalePage::onActivate()
!m_selectedLocaleConfiguration.explicit_lang ) !m_selectedLocaleConfiguration.explicit_lang )
{ {
auto newLocale = guessLocaleConfiguration(); auto newLocale = guessLocaleConfiguration();
m_selectedLocaleConfiguration.lang = newLocale.lang; m_selectedLocaleConfiguration.setLanguage( newLocale.language() );
updateGlobalLocale();
updateLocaleLabels(); updateLocaleLabels();
} }
} }
@ -452,41 +454,39 @@ LocalePage::onActivate()
LocaleConfiguration LocaleConfiguration
LocalePage::guessLocaleConfiguration() const LocalePage::guessLocaleConfiguration() const
{ {
QLocale myLocale; // User-selected language return LocaleConfiguration::fromLanguageAndLocation( QLocale().name(),
// If we cannot say anything about available locales
if ( m_localeGenLines.isEmpty() )
{
cWarning() << "guessLocaleConfiguration can't guess from an empty list.";
return LocaleConfiguration::createDefault();
}
QString myLanguageLocale = myLocale.name();
if ( myLanguageLocale.isEmpty() )
return LocaleConfiguration::createDefault();
return LocaleConfiguration::fromLanguageAndLocation( myLanguageLocale,
m_localeGenLines, m_localeGenLines,
m_tzWidget->getCurrentLocation().country ); m_tzWidget->getCurrentLocation().country );
} }
void
LocalePage::updateGlobalLocale()
{
auto *gs = Calamares::JobQueue::instance()->globalStorage();
const QString bcp47 = m_selectedLocaleConfiguration.toBcp47();
gs->insert( "locale", bcp47 );
}
void void
LocalePage::updateGlobalStorage() LocalePage::updateGlobalStorage()
{ {
LocaleGlobal::Location location = m_tzWidget->getCurrentLocation(); auto *gs = Calamares::JobQueue::instance()->globalStorage();
Calamares::JobQueue::instance()->globalStorage()
->insert( "locationRegion", location.region );
Calamares::JobQueue::instance()->globalStorage()
->insert( "locationZone", location.zone );
const QString bcp47 = m_selectedLocaleConfiguration.toBcp47(); LocaleGlobal::Location location = m_tzWidget->getCurrentLocation();
Calamares::JobQueue::instance()->globalStorage()->insert( "locale", bcp47 ); bool locationChanged = ( location.region != gs->value( "locationRegion" ) ) ||
( location.zone != gs->value( "locationZone" ) );
gs->insert( "locationRegion", location.region );
gs->insert( "locationZone", location.zone );
updateGlobalLocale();
// If we're in chroot mode (normal install mode), then we immediately set the // If we're in chroot mode (normal install mode), then we immediately set the
// timezone on the live system. When debugging timezones, don't bother. // timezone on the live system. When debugging timezones, don't bother.
#ifndef DEBUG_TIMEZONES #ifndef DEBUG_TIMEZONES
if ( Calamares::Settings::instance()->doChroot() ) if ( locationChanged && Calamares::Settings::instance()->doChroot() )
{ {
QProcess::execute( "timedatectl", // depends on systemd QProcess::execute( "timedatectl", // depends on systemd
{ "set-timezone", { "set-timezone",
@ -498,7 +498,7 @@ LocalePage::updateGlobalStorage()
auto newLocale = guessLocaleConfiguration(); auto newLocale = guessLocaleConfiguration();
if ( !m_selectedLocaleConfiguration.isEmpty() && if ( !m_selectedLocaleConfiguration.isEmpty() &&
m_selectedLocaleConfiguration.explicit_lang ) m_selectedLocaleConfiguration.explicit_lang )
newLocale.lang = m_selectedLocaleConfiguration.lang; newLocale.setLanguage( m_selectedLocaleConfiguration.language() );
if ( !m_selectedLocaleConfiguration.isEmpty() && if ( !m_selectedLocaleConfiguration.isEmpty() &&
m_selectedLocaleConfiguration.explicit_lc ) m_selectedLocaleConfiguration.explicit_lc )
{ {

View File

@ -1,6 +1,7 @@
/* === This file is part of Calamares - <https://github.com/calamares> === /* === This file is part of Calamares - <https://github.com/calamares> ===
* *
* Copyright 2014, Teo Mrnjavac <teo@kde.org> * Copyright 2014, Teo Mrnjavac <teo@kde.org>
* Copyright 2019, Adriaan de Groot <groot@kde.org>
* *
* Calamares is free software: you can redistribute it and/or modify * Calamares is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -56,6 +57,12 @@ private:
// the settings for language and numbers. // the settings for language and numbers.
std::pair< QString, QString > prettyLocaleStatus( const LocaleConfiguration& ) const; std::pair< QString, QString > prettyLocaleStatus( const LocaleConfiguration& ) const;
/** @brief Update the GS *locale* key with the selected system language.
*
* This uses whatever is set in m_selectedLocaleConfiguration as the language,
* and writes it to GS *locale* key (as a string, in BCP47 format).
*/
void updateGlobalLocale();
void updateGlobalStorage(); void updateGlobalStorage();
void updateLocaleLabels(); void updateLocaleLabels();

View File

@ -0,0 +1,80 @@
/* === This file is part of Calamares - <http://github.com/calamares> ===
*
* Copyright 2019, Adriaan de Groot <groot@kde.org>
*
* Calamares is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Calamares is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
*/
#include "Tests.h"
#include "LocaleConfiguration.h"
#include <QtTest/QtTest>
QTEST_GUILESS_MAIN( LocaleTests )
LocaleTests::LocaleTests()
{
}
LocaleTests::~LocaleTests()
{
}
void LocaleTests::initTestCase()
{
}
void LocaleTests::testEmptyLocaleConfiguration()
{
LocaleConfiguration lc;
QVERIFY( lc.isEmpty() );
QCOMPARE( lc.toBcp47(), QString() );
}
void LocaleTests::testDefaultLocaleConfiguration()
{
LocaleConfiguration lc( "en_US.UTF-8" );
QVERIFY( !lc.isEmpty() );
QCOMPARE( lc.language(), "en_US.UTF-8" );
QCOMPARE( lc.toBcp47(), "en" );
LocaleConfiguration lc2( "de_DE.UTF-8" );
QVERIFY( !lc2.isEmpty() );
QCOMPARE( lc2.language(), "de_DE.UTF-8" );
QCOMPARE( lc2.toBcp47(), "de" );
}
void LocaleTests::testSplitLocaleConfiguration()
{
LocaleConfiguration lc( "en_US.UTF-8", "de_DE.UTF-8" );
QVERIFY( !lc.isEmpty() );
QCOMPARE( lc.language(), "en_US.UTF-8" );
QCOMPARE( lc.toBcp47(), "en" );
QCOMPARE( lc.lc_numeric, QStringLiteral( "de_DE.UTF-8" ) );
LocaleConfiguration lc2( "de_DE.UTF-8", "da_DK.UTF-8" );
QVERIFY( !lc2.isEmpty() );
QCOMPARE( lc2.language(), "de_DE.UTF-8" );
QCOMPARE( lc2.toBcp47(), "de" );
QCOMPARE( lc2.lc_numeric, "da_DK.UTF-8" );
LocaleConfiguration lc3( "da_DK.UTF-8", "de_DE.UTF-8" );
QVERIFY( !lc3.isEmpty() );
QCOMPARE( lc3.toBcp47(), "da" );
QCOMPARE( lc3.lc_numeric, "de_DE.UTF-8" );
}

View File

@ -0,0 +1,40 @@
/* === This file is part of Calamares - <http://github.com/calamares> ===
*
* Copyright 2019, Adriaan de Groot <groot@kde.org>
*
* Calamares is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Calamares is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef TESTS_H
#define TESTS_H
#include <QObject>
class LocaleTests : public QObject
{
Q_OBJECT
public:
LocaleTests();
~LocaleTests() override;
private Q_SLOTS:
void initTestCase();
// Check the sample config file is processed correctly
void testEmptyLocaleConfiguration();
void testDefaultLocaleConfiguration();
void testSplitLocaleConfiguration();
};
#endif

View File

@ -1,6 +1,7 @@
/* === This file is part of Calamares - <https://github.com/calamares> === /* === This file is part of Calamares - <https://github.com/calamares> ===
* *
* Copyright 2014-2016, Teo Mrnjavac <teo@kde.org> * Copyright 2014-2016, Teo Mrnjavac <teo@kde.org>
* Copyright 2019, Adriaan de Groot <groot@kde.org>
* *
* Originally from the Manjaro Installation Framework * Originally from the Manjaro Installation Framework
* by Roland Singer <roland@manjaro.org> * by Roland Singer <roland@manjaro.org>
@ -38,11 +39,13 @@
class LocaleGlobal class LocaleGlobal
{ {
public: public:
struct Locale { struct Locale
{
QString description, locale; QString description, locale;
}; };
struct Location { struct Location
{
QString region, zone, country; QString region, zone, country;
double latitude, longitude; double latitude, longitude;
static QString pretty( const QString& s ); static QString pretty( const QString& s );
@ -62,4 +65,9 @@ private:
static double getRightGeoLocation( QString str ); static double getRightGeoLocation( QString str );
}; };
inline QDebug& operator <<( QDebug& s, const LocaleGlobal::Location& l )
{
return s << l.region << '/' << l.zone << '(' << l.country << ") @N" << l.latitude << 'E' << l.longitude;
}
#endif // LOCALEGLOBAL_H #endif // LOCALEGLOBAL_H