diff --git a/CHANGES b/CHANGES
index e6da1eb55..58602f256 100644
--- a/CHANGES
+++ b/CHANGES
@@ -3,6 +3,19 @@ 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
website will have to do for older versions.
+# 3.2.24 (unreleased) #
+
+This release contains contributions from (alphabetically by first name):
+ - Gaël PORTAY
+
+## Core ##
+ - There is now a bash-completions script for Calamares; turn on
+ the (CMake-time) option INSTALL_COMPLETION to get it. (Thanks Gaël)
+
+## Modules ##
+ - No module changes yet
+
+
# 3.2.23 (2020-04-17) #
This release contains contributions from (alphabetically by first name):
diff --git a/CMakeLists.txt b/CMakeLists.txt
index b122301eb..6d4b3c4e9 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -49,6 +49,7 @@ set( CALAMARES_VERSION_RC 0 ) # Set to 0 during release cycle, 1 during develop
#
option( INSTALL_CONFIG "Install configuration files" OFF )
option( INSTALL_POLKIT "Install Polkit configuration" ON )
+option( INSTALL_COMPLETION "Install shell completions" OFF )
option( BUILD_TESTING "Build the testing tree." ON )
option( WITH_PYTHON "Enable Python modules API (requires Boost.Python)." ON )
option( WITH_PYTHONQT "Enable next generation Python modules API (experimental, requires PythonQt)." OFF )
@@ -389,6 +390,13 @@ list( SORT CALAMARES_TRANSLATION_LANGUAGES )
add_subdirectory( lang ) # i18n tools
+if ( INSTALL_COMPLETION )
+ if( NOT CMAKE_INSTALL_BASHCOMPLETIONDIR )
+ set( CMAKE_INSTALL_BASHCOMPLETIONDIR "${CMAKE_INSTALL_DATADIR}/bash-completion/completions" )
+ endif()
+
+ install( FILES ${CMAKE_SOURCE_DIR}/data/completion/bash/calamares DESTINATION "${CMAKE_INSTALL_BASHCOMPLETIONDIR}" )
+endif()
### Example Distro
#
diff --git a/data/completion/bash/calamares b/data/completion/bash/calamares
new file mode 100644
index 000000000..47c2bb268
--- /dev/null
+++ b/data/completion/bash/calamares
@@ -0,0 +1,36 @@
+# === This file is part of Calamares - ===
+#
+# Copyright 2020, Gaël PORTAY
+#
+# 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 .
+
+_calamares()
+{
+ local cur prev words cword
+ _init_completion || return
+
+ case "$prev" in
+ -D)
+ COMPREPLY=( $( compgen -W "$( seq 0 1 8 )" -- "$cur" ) )
+ return
+ ;;
+ -c|--config)
+ _filedir
+ return
+ ;;
+ esac
+
+ COMPREPLY=( $( compgen -W "-h --help -v --version -d --debug -D -c --config -X -xdg-config -T --debug-translation" -- "$cur" ) )
+} &&
+complete -F _calamares calamares
diff --git a/lang/calamares_eo.ts b/lang/calamares_eo.ts
index e7d9636d0..5173f5527 100644
--- a/lang/calamares_eo.ts
+++ b/lang/calamares_eo.ts
@@ -6,17 +6,17 @@
-
+ La <strong>praŝarga ĉirkaŭaĵo</strong> de ĉi tiu sistemo.<br><br>Pli maljuna x86 sistemoj subtenas nur <strong>BIOS</strong>.<br>Pli sistemoj kutime uzas <strong>EFI</strong>, sed povos ankaŭ aspektas kiel BIOS, sed ŝaltita en kongrua reĝimo.
-
+ Tio ĉi sistemo estis ŝaltita per <strong>EFI</strong> praŝarga ĉirkaŭaĵo.<br><br>Agordi praŝargo el EFI, la instalilo devas disponigi praŝargilon, kiel: <strong>GRUB</strong> aŭ <strong>systemd-boot</strong> sur <strong>EFI Sistema Subdisko</strong>. Tio estas aŭtomata, krom se vi selektas manan dispartigon, tiukaze vi devas selekti ĝin, aŭ kreias unu mane.
-
+ Tio ĉi sistemo estis ŝaltita per <strong>BIOS</strong> praŝarga ĉirkaŭaĵo.<br><br>Agordi praŝargo el BIOS, la instalilo devas disponigi praŝargilon, kiel: <strong>GRUB</strong>, ĉe la komenco de subdisko aŭ sur la<strong>Ĉefa Ŝargodosiero</strong> apud la komencao de la subdiska tablo (preferred). Tio estas aŭtomata, krom se vi selektas manan dispartigon, tiukaze vi devas manipuli ĝin mane.
@@ -24,22 +24,22 @@
-
+ Ĉefa Ŝargodosiero de %1
-
+ Praŝarga Subdisko
-
+ Sistema Subdisko
-
+ Ne instalu praŝargilon
@@ -52,7 +52,7 @@
-
+ Senskriba Paĝo
@@ -65,12 +65,12 @@
-
+ GlobalStorage
-
+ JobQueue
@@ -101,17 +101,17 @@
-
+ Reŝargu Stilfolio
-
+ KromprogrametArbo
-
+ Sencimiga Informaĵo
@@ -124,7 +124,7 @@
- Instali
+ Instalu
@@ -513,17 +513,17 @@ La instalilo forlasos kaj ĉiuj ŝanĝoj perdos.
-
+ Nune:
-
+ Poste:
-
+ <strong>Manan aranĝaĵon de subdisko</strong><br/>Vi povas kreii aŭ regrandigi subdiskon ajne.
@@ -543,7 +543,7 @@ La instalilo forlasos kaj ĉiuj ŝanĝoj perdos.
-
+ Allokigo de la Praŝargilo:
@@ -801,7 +801,7 @@ La instalilo forlasos kaj ĉiuj ŝanĝoj perdos.
- Kreiu Subdisko
+ Kreiu Subdiskon
@@ -1153,12 +1153,12 @@ La instalilo forlasos kaj ĉiuj ŝanĝoj perdos.
-
+ Strukturu
-
+ Averto: Strukturi la subdiskon, forviŝos ĉiujn eksistantajn datumojn.
@@ -1173,7 +1173,7 @@ La instalilo forlasos kaj ĉiuj ŝanĝoj perdos.
-
+ MiB
@@ -1272,32 +1272,32 @@ La instalilo forlasos kaj ĉiuj ŝanĝoj perdos.
-
+ <h1>Plenumita!</h1><br/>%1 estis agordita sur vian komputilon.<br/>Vi povas nun ekuzi vian novan sistemon.
-
+ <html><head/><body><p>Se ĉi tio elektobutono estas elektita, via sistemo restartos senprokraste, kiam vi klikas <span style="font-style:italic;">Finita</span> aŭ vi malfermas la agordilon.</p></body></html>
-
+ <h1>Plenumita!</h1><br/>%1 estis instalita sur vian komputilon.<br/>Vi povas nun restartigas en vian novan sistemon, aŭ vi povas pluiri uzi la %2 aŭtonoman sistemon.
-
+ <html><head/><body><p>Se ĉi tio elektobutono estas elektita, via sistemo restartos senprokraste, kiam vi klikas <span style="font-style:italic;">Finita</span> aŭ vi malfermas la instalilon.</p></body></html>
-
+ <h1>Agorado Malsukcesis</h1><br/>%1 ne estis agordita sur vian komputilon.<br/>La erara mesaĝo estis: %2.
-
+ <h1>Instalaĵo Malsukcesis</h1><br/>%1 ne estis instalita sur vian komputilon.<br/>La erara mesaĝo estis: %2.
@@ -1305,27 +1305,27 @@ La instalilo forlasos kaj ĉiuj ŝanĝoj perdos.
-
+ Pretigu
-
+ Agordaĵo Plenumita
-
+ Instalaĵo Plenumita
-
+ La agordaĵo de %1 estas plenumita.
-
+ La instalaĵo de %1 estas plenumita.
@@ -1333,22 +1333,22 @@ La instalilo forlasos kaj ĉiuj ŝanĝoj perdos.
-
+ Strukturu subdiskon %1 (dosiersistemo: %2, grandeco: %3 MiB) ja %4.
-
+ Strukturu <strong>%3MiB</strong> subdiskon <strong>%1</strong> kiel dosiersistemo <strong>%2</strong>.
-
+ Strukturanta subdiskon %1 kiel dosiersistemo %2.
-
+ La instalilo malsukcesis strukturi ls subdiskon %1 sur disko '%2'.
@@ -2539,12 +2539,12 @@ La instalilo forlasos kaj ĉiuj ŝanĝoj perdos.
-
+ Nune:
-
+ Poste:
@@ -2746,7 +2746,7 @@ Output:
-
+ nestrukturita
diff --git a/lang/calamares_ja.ts b/lang/calamares_ja.ts
index 870d85e79..8c14c1456 100644
--- a/lang/calamares_ja.ts
+++ b/lang/calamares_ja.ts
@@ -3665,7 +3665,7 @@ Output:
-
+ <h1>%1</h1><br/><strong>%2<br/>for %3</strong><br/><br/>Copyright 2014-2017 Teo Mrnjavac <teo@kde.org><br/>Copyright 2017-2020 Adriaan de Groot <groot@kde.org><br/>Thanks to <a href="https://calamares.io/team/">the Calamares team</a> and the <a href="https://www.transifex.com/calamares/calamares/">Calamares translators team</a>.<br/><br/><a href="https://calamares.io/">Calamares</a> development is sponsored by <br/><a href="http://www.blue-systems.com/">Blue Systems</a> - Liberating Software.
diff --git a/lang/calamares_sv.ts b/lang/calamares_sv.ts
index d0a8d06a5..f1acd343c 100644
--- a/lang/calamares_sv.ts
+++ b/lang/calamares_sv.ts
@@ -623,12 +623,12 @@ Alla ändringar kommer att gå förlorade.
-
+ Swap (utan viloläge)
-
+ Swap (med viloläge)
@@ -1789,12 +1789,12 @@ Alla ändringar kommer att gå förlorade.
-
+ Webbläsare
-
+ Webbläsare
@@ -1839,7 +1839,7 @@ Alla ändringar kommer att gå förlorade.
-
+ Kontorsprogram
@@ -3723,7 +3723,7 @@ Utdata:
-
+ Ladda om
@@ -3768,7 +3768,7 @@ Utdata:
-
+ <h3>Välkommen till %1 <quote>%2</quote> installeraren</h3>
diff --git a/lang/calamares_tr_TR.ts b/lang/calamares_tr_TR.ts
index eaa871552..42738f7a8 100644
--- a/lang/calamares_tr_TR.ts
+++ b/lang/calamares_tr_TR.ts
@@ -3673,7 +3673,7 @@ Kuruluma devam edebilirsiniz fakat bazı özellikler devre dışı kalabilir.
-
+ <h1>%1</h1><br/><strong>%2<br/>for %3</strong><br/><br/>Telif Hakkı 2014-2017 Teo Mrnjavac <teo@kde.org><br/>Telif Hakkı 2017-2020 Adriaan de Groot <groot@kde.org><br/>Teşekkrürler <a href="https://calamares.io/team/">Calamares takımı</a> ve <a href="https://www.transifex.com/calamares/calamares/">Calamares çeviri ekibi</a>.<br/><br/><a href="https://calamares.io/">Calamares</a> gelişim sponsoru <br/><a href="http://www.blue-systems.com/">Blue Systems</a> - Özgür Yazılım
diff --git a/src/branding/default/banner.png b/src/branding/default/banner.png
new file mode 100644
index 000000000..d1baeee85
Binary files /dev/null and b/src/branding/default/banner.png differ
diff --git a/src/branding/default/branding.desc b/src/branding/default/branding.desc
index b6694d1f4..53884e311 100644
--- a/src/branding/default/branding.desc
+++ b/src/branding/default/branding.desc
@@ -106,6 +106,11 @@ strings:
# These images are loaded from the branding module directory.
#
+# productBanner is an optional image, which if present, will be shown
+# on the welcome page of the application, above the welcome text.
+# It is intended to have a width much greater than height.
+# It is displayed at 64px height (also on HiDPI).
+# Recommended size is 64px tall, and up to 460px wide.
# productIcon is used as the window icon, and will (usually) be used
# by the window manager to represent the application. This image
# should be square, and may be displayed by the window manager
@@ -121,8 +126,9 @@ strings:
#
# These filenames can also use substitutions from os-release (see above).
images:
- productLogo: "squid.png"
+ # productBanner: "banner.png"
productIcon: "squid.png"
+ productLogo: "squid.png"
productWelcome: "languages.png"
# The slideshow is displayed during execution steps (e.g. when the
diff --git a/src/libcalamares/CMakeLists.txt b/src/libcalamares/CMakeLists.txt
index 91dce96cd..dd6f01fb1 100644
--- a/src/libcalamares/CMakeLists.txt
+++ b/src/libcalamares/CMakeLists.txt
@@ -226,6 +226,16 @@ calamares_add_test(
partition/Tests.cpp
)
+if( KPMcore_FOUND )
+ calamares_add_test(
+ libcalamarespartitionkpmtest
+ SOURCES
+ partition/KPMTests.cpp
+ LIBRARIES
+ ${OPTIONAL_PRIVATE_LIBRARIES}
+ )
+endif()
+
calamares_add_test(
libcalamareslocaletest
SOURCES
@@ -244,8 +254,8 @@ calamares_add_test(
modulesystem/Tests.cpp
)
-if( BUILD_TESTING )
- add_executable( test_geoip geoip/test_geoip.cpp ${geoip_src} )
- target_link_libraries( test_geoip calamares Qt5::Network yamlcpp )
- calamares_automoc( test_geoip )
-endif()
+# This is not an actual test, it's a test / demo application
+# for experimenting with GeoIP.
+add_executable( test_geoip geoip/test_geoip.cpp ${geoip_src} )
+target_link_libraries( test_geoip calamares Qt5::Network yamlcpp )
+calamares_automoc( test_geoip )
diff --git a/src/libcalamares/locale/Tests.cpp b/src/libcalamares/locale/Tests.cpp
index bf71fb0a2..6cbe980be 100644
--- a/src/libcalamares/locale/Tests.cpp
+++ b/src/libcalamares/locale/Tests.cpp
@@ -37,6 +37,7 @@ void
LocaleTests::initTestCase()
{
// Otherwise plain get() is dubious in the TranslatableConfiguration tests
+ QLocale::setDefault( QLocale( QStringLiteral( "en_US" ) ) );
QVERIFY( ( QLocale().name() == "C" ) || ( QLocale().name() == "en_US" ) );
}
diff --git a/src/libcalamares/partition/KPMTests.cpp b/src/libcalamares/partition/KPMTests.cpp
new file mode 100644
index 000000000..7468d3938
--- /dev/null
+++ b/src/libcalamares/partition/KPMTests.cpp
@@ -0,0 +1,82 @@
+/* === This file is part of Calamares - ===
+ *
+ * Copyright 2019, Adriaan de Groot
+ *
+ * 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 .
+ */
+
+#include "utils/Logger.h"
+
+#include
+
+#include
+
+class KPMTests : public QObject
+{
+ Q_OBJECT
+public:
+ KPMTests();
+ ~KPMTests() override;
+private Q_SLOTS:
+ void initTestCase();
+
+ void testFlagNames();
+};
+
+KPMTests::KPMTests() {}
+
+KPMTests::~KPMTests() {}
+
+void
+KPMTests::initTestCase()
+{
+ Logger::setupLogLevel( Logger::LOGDEBUG );
+}
+
+void
+KPMTests::testFlagNames()
+{
+ int f = 1;
+ QStringList names;
+ QString s;
+ while ( !( s = PartitionTable::flagName( static_cast< PartitionTable::Flag >( f ) ) ).isEmpty() )
+ {
+ cDebug() << f << s;
+ names.append( s );
+
+ f <<= 1;
+ }
+
+ QCOMPARE( PartitionTable::flagName( static_cast< PartitionTable::Flag >( 1 ) ), QStringLiteral( "boot" ) );
+
+#ifdef WITH_KPMCORE4API
+ // KPMCore 4 unifies the flags and handles them internally
+ QCOMPARE( PartitionTable::flagName( PartitionTable::Flag::Boot ), QStringLiteral( "boot" ) );
+ QVERIFY( names.contains( QStringLiteral( "boot" ) ) );
+ QVERIFY( !names.contains( QStringLiteral( "esp" ) ) );
+#else
+ // KPMCore 3 has separate flags
+ QCOMPARE( PartitionTable::flagName( PartitionTable::FlagBoot ), QStringLiteral( "boot" ) );
+ QCOMPARE( PartitionTable::flagName( PartitionTable::FlagEsp ), QStringLiteral( "esp" ) );
+ QVERIFY( names.contains( QStringLiteral( "boot" ) ) );
+ QVERIFY( names.contains( QStringLiteral( "esp" ) ) );
+#endif
+}
+
+
+QTEST_GUILESS_MAIN( KPMTests )
+
+#include "utils/moc-warnings.h"
+
+#include "KPMTests.moc"
diff --git a/src/libcalamares/utils/CalamaresUtilsSystem.cpp b/src/libcalamares/utils/CalamaresUtilsSystem.cpp
index 651ac2c1e..327bece92 100644
--- a/src/libcalamares/utils/CalamaresUtilsSystem.cpp
+++ b/src/libcalamares/utils/CalamaresUtilsSystem.cpp
@@ -195,7 +195,7 @@ System::runCommand( System::RunLocation location,
? ( static_cast< int >( std::chrono::milliseconds( timeoutSec ).count() ) )
: -1 ) )
{
- ( cWarning() << "Process" << args.first() << "timed out after" << timeoutSec.count() << "s. Output so far:\n" ).noquote().nospace() << process.readAllStandardOutput();
+ cWarning() << "Process" << args.first() << "timed out after" << timeoutSec.count() << "s. Output so far:\n" << Logger::NoQuote{} << process.readAllStandardOutput();
return ProcessResult::Code::TimedOut;
}
@@ -203,7 +203,7 @@ System::runCommand( System::RunLocation location,
if ( process.exitStatus() == QProcess::CrashExit )
{
- ( cWarning() << "Process" << args.first() << "crashed. Output so far:\n" ).noquote().nospace() << output;
+ cWarning() << "Process" << args.first() << "crashed. Output so far:\n" << Logger::NoQuote{} << output;
return ProcessResult::Code::Crashed;
}
@@ -212,7 +212,7 @@ System::runCommand( System::RunLocation location,
bool showDebug = ( !Calamares::Settings::instance() ) || ( Calamares::Settings::instance()->debugMode() );
if ( ( r != 0 ) || showDebug )
{
- ( cDebug() << "Target cmd:" << RedactedList( args ) << "output:\n" ).noquote().nospace() << output;
+ cDebug() << "Target cmd:" << RedactedList( args ) << "output:\n" << Logger::NoQuote{} << output;
}
return ProcessResult( r, output );
}
diff --git a/src/libcalamares/utils/Logger.h b/src/libcalamares/utils/Logger.h
index fe4b98fd4..24198e256 100644
--- a/src/libcalamares/utils/Logger.h
+++ b/src/libcalamares/utils/Logger.h
@@ -33,6 +33,9 @@ struct FuncSuppressor
const char* m_s;
};
+struct NoQuote {};
+struct Quote {};
+
DLLEXPORT extern const FuncSuppressor Continuation;
DLLEXPORT extern const FuncSuppressor SubEntry;
@@ -74,6 +77,18 @@ operator<<( QDebug& s, const FuncSuppressor& f )
return s << f.m_s;
}
+inline QDebug&
+operator<<( QDebug& s, const NoQuote& )
+{
+ return s.noquote().nospace();
+}
+
+inline QDebug&
+operator<<( QDebug& s, const Quote& )
+{
+ return s.quote().space();
+}
+
/**
* @brief The full path of the log file.
*/
diff --git a/src/libcalamaresui/Branding.cpp b/src/libcalamaresui/Branding.cpp
index ff7e43fb8..67054a902 100644
--- a/src/libcalamaresui/Branding.cpp
+++ b/src/libcalamaresui/Branding.cpp
@@ -73,10 +73,11 @@ const QStringList Branding::s_stringEntryStrings =
const QStringList Branding::s_imageEntryStrings =
{
- "productLogo",
+ "productBanner",
"productIcon",
- "productWelcome",
- "productWallpaper"
+ "productLogo",
+ "productWallpaper",
+ "productWelcome"
};
const QStringList Branding::s_styleEntryStrings =
@@ -537,7 +538,7 @@ Branding::initSimpleSettings( const YAML::Node& doc )
[[noreturn]] void
Branding::bail( const QString& message )
{
- cError() << "FATAL in" << m_descriptorPath << "\n" + message;
+ cError() << "FATAL in" << m_descriptorPath << Logger::Continuation << Logger::NoQuote{} << message;
::exit( EXIT_FAILURE );
}
diff --git a/src/libcalamaresui/Branding.h b/src/libcalamaresui/Branding.h
index 023f1a511..847f28d89 100644
--- a/src/libcalamaresui/Branding.h
+++ b/src/libcalamaresui/Branding.h
@@ -67,10 +67,11 @@ public:
enum ImageEntry : short
{
- ProductLogo,
+ ProductBanner,
ProductIcon,
- ProductWelcome,
- ProductWallpaper
+ ProductLogo,
+ ProductWallpaper,
+ ProductWelcome
};
Q_ENUM( ImageEntry )
diff --git a/src/modules/locale/Tests.cpp b/src/modules/locale/Tests.cpp
index b07482ce7..af37a664b 100644
--- a/src/modules/locale/Tests.cpp
+++ b/src/modules/locale/Tests.cpp
@@ -25,12 +25,14 @@
#include
+#include
+
QTEST_MAIN( LocaleTests )
-LocaleTests::LocaleTests() { }
+LocaleTests::LocaleTests() {}
-LocaleTests::~LocaleTests() { }
+LocaleTests::~LocaleTests() {}
void
LocaleTests::initTestCase()
@@ -147,6 +149,122 @@ LocaleTests::testTZImages()
}
}
- QEXPECT_FAIL("", "TZ Images not yet all fixed", Continue);
+ QEXPECT_FAIL( "", "TZ Images not yet all fixed", Continue );
QCOMPARE( overlapcount, 0 );
}
+
+bool
+operator<( const QPoint& l, const QPoint& r )
+{
+ if ( l.x() < r.x() )
+ {
+ return true;
+ }
+ if ( l.x() > r.x() )
+ {
+ return false;
+ }
+ return l.y() < r.y();
+}
+
+void
+listAll( const QPoint& p, const CalamaresUtils::Locale::CStringPairList& zones )
+{
+ using namespace CalamaresUtils::Locale;
+ for ( const auto* pz : zones )
+ {
+ const TZZone* zone = dynamic_cast< const TZZone* >( pz );
+ if ( p == TimeZoneImageList::getLocationPosition( zone->longitude(), zone->latitude() ) )
+ {
+ cError() << Logger::SubEntry << zone->zone();
+ }
+ }
+}
+
+void
+LocaleTests::testTZLocations()
+{
+ using namespace CalamaresUtils::Locale;
+ const CStringPairList& regions = TZRegion::fromZoneTab();
+
+ int overlapcount = 0;
+ for ( const auto* pr : regions )
+ {
+ const TZRegion* region = dynamic_cast< const TZRegion* >( pr );
+ QVERIFY( region );
+
+ Logger::setupLogLevel( Logger::LOGDEBUG );
+ cDebug() << "Region" << region->region() << "zones #" << region->zones().count();
+ Logger::setupLogLevel( Logger::LOGERROR );
+
+ std::set< QPoint > occupied;
+
+ const auto zones = region->zones();
+ QVERIFY( zones.count() > 0 );
+ for ( const auto* pz : zones )
+ {
+ const TZZone* zone = dynamic_cast< const TZZone* >( pz );
+ QVERIFY( zone );
+
+ auto pos = TimeZoneImageList::getLocationPosition( zone->longitude(), zone->latitude() );
+ if ( occupied.find( pos ) != occupied.end() )
+ {
+ cError() << "Zone" << zone->zone() << "occupies same spot as ..";
+ listAll( pos, zones );
+ overlapcount++;
+ }
+ occupied.insert( pos );
+ }
+ }
+
+ QEXPECT_FAIL( "", "TZ Images contain pixel-overlaps", Continue );
+ QCOMPARE( overlapcount, 0 );
+}
+
+const CalamaresUtils::Locale::TZZone*
+findZone( const QString& name )
+{
+ using namespace CalamaresUtils::Locale;
+ const CStringPairList& regions = TZRegion::fromZoneTab();
+
+ for ( const auto* pr : regions )
+ {
+ const TZRegion* region = dynamic_cast< const TZRegion* >( pr );
+ if ( !region )
+ {
+ continue;
+ }
+ const auto zones = region->zones();
+ for ( const auto* pz : zones )
+ {
+ const TZZone* zone = dynamic_cast< const TZZone* >( pz );
+ if ( !zone )
+ {
+ continue;
+ }
+
+ if ( zone->zone() == name )
+ {
+ return zone;
+ }
+ }
+ }
+ return nullptr;
+}
+
+void
+LocaleTests::testSpecificLocations()
+{
+ const auto* gibraltar = findZone( "Gibraltar" );
+ const auto* ceuta = findZone( "Ceuta" );
+ QVERIFY( gibraltar );
+ QVERIFY( ceuta );
+
+ auto gpos = TimeZoneImageList::getLocationPosition( gibraltar->longitude(), gibraltar->latitude() );
+ auto cpos = TimeZoneImageList::getLocationPosition( ceuta->longitude(), ceuta->latitude() );
+ QEXPECT_FAIL( "", "Gibraltar and Ceuta are really close", Continue );
+ QVERIFY( gpos != cpos );
+ QVERIFY( gibraltar->latitude() > ceuta->latitude() );
+ QEXPECT_FAIL( "", "Gibraltar and Ceuta are really close", Continue );
+ QVERIFY( gpos.y() < cpos.y() ); // Gibraltar is north of Ceuta
+}
diff --git a/src/modules/locale/Tests.h b/src/modules/locale/Tests.h
index e0ca7ad0b..e01b1a25c 100644
--- a/src/modules/locale/Tests.h
+++ b/src/modules/locale/Tests.h
@@ -37,7 +37,9 @@ private Q_SLOTS:
void testSplitLocaleConfiguration();
// Check the TZ images for consistency
- void testTZImages();
+ void testTZImages(); // No overlaps in images
+ void testTZLocations(); // No overlaps in locations
+ void testSpecificLocations();
};
#endif
diff --git a/src/modules/partition/core/PartitionActions.cpp b/src/modules/partition/core/PartitionActions.cpp
index 5e785c9d1..d0de2c0d4 100644
--- a/src/modules/partition/core/PartitionActions.cpp
+++ b/src/modules/partition/core/PartitionActions.cpp
@@ -151,6 +151,10 @@ doAutopartition( PartitionCoreModule* core, Device* dev, Choices::AutoPartitionO
KPM_PARTITION_FLAG( None ) );
PartitionInfo::setFormat( efiPartition, true );
PartitionInfo::setMountPoint( efiPartition, o.efiPartitionMountPoint );
+ if ( gs->contains( "efiSystemPartitionName" ) )
+ {
+ efiPartition->setLabel( gs->value( "efiSystemPartitionName" ).toString() );
+ }
core->createPartition( dev, efiPartition, KPM_PARTITION_FLAG_ESP );
firstFreeSector = lastSector + 1;
}
diff --git a/src/modules/partition/gui/PartitionViewStep.cpp b/src/modules/partition/gui/PartitionViewStep.cpp
index ed35fafa4..c9bdd03f9 100644
--- a/src/modules/partition/gui/PartitionViewStep.cpp
+++ b/src/modules/partition/gui/PartitionViewStep.cpp
@@ -417,6 +417,12 @@ PartitionViewStep::onLeave()
{
QString espMountPoint
= Calamares::JobQueue::instance()->globalStorage()->value( "efiSystemPartition" ).toString();
+#ifdef WITH_KPMCORE4API
+ auto espFlag = PartitionTable::Flag::Boot;
+#else
+ auto espFlag = PartitionTable::FlagEsp;
+#endif
+ QString espFlagName = PartitionTable::flagName( espFlag );
Partition* esp = m_core->findPartitionByMountPoint( espMountPoint );
QString message;
@@ -428,12 +434,12 @@ PartitionViewStep::onLeave()
"
"
"To configure an EFI system partition, go back and "
"select or create a FAT32 filesystem with the "
- "esp flag enabled and mount point "
+ "%3 flag enabled and mount point "
"%2.
"
"You can continue without setting up an EFI system "
"partition but your system may fail to start." )
.arg( *Calamares::Branding::ShortProductName )
- .arg( espMountPoint );
+ .arg( espMountPoint, espFlagName );
}
else if ( esp && !PartUtils::isEfiBootable( esp ) )
{
@@ -441,14 +447,14 @@ PartitionViewStep::onLeave()
description = tr( "An EFI system partition is necessary to start %1."
"
"
"A partition was configured with mount point "
- "%2 but its esp "
+ "%2 but its %3 "
"flag is not set. "
"To set the flag, go back and edit the partition."
"
"
"You can continue without setting the flag but your "
"system may fail to start." )
.arg( *Calamares::Branding::ShortProductName )
- .arg( espMountPoint );
+ .arg( espMountPoint, espFlagName );
}
if ( !message.isEmpty() )
@@ -538,6 +544,12 @@ PartitionViewStep::setConfigurationMap( const QVariantMap& configurationMap )
gs->insert( "efiSystemPartitionSize", CalamaresUtils::getString( configurationMap, "efiSystemPartitionSize" ) );
}
+ // Read and parse key efiSystemPartitionName
+ if ( configurationMap.contains( "efiSystemPartitionName" ) )
+ {
+ gs->insert( "efiSystemPartitionName", CalamaresUtils::getString( configurationMap, "efiSystemPartitionName" ) );
+ }
+
// SWAP SETTINGS
//
// This is a bit convoluted because there's legacy settings to handle as well
diff --git a/src/modules/partition/jobs/FillGlobalStorageJob.cpp b/src/modules/partition/jobs/FillGlobalStorageJob.cpp
index ac65b5ff6..a302a3f31 100644
--- a/src/modules/partition/jobs/FillGlobalStorageJob.cpp
+++ b/src/modules/partition/jobs/FillGlobalStorageJob.cpp
@@ -107,7 +107,7 @@ mapForPartition( Partition* partition, const QString& uuid )
Logger::CDebug deb;
using TR = Logger::DebugRow< const char* const, const QString& >;
deb << Logger::SubEntry << "mapping for" << partition->partitionPath() << partition->deviceNode()
- << TR( "mtpoint:", PartitionInfo::mountPoint( partition ) ) << TR( "fs:", map[ "fs" ].toString() )
+ << TR( "mountPoint:", PartitionInfo::mountPoint( partition ) ) << TR( "fs:", map[ "fs" ].toString() )
<< TR( "fsName", map[ "fsName" ].toString() ) << TR( "uuid", uuid )
<< TR( "claimed", map[ "claimed" ].toString() );
diff --git a/src/modules/partition/partition.conf b/src/modules/partition/partition.conf
index 241e4ea05..f6cc34ee4 100644
--- a/src/modules/partition/partition.conf
+++ b/src/modules/partition/partition.conf
@@ -7,6 +7,10 @@ efiSystemPartition: "/boot/efi"
# If nothing is specified, the default size of 300MiB will be used.
# efiSystemPartitionSize: 300M
+# This optional setting specifies the name of the EFI system partition.
+# If nothing is specified, the partition name is left unset.
+# efiSystemPartitionName: EFI
+
# In autogenerated partitioning, allow the user to select a swap size?
# If there is exactly one choice, no UI is presented, and the user
# cannot make a choice -- this setting is used. If there is more than
diff --git a/src/modules/partition/tests/ClearMountsJobTests.cpp b/src/modules/partition/tests/ClearMountsJobTests.cpp
index 1f01c4638..17ff48945 100644
--- a/src/modules/partition/tests/ClearMountsJobTests.cpp
+++ b/src/modules/partition/tests/ClearMountsJobTests.cpp
@@ -42,7 +42,11 @@ getPartitionsForDevice_other(const QString& deviceName)
process.start();
process.waitForFinished();
- const QString partitions = process.readAllStandardOutput();
+ const QString partitions = process.readAllStandardOutput().trimmed();
+ if ( partitions.isEmpty() )
+ {
+ return QStringList();
+ }
const QStringList partitionsList = partitions.simplified().split( ' ' );
return partitionsList;
diff --git a/src/modules/umount/main.py b/src/modules/umount/main.py
index a337c481a..454222c5c 100644
--- a/src/modules/umount/main.py
+++ b/src/modules/umount/main.py
@@ -98,7 +98,9 @@ def run():
lst.sort(key=lambda x: x[1], reverse=True)
for device, mount_point in lst:
- subprocess.check_call(["umount", "-lv", mount_point])
+ # On success, no output; if the command fails, its output is
+ # in the exception object.
+ subprocess.check_output(["umount", "-lv", mount_point], stderr=subprocess.STDOUT)
os.rmdir(root_mount_point)
diff --git a/src/modules/welcome/WelcomePage.cpp b/src/modules/welcome/WelcomePage.cpp
index e4be00fe7..89fde33a0 100644
--- a/src/modules/welcome/WelcomePage.cpp
+++ b/src/modules/welcome/WelcomePage.cpp
@@ -51,7 +51,45 @@ WelcomePage::WelcomePage( Config* conf, QWidget* parent )
, m_languages( nullptr )
, m_conf( conf )
{
+ using Branding = Calamares::Branding;
+ const int defaultFontHeight = CalamaresUtils::defaultFontHeight();
+ ui->setupUi( this );
+ ui->aboutButton->setIcon( CalamaresUtils::defaultPixmap(
+ CalamaresUtils::Information,
+ CalamaresUtils::Original,
+ 2 * QSize( defaultFontHeight, defaultFontHeight ) ) );
+
+ // insert system-check widget below welcome text
+ const int welcome_text_idx = ui->verticalLayout->indexOf( ui->mainText );
+ ui->verticalLayout->insertWidget( welcome_text_idx + 1, m_checkingWidget );
+
+ // insert optional logo banner image above welcome text
+ QString bannerPath = Branding::instance()->imagePath( Branding::ProductBanner );
+ if ( !bannerPath.isEmpty() )
+ {
+ // If the name is not empty, the file exists -- Branding checks that at startup
+ QPixmap bannerPixmap = QPixmap( bannerPath );
+ if ( !bannerPixmap.isNull() )
+ {
+ QLabel* bannerLabel = new QLabel;
+ bannerLabel->setPixmap( bannerPixmap );
+ bannerLabel->setMinimumHeight( 64 );
+ bannerLabel->setAlignment( Qt::AlignCenter );
+ ui->aboveTextSpacer->changeSize( 20, defaultFontHeight ); // Shrink it down
+ ui->aboveTextSpacer->invalidate();
+ ui->verticalLayout->insertSpacing( welcome_text_idx, defaultFontHeight );
+ ui->verticalLayout->insertWidget( welcome_text_idx, bannerLabel );
+ }
+ }
+
+ initLanguages();
+
+ cDebug() << "Welcome string" << Calamares::Branding::instance()->welcomeStyleCalamares()
+ << *Calamares::Branding::VersionedName;
+ CALAMARES_RETRANSLATE_SLOT( &WelcomePage::retranslate )
+
+ connect( ui->aboutButton, &QPushButton::clicked, this, &WelcomePage::showAboutBox );
connect( Calamares::ModuleManager::instance(),
&Calamares::ModuleManager::requirementsComplete,
m_checkingWidget,
@@ -60,28 +98,6 @@ WelcomePage::WelcomePage( Config* conf, QWidget* parent )
&Calamares::ModuleManager::requirementsProgress,
m_checkingWidget,
&CheckerContainer::requirementsProgress );
- ui->setupUi( this );
-
- ui->verticalLayout->insertSpacing( 1, CalamaresUtils::defaultFontHeight() * 2 );
- initLanguages();
-
- ui->mainText->setAlignment( Qt::AlignCenter );
- ui->mainText->setWordWrap( true );
- ui->mainText->setOpenExternalLinks( true );
-
- cDebug() << "Welcome string" << Calamares::Branding::instance()->welcomeStyleCalamares()
- << *Calamares::Branding::VersionedName;
-
- CALAMARES_RETRANSLATE_SLOT( &WelcomePage::retranslate )
-
- ui->aboutButton->setIcon( CalamaresUtils::defaultPixmap(
- CalamaresUtils::Information,
- CalamaresUtils::Original,
- 2 * QSize( CalamaresUtils::defaultFontHeight(), CalamaresUtils::defaultFontHeight() ) ) );
- connect( ui->aboutButton, &QPushButton::clicked, this, &WelcomePage::showAboutBox );
-
- int welcome_text_idx = ui->verticalLayout->indexOf( ui->mainText );
- ui->verticalLayout->insertWidget( welcome_text_idx + 1, m_checkingWidget );
}
void
diff --git a/src/modules/welcome/WelcomePage.ui b/src/modules/welcome/WelcomePage.ui
index 590029558..04b89f256 100644
--- a/src/modules/welcome/WelcomePage.ui
+++ b/src/modules/welcome/WelcomePage.ui
@@ -17,7 +17,7 @@
-
+ Qt::Vertical
@@ -43,6 +43,12 @@
<Calamares welcome text>
+
+ Qt::AlignCenter
+
+
+ true
+
@@ -78,15 +84,15 @@
-
- Select application and system language
- 20
+
+ Select application and system language
+
diff --git a/src/modules/welcomeq/img/language-icon-48px.png b/src/modules/welcomeq/img/language-icon-48px.png
new file mode 100644
index 000000000..4012a4bee
Binary files /dev/null and b/src/modules/welcomeq/img/language-icon-48px.png differ
diff --git a/src/modules/welcomeq/release_notes.qml b/src/modules/welcomeq/release_notes.qml
new file mode 100644
index 000000000..ce9d1d4af
--- /dev/null
+++ b/src/modules/welcomeq/release_notes.qml
@@ -0,0 +1,100 @@
+/* === This file is part of Calamares - ===
+ *
+ * Copyright 2020, Anke Boersma
+ *
+ * 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 .
+ */
+
+import io.calamares.ui 1.0
+
+import QtQuick 2.7
+import QtQuick.Controls 2.2
+import QtQuick.Window 2.2
+import QtQuick.Layouts 1.3
+
+Rectangle {
+ width: parent.width
+ height: parent.height
+ focus: true
+ color: "#f2f2f2"
+
+ Flickable {
+ id: flick
+ anchors.fill: parent
+ contentHeight: 3500
+
+ ScrollBar.vertical: ScrollBar {
+ id: fscrollbar
+ width: 10
+ policy: ScrollBar.AlwaysOn
+ }
+
+ TextArea {
+ id: intro
+ x: 130
+ y: 8
+ width: 640
+ font.pointSize: 14
+ textFormat: Text.RichText
+ antialiasing: true
+ activeFocusOnPress: false
+ wrapMode: Text.WordWrap
+
+ text: qsTr("
%1
+
This an example QML file, showing options in RichText with Flickable content.
+
+
QML with RichText can use HTML tags, Flickable content is useful for touchscreens.
+
+
This is bold text
+
This is italic text
+
This is underlined text
+
This text will be center-aligned.
+
This is strikethrough
+
+
Code example:
+ ls -l /home
+
+
Lists:
+
+
Intel CPU systems
+
AMD CPU systems
+
+
+
The vertical scrollbar is adjustable, current width set to 10.
").arg(Branding.string(Branding.VersionedName))
+
+ }
+ }
+
+ ToolButton {
+ id: toolButton
+ x: 19
+ y: 29
+ width: 105
+ height: 48
+ text: qsTr("Back")
+ hoverEnabled: true
+ onClicked: load.source = ""
+
+ Image {
+ id: image1
+ x: 0
+ y: 13
+ width: 22
+ height: 22
+ source: "img/chevron-left-solid.svg"
+ fillMode: Image.PreserveAspectFit
+ }
+ }
+
+}
diff --git a/src/modules/welcomeq/welcomeq.qml b/src/modules/welcomeq/welcomeq.qml
index 729b61b28..6330f5116 100644
--- a/src/modules/welcomeq/welcomeq.qml
+++ b/src/modules/welcomeq/welcomeq.qml
@@ -16,6 +16,7 @@
* You should have received a copy of the GNU General Public License
* along with Calamares. If not, see .
*/
+import io.calamares.core 1.0
import io.calamares.ui 1.0
import QtQuick 2.10
@@ -29,21 +30,21 @@ Page
{
id: welcome
- header: Item
- {
+ header: Item {
width: parent.width
height: parent.height
- Text
- {
+ Text {
id: welcomeTopText
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: parent.top
+ horizontalAlignment: Text.AlignHCenter
+ padding: 40
// In QML, QString::arg() only takes one argument
- text: qsTr("