Merge branch 'calamares' of https://github.com/calamares/calamares into development
This commit is contained in:
commit
9a2fd457ba
16
CHANGES-3.2
16
CHANGES-3.2
@ -7,6 +7,22 @@ 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.49 (unreleased) #
|
||||
|
||||
This release contains contributions from (alphabetically by first name):
|
||||
- Artem Grinev
|
||||
- Evan James
|
||||
|
||||
## Core ##
|
||||
- Errors (e.g. when an installation fails for whatever reason) are displayed
|
||||
in a dialog with a scrollable details panel, rather than growing up
|
||||
to the size of the screen. (Thanks Artem)
|
||||
|
||||
## Modules ##
|
||||
- *partition* now supports "deep" btrfs subvolume names, e.g. a
|
||||
separate subvolume for `/usr/local`. (Thanks Evan)
|
||||
|
||||
|
||||
# 3.2.48 (2021-12-03) #
|
||||
|
||||
This release contains contributions from (alphabetically by first name):
|
||||
|
@ -41,11 +41,11 @@
|
||||
# TODO:3.3: Require CMake 3.12
|
||||
cmake_minimum_required( VERSION 3.3 FATAL_ERROR )
|
||||
project( CALAMARES
|
||||
VERSION 3.2.48
|
||||
VERSION 3.2.49
|
||||
LANGUAGES C CXX
|
||||
)
|
||||
|
||||
set( CALAMARES_VERSION_RC 0 ) # Set to 0 during release cycle, 1 during development
|
||||
set( CALAMARES_VERSION_RC 1 ) # Set to 0 during release cycle, 1 during development
|
||||
if( CALAMARES_VERSION_RC EQUAL 1 AND CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR )
|
||||
message( FATAL_ERROR "Do not build development versions in the source-directory." )
|
||||
endif()
|
||||
|
@ -21,10 +21,18 @@ Name[as]=চিছটেম ইনস্তল কৰক
|
||||
Icon[as]=কেলামাৰেচ
|
||||
GenericName[as]=চিছটেম ইনস্তলাৰ
|
||||
Comment[as]=কেলামাৰেচ — চিছটেম ইনস্তলাৰ
|
||||
Name[ast]=Instalar el sistema
|
||||
Icon[ast]=calamares
|
||||
GenericName[ast]=Instalador del sistema
|
||||
Comment[ast]=Calamares — Instalador del sistema
|
||||
Name[az]=Sistemi Quraşdırmaq
|
||||
Icon[az]=calamares
|
||||
GenericName[az]=Sistem Quraşdırıcısı
|
||||
Comment[az]=Calamares Sistem Quraşdırıcısı
|
||||
Name[az_AZ]=Sistemi quraşdırmaq
|
||||
Icon[az_AZ]=calamares
|
||||
GenericName[az_AZ]=Sistem quraşdırcısı
|
||||
Comment[az_AZ]=Calamares — Sistem Quraşdırıcısı
|
||||
Name[be]=Усталяваць сістэму
|
||||
Icon[be]=calamares
|
||||
GenericName[be]=Усталёўшчык сістэмы
|
||||
@ -41,6 +49,10 @@ Name[ca]=Instal·la el sistema
|
||||
Icon[ca]=calamares
|
||||
GenericName[ca]=Instal·lador de sistema
|
||||
Comment[ca]=Calamares — Instal·lador de sistema
|
||||
Name[cs_CZ]=Nainstalovat systém
|
||||
Icon[cs_CZ]=calamares
|
||||
GenericName[cs_CZ]=Instalátor systému
|
||||
Comment[cs_CZ]=Calamares – instalátor operačních systémů
|
||||
Name[da]=Installér system
|
||||
Icon[da]=calamares
|
||||
GenericName[da]=Systeminstallationsprogram
|
||||
@ -57,10 +69,19 @@ Name[en_GB]=Install System
|
||||
Icon[en_GB]=calamares
|
||||
GenericName[en_GB]=System Installer
|
||||
Comment[en_GB]=Calamares — System Installer
|
||||
Name[eo]=Instali Sistemo
|
||||
Icon[eo]=calamares
|
||||
GenericName[eo]=Sistema Instalilo
|
||||
Comment[eo]=Calamares — Sistema Instalilo
|
||||
Name[es]=Instalar Sistema
|
||||
Icon[es]=calamares
|
||||
GenericName[es]=Instalador del Sistema
|
||||
Comment[es]=Calamares — Instalador del Sistema
|
||||
Name[es_MX]=Instalar el Sistema
|
||||
Icon[es_MX]=calamares
|
||||
GenericName[es_MX]=Instalador del sistema
|
||||
Comment[es_MX]=Calamares - Instalador del sistema
|
||||
Name[es_PR]=Instalar el sistema
|
||||
Name[et]=Paigalda süsteem
|
||||
Icon[et]=calamares
|
||||
GenericName[et]=Süsteemipaigaldaja
|
||||
@ -73,7 +94,10 @@ Name[fa]=نصب سامانه
|
||||
Icon[fa]=کالامارس
|
||||
GenericName[fa]=نصبکننده سامانه
|
||||
Comment[fa]=کالامارس — نصبکننده سامانه
|
||||
Name[es_PR]=Instalar el sistema
|
||||
Name[fi_FI]=Asenna järjestelmä
|
||||
Icon[fi_FI]=calamares
|
||||
GenericName[fi_FI]=Järjestelmän asennusohjelma
|
||||
Comment[fi_FI]=Calamares — Järjestelmän asentaja
|
||||
Name[fr]=Installer le système
|
||||
Icon[fr]=calamares
|
||||
GenericName[fr]=Installateur système
|
||||
@ -98,10 +122,6 @@ Name[hr]=Instaliraj sustav
|
||||
Icon[hr]=calamares
|
||||
GenericName[hr]=Instalacija sustava
|
||||
Comment[hr]=Calamares — Instalacija sustava
|
||||
Name[ie]=Installar li sistema
|
||||
Icon[ie]=calamares
|
||||
GenericName[ie]=Installator del sistema
|
||||
Comment[ie]=Calamares — Installator del sistema
|
||||
Name[hu]=Rendszer telepítése
|
||||
Icon[hu]=calamares
|
||||
GenericName[hu]=Rendszertelepítő
|
||||
@ -110,14 +130,18 @@ Name[id]=Instal Sistem
|
||||
Icon[id]=calamares
|
||||
GenericName[id]=Pemasang
|
||||
Comment[id]=Calamares — Pemasang Sistem
|
||||
Name[ie]=Installar li sistema
|
||||
Icon[ie]=calamares
|
||||
GenericName[ie]=Installator del sistema
|
||||
Comment[ie]=Calamares — Installator del sistema
|
||||
Name[is]=Setja upp kerfið
|
||||
Icon[is]=calamares
|
||||
GenericName[is]=Kerfis uppsetning
|
||||
Comment[is]=Calamares — Kerfis uppsetning
|
||||
Name[cs_CZ]=Nainstalovat systém
|
||||
Icon[cs_CZ]=calamares
|
||||
GenericName[cs_CZ]=Instalátor systému
|
||||
Comment[cs_CZ]=Calamares – instalátor operačních systémů
|
||||
Name[it_IT]=Installa il sistema
|
||||
Icon[it_IT]=calamares
|
||||
GenericName[it_IT]=Programma d'installazione del sistema
|
||||
Comment[it_IT]=Calamares — Programma d'installazione del sistema
|
||||
Name[ja]=システムをインストール
|
||||
Icon[ja]=calamares
|
||||
GenericName[ja]=システムインストーラー
|
||||
@ -130,10 +154,6 @@ Name[lt]=Įdiegti Sistemą
|
||||
Icon[lt]=calamares
|
||||
GenericName[lt]=Sistemos diegimas į kompiuterį
|
||||
Comment[lt]=Calamares — Sistemos diegimo programa
|
||||
Name[it_IT]=Installa il sistema
|
||||
Icon[it_IT]=calamares
|
||||
GenericName[it_IT]=Programma d'installazione del sistema
|
||||
Comment[it_IT]=Calamares — Programma d'installazione del sistema
|
||||
Name[mk]=Инсталирај го системот
|
||||
Icon[mk]=calamares
|
||||
GenericName[mk]=Системен Инсталер
|
||||
@ -146,14 +166,14 @@ Name[nb]=Installer System
|
||||
Icon[nb]=calamares
|
||||
GenericName[nb]=Systeminstallatør
|
||||
Comment[nb]=Calamares-systeminstallatør
|
||||
Name[ne_NP]= सिस्टम इन्स्टल गर्नुहोस्
|
||||
Icon[ne_NP]=Calamares
|
||||
GenericName[ne_NP]=सिस्टम इन्स्टलर
|
||||
Comment[ne_NP]=Calamares - सिस्टम इन्स्टलर
|
||||
Name[nl]=Installeer systeem
|
||||
Icon[nl]=calamares
|
||||
GenericName[nl]=Installatieprogramma
|
||||
Comment[nl]=Calamares — Installatieprogramma
|
||||
Name[az_AZ]=Sistemi quraşdırmaq
|
||||
Icon[az_AZ]=calamares
|
||||
GenericName[az_AZ]=Sistem quraşdırcısı
|
||||
Comment[az_AZ]=Calamares — Sistem Quraşdırıcısı
|
||||
Name[pl]=Zainstaluj system
|
||||
Icon[pl]=calamares
|
||||
GenericName[pl]=Instalator systemu
|
||||
@ -162,6 +182,10 @@ Name[pt_BR]=Sistema de Instalação
|
||||
Icon[pt_BR]=calamares
|
||||
GenericName[pt_BR]=Instalador de Sistema
|
||||
Comment[pt_BR]=Calamares — Instalador de Sistema
|
||||
Name[pt_PT]=Instalar Sistema
|
||||
Icon[pt_PT]=calamares
|
||||
GenericName[pt_PT]=Instalador de Sistema
|
||||
Comment[pt_PT]=Instalador de Sistema - Calamares
|
||||
Name[ro]=Instalează sistemul
|
||||
Icon[ro]=calamares
|
||||
GenericName[ro]=Instalator de sistem
|
||||
@ -183,15 +207,11 @@ Name[sq]=Instalo Sistemin
|
||||
Icon[sq]=calamares
|
||||
GenericName[sq]=Instalues Sistemi
|
||||
Comment[sq]=Calamares — Instalues Sistemi
|
||||
Name[fi_FI]=Asenna järjestelmä
|
||||
Icon[fi_FI]=calamares
|
||||
GenericName[fi_FI]=Järjestelmän asennusohjelma
|
||||
Comment[fi_FI]=Calamares — Järjestelmän asentaja
|
||||
Name[sr@latin]=Instaliraj sistem
|
||||
Name[sr]=Инсталирај систем
|
||||
Icon[sr]=calamares
|
||||
GenericName[sr]=Инсталатер система
|
||||
Comment[sr]=Каламарес — инсталатер система
|
||||
Name[sr@latin]=Instaliraj sistem
|
||||
Name[sv]=Installera system
|
||||
Icon[sv]=calamares
|
||||
GenericName[sv]=Systeminstallerare
|
||||
@ -201,6 +221,10 @@ Icon[tg]=calamares
|
||||
GenericName[tg]=Насбкунандаи низомӣ
|
||||
Comment[tg]=Calamares — Насбкунандаи низомӣ
|
||||
Name[th]=ติดตั้งระบบ
|
||||
Name[tr_TR]=Sistemi Yükle
|
||||
Icon[tr_TR]=calamares
|
||||
GenericName[tr_TR]=Sistem Yükleyici
|
||||
Comment[tr_TR]=Calamares — Sistem Yükleyici
|
||||
Name[uk]=Встановити Систему
|
||||
Icon[uk]=calamares
|
||||
GenericName[uk]=Встановлювач системи
|
||||
@ -217,27 +241,3 @@ Name[zh_TW]=安裝系統
|
||||
Icon[zh_TW]=calamares
|
||||
GenericName[zh_TW]=系統安裝程式
|
||||
Comment[zh_TW]=Calamares ── 系統安裝程式
|
||||
Name[ast]=Instalar el sistema
|
||||
Icon[ast]=calamares
|
||||
GenericName[ast]=Instalador del sistema
|
||||
Comment[ast]=Calamares — Instalador del sistema
|
||||
Name[eo]=Instali Sistemo
|
||||
Icon[eo]=calamares
|
||||
GenericName[eo]=Sistema Instalilo
|
||||
Comment[eo]=Calamares — Sistema Instalilo
|
||||
Name[ne_NP]= सिस्टम इन्स्टल गर्नुहोस्
|
||||
Icon[ne_NP]=Calamares
|
||||
GenericName[ne_NP]=सिस्टम इन्स्टलर
|
||||
Comment[ne_NP]=Calamares - सिस्टम इन्स्टलर
|
||||
Name[es_MX]=Instalar el Sistema
|
||||
Icon[es_MX]=calamares
|
||||
GenericName[es_MX]=Instalador del sistema
|
||||
Comment[es_MX]=Calamares - Instalador del sistema
|
||||
Name[pt_PT]=Instalar Sistema
|
||||
Icon[pt_PT]=calamares
|
||||
GenericName[pt_PT]=Instalador de Sistema
|
||||
Comment[pt_PT]=Instalador de Sistema - Calamares
|
||||
Name[tr_TR]=Sistemi Yükle
|
||||
Icon[tr_TR]=calamares
|
||||
GenericName[tr_TR]=Sistem Yükleyici
|
||||
Comment[tr_TR]=Calamares — Sistem Yükleyici
|
||||
|
32
ci/txpull.sh
32
ci/txpull.sh
@ -108,6 +108,21 @@ awk '
|
||||
skip=0; print $0;
|
||||
}}' < calamares.desktop > calamares.desktop.new
|
||||
mv calamares.desktop.new calamares.desktop
|
||||
# Now group translated key-names (Name, Icon, Description, ..) by sorted
|
||||
# language key rather than random-ish language-key order (which shuffles
|
||||
# entries around).
|
||||
#
|
||||
# First, the non-translated lines
|
||||
grep -v '\[.*\]=' calamares.desktop > calamares.desktop.new
|
||||
# The translated lines:
|
||||
# - replace (the first) [] by | so we have a consistent field separator
|
||||
# - sort based on field 2, then 1 (language code, then reversed key-name)
|
||||
# - replace the first | by [, the first (remaining) | by ]
|
||||
# Effectively this puts the fields in this order: Name, Icon, Generic Name,
|
||||
# Comment -- within each language key. This keeps churn down since the
|
||||
# language codes and key-names are constant.
|
||||
grep '\[.*\]=' calamares.desktop | sed -e 's/\[/|/' -e 's/\]/|/' | sort -t '|' -k 2,2 -k 1,1r | sed -e 's/|/\[/' | sed -e 's/|/\]/' >> calamares.desktop.new
|
||||
mv calamares.desktop.new calamares.desktop
|
||||
git add --verbose calamares.desktop
|
||||
git commit "$AUTHOR" --message="i18n: [desktop] $BOILERPLATE" | true
|
||||
|
||||
@ -116,6 +131,19 @@ git commit "$AUTHOR" --message="i18n: [desktop] $BOILERPLATE" | true
|
||||
# PO-Created line). This applies only to modules which use po-files.
|
||||
git diff --numstat src/modules | awk '($1==1 && $2==1){print $3}' | xargs git checkout --
|
||||
|
||||
# sed either wants -i'' (GNU sed) or -i '' (BSD sed) to
|
||||
# replace in a file, with no backup extension. Define
|
||||
# a `reinplace` command to deal with the difference.
|
||||
if test FreeBSD = `uname` ; then
|
||||
reinplace() {
|
||||
sed -i '' "$@"
|
||||
}
|
||||
else
|
||||
reinplace() {
|
||||
sed -i'' "$@"
|
||||
}
|
||||
fi
|
||||
|
||||
# Go through the Python modules; those with a lang/ subdir have their
|
||||
# own complete gettext-based setup.
|
||||
for MODULE_DIR in $(find src/modules -maxdepth 1 -mindepth 1 -type d) ; do
|
||||
@ -125,7 +153,7 @@ for MODULE_DIR in $(find src/modules -maxdepth 1 -mindepth 1 -type d) ; do
|
||||
if [ -d ${MODULE_DIR}/lang ]; then
|
||||
# Convert PO files to MO files
|
||||
for POFILE in $(find ${MODULE_DIR} -name "*.po") ; do
|
||||
sed -i'' '/^"Content-Type/s/CHARSET/UTF-8/' $POFILE
|
||||
reinplace '/^"Content-Type/s/CHARSET/UTF-8/' $POFILE
|
||||
# msgfmt -o ${POFILE%.po}.mo $POFILE
|
||||
done
|
||||
git add --verbose ${MODULE_DIR}/lang/*
|
||||
@ -135,7 +163,7 @@ for MODULE_DIR in $(find src/modules -maxdepth 1 -mindepth 1 -type d) ; do
|
||||
done
|
||||
|
||||
for POFILE in $(find lang -name "python.po") ; do
|
||||
sed -i'' '/^"Content-Type/s/CHARSET/UTF-8/' $POFILE
|
||||
reinplace '/^"Content-Type/s/CHARSET/UTF-8/' $POFILE
|
||||
# msgfmt -o ${POFILE%.po}.mo $POFILE
|
||||
done
|
||||
git add --verbose lang/python*
|
||||
|
@ -688,17 +688,17 @@ Alla ändringar kommer att gå förlorade.</translation>
|
||||
<message>
|
||||
<location filename="../src/modules/partition/jobs/ClearMountsJob.cpp" line="259"/>
|
||||
<source>Successfully unmounted %1.</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Framgångsrikt avmonterade %1.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/modules/partition/jobs/ClearMountsJob.cpp" line="266"/>
|
||||
<source>Successfully disabled swap %1.</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Framgångsrikt inaktiverade swap %1.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/modules/partition/jobs/ClearMountsJob.cpp" line="292"/>
|
||||
<source>Successfully cleared swap %1.</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Framgångsrikt rensade swap %1.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/modules/partition/jobs/ClearMountsJob.cpp" line="306"/>
|
||||
@ -708,7 +708,7 @@ Alla ändringar kommer att gå förlorade.</translation>
|
||||
<message>
|
||||
<location filename="../src/modules/partition/jobs/ClearMountsJob.cpp" line="319"/>
|
||||
<source>Successfully disabled volume group %1.</source>
|
||||
<translation type="unfinished"/>
|
||||
<translation>Framgångsrikt inaktiverade volymgrupp %1.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<location filename="../src/modules/partition/jobs/ClearMountsJob.cpp" line="358"/>
|
||||
|
@ -26,6 +26,11 @@ namespace CalamaresPython
|
||||
boost::python::object
|
||||
variantToPyObject( const QVariant& variant )
|
||||
{
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wswitch-enum"
|
||||
#endif
|
||||
// 49 enumeration values not handled
|
||||
switch ( variant.type() )
|
||||
{
|
||||
case QVariant::Map:
|
||||
@ -62,6 +67,9 @@ variantToPyObject( const QVariant& variant )
|
||||
default:
|
||||
return bp::object();
|
||||
}
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -23,6 +23,11 @@ static const char* s_preScript = nullptr;
|
||||
|
||||
namespace bp = boost::python;
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wdisabled-macro-expansion"
|
||||
#endif
|
||||
|
||||
BOOST_PYTHON_FUNCTION_OVERLOADS( mount_overloads, CalamaresPython::mount, 2, 4 );
|
||||
BOOST_PYTHON_FUNCTION_OVERLOADS( target_env_call_str_overloads, CalamaresPython::target_env_call, 1, 3 );
|
||||
BOOST_PYTHON_FUNCTION_OVERLOADS( target_env_call_list_overloads, CalamaresPython::target_env_call, 1, 3 );
|
||||
@ -42,6 +47,10 @@ BOOST_PYTHON_FUNCTION_OVERLOADS( target_env_process_output_overloads,
|
||||
4 );
|
||||
BOOST_PYTHON_FUNCTION_OVERLOADS( host_env_process_output_overloads, CalamaresPython::host_env_process_output, 1, 4 );
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
BOOST_PYTHON_MODULE( libcalamares )
|
||||
{
|
||||
bp::object package = bp::scope();
|
||||
|
@ -22,6 +22,11 @@ namespace Partition
|
||||
QString
|
||||
prettyNameForFileSystemType( FileSystem::Type t )
|
||||
{
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wswitch-enum"
|
||||
#endif
|
||||
// 13 enumeration values not handled
|
||||
switch ( t )
|
||||
{
|
||||
case FileSystem::Unknown:
|
||||
@ -60,11 +65,19 @@ prettyNameForFileSystemType( FileSystem::Type t )
|
||||
default:
|
||||
return FileSystem::nameForType( t );
|
||||
}
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
}
|
||||
|
||||
QString
|
||||
untranslatedFS( FileSystem::Type t )
|
||||
{
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wswitch-enum"
|
||||
#endif
|
||||
// 34 enumeration values not handled
|
||||
switch ( t )
|
||||
{
|
||||
case FileSystem::Type::ReiserFS:
|
||||
@ -72,6 +85,9 @@ untranslatedFS( FileSystem::Type t )
|
||||
default:
|
||||
return FileSystem::nameForType( t, { QStringLiteral( "C" ) } );
|
||||
}
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace Partition
|
||||
|
@ -115,12 +115,14 @@ System::createTargetFile( const QString& path, const QByteArray& contents, Write
|
||||
QString completePath = targetPath( path );
|
||||
if ( completePath.isEmpty() )
|
||||
{
|
||||
cWarning() << "No target path for" << path;
|
||||
return CreationResult( CreationResult::Code::Invalid );
|
||||
}
|
||||
|
||||
QFile f( completePath );
|
||||
if ( ( mode == WriteMode::KeepExisting ) && f.exists() )
|
||||
{
|
||||
cWarning() << "Target file" << completePath << "already exists";
|
||||
return CreationResult( CreationResult::Code::AlreadyExists );
|
||||
}
|
||||
|
||||
@ -133,13 +135,16 @@ System::createTargetFile( const QString& path, const QByteArray& contents, Write
|
||||
|
||||
if ( !f.open( m ) )
|
||||
{
|
||||
cWarning() << "Could not open target file" << completePath;
|
||||
return CreationResult( CreationResult::Code::Failed );
|
||||
}
|
||||
|
||||
if ( f.write( contents ) != contents.size() )
|
||||
auto written = f.write( contents );
|
||||
if ( written != contents.size() )
|
||||
{
|
||||
f.close();
|
||||
f.remove();
|
||||
cWarning() << "Short write (" << written << "out of" << contents.size() << "bytes) to" << completePath;
|
||||
return CreationResult( CreationResult::Code::Failed );
|
||||
}
|
||||
|
||||
@ -147,6 +152,30 @@ System::createTargetFile( const QString& path, const QByteArray& contents, Write
|
||||
return CreationResult( QFileInfo( f ).canonicalFilePath() );
|
||||
}
|
||||
|
||||
QStringList
|
||||
System::readTargetFile( const QString& path ) const
|
||||
{
|
||||
const QString completePath = targetPath( path );
|
||||
if ( completePath.isEmpty() )
|
||||
{
|
||||
return QStringList();
|
||||
}
|
||||
|
||||
QFile f( completePath );
|
||||
if ( !f.open( QIODevice::ReadOnly ) )
|
||||
{
|
||||
return QStringList();
|
||||
}
|
||||
|
||||
QTextStream in( &f );
|
||||
QStringList l;
|
||||
while ( !f.atEnd() )
|
||||
{
|
||||
l << in.readLine();
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
void
|
||||
System::removeTargetFile( const QString& path ) const
|
||||
{
|
||||
|
@ -287,6 +287,24 @@ public:
|
||||
*/
|
||||
DLLEXPORT void removeTargetFile( const QString& path ) const;
|
||||
|
||||
/** @brief Reads a file from the target system.
|
||||
*
|
||||
* @param path Path to the file; this is interpreted from the root of
|
||||
* the target system (@see targetPath()).
|
||||
*
|
||||
* Does no error checking, and returns an empty list if the file does
|
||||
* not exist.
|
||||
*
|
||||
* NOTE: This function is now basically the same as QFile::readAll(),
|
||||
* splitting into lines, but Calamares may need to change
|
||||
* permissions or raise privileges to actually read the file,
|
||||
* which is why there is an API.
|
||||
*
|
||||
* NOTE: Since this buffers the whole file in memory, reading big files
|
||||
* is not recommended.
|
||||
*/
|
||||
DLLEXPORT QStringList readTargetFile( const QString& path ) const;
|
||||
|
||||
/** @brief Ensure that the directory @p path exists
|
||||
*
|
||||
* @param path a full pathname to a desired directory.
|
||||
|
@ -76,6 +76,9 @@ private Q_SLOTS:
|
||||
void testCalculateWorkingDirectory();
|
||||
void testRunnerOutput();
|
||||
|
||||
/** @section Test file-functions */
|
||||
void testReadWriteFile();
|
||||
|
||||
private:
|
||||
void recursiveCompareMap( const QVariantMap& a, const QVariantMap& b, int depth );
|
||||
};
|
||||
@ -950,6 +953,84 @@ LibCalamaresTests::testRunnerOutput()
|
||||
}
|
||||
|
||||
|
||||
CalamaresUtils::System*
|
||||
file_setup( const QTemporaryDir& tempRoot )
|
||||
{
|
||||
CalamaresUtils::System* ss = CalamaresUtils::System::instance();
|
||||
if ( !ss )
|
||||
{
|
||||
ss = new CalamaresUtils::System( true );
|
||||
}
|
||||
|
||||
Calamares::GlobalStorage* gs
|
||||
= Calamares::JobQueue::instance() ? Calamares::JobQueue::instance()->globalStorage() : nullptr;
|
||||
if ( !gs )
|
||||
{
|
||||
cDebug() << "Creating new JobQueue";
|
||||
(void)new Calamares::JobQueue();
|
||||
gs = Calamares::JobQueue::instance() ? Calamares::JobQueue::instance()->globalStorage() : nullptr;
|
||||
}
|
||||
if ( gs )
|
||||
{
|
||||
// Working with a rootMountPoint set
|
||||
gs->insert( "rootMountPoint", tempRoot.path() );
|
||||
}
|
||||
return ss;
|
||||
}
|
||||
|
||||
void
|
||||
LibCalamaresTests::testReadWriteFile()
|
||||
{
|
||||
static const QByteArray otherContents( "derp\n" );
|
||||
|
||||
QTemporaryDir tempRoot( QDir::tempPath() + QStringLiteral( "/test-job-XXXXXX" ) );
|
||||
auto* ss = file_setup( tempRoot );
|
||||
|
||||
QVERIFY( ss );
|
||||
{
|
||||
auto fullPath = ss->createTargetFile( "test0", QByteArray(), CalamaresUtils::System::WriteMode::Overwrite );
|
||||
QVERIFY( fullPath );
|
||||
QVERIFY( !fullPath.path().isEmpty() );
|
||||
|
||||
QFileInfo fi( fullPath.path() );
|
||||
QVERIFY( fi.exists() );
|
||||
QVERIFY( fi.isFile() );
|
||||
QCOMPARE( fi.size(), 0 );
|
||||
}
|
||||
// It won't overwrite unless you ask for it
|
||||
{
|
||||
auto fullPath = ss->createTargetFile( "test0", otherContents );
|
||||
QVERIFY( !fullPath ); // Failed, because it won't overwrite
|
||||
QCOMPARE( fullPath.code(), decltype(fullPath)::Code::AlreadyExists );
|
||||
QVERIFY( fullPath.path().isEmpty() ); // Because it wasn't written
|
||||
|
||||
QFileInfo fi( tempRoot.filePath( "test0" ) ); // Compute the name some other way
|
||||
QVERIFY( fi.exists() );
|
||||
QVERIFY( fi.isFile() );
|
||||
QCOMPARE( fi.size(), 0 );
|
||||
}
|
||||
// But it will if you say so explicitly
|
||||
{
|
||||
auto fullPath = ss->createTargetFile( "test0", otherContents, CalamaresUtils::System::WriteMode::Overwrite );
|
||||
QVERIFY( fullPath );
|
||||
QVERIFY( !fullPath.path().isEmpty() );
|
||||
|
||||
QFileInfo fi( fullPath.path() );
|
||||
QVERIFY( fi.exists() );
|
||||
QVERIFY( fi.isFile() );
|
||||
QCOMPARE( fi.size(), 5 );
|
||||
}
|
||||
|
||||
// Now it's been written, we can read it, too
|
||||
{
|
||||
auto contents = ss->readTargetFile( "test0" );
|
||||
QVERIFY( !contents.isEmpty() );
|
||||
QCOMPARE( contents.count(), 1 );
|
||||
QCOMPARE( contents[ 0 ], QStringLiteral( "derp" ) ); // No trailing \n
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QTEST_GUILESS_MAIN( LibCalamaresTests )
|
||||
|
||||
#include "utils/moc-warnings.h"
|
||||
|
@ -162,14 +162,15 @@ uploadServerFromMap( const QVariantMap& map )
|
||||
|
||||
if ( typestring.isEmpty() || urlstring.isEmpty() )
|
||||
{
|
||||
return Branding::UploadServerInfo( Branding::UploadServerType::None, QUrl(), 0 );
|
||||
return Branding::UploadServerInfo { Branding::UploadServerType::None, QUrl(), 0 };
|
||||
}
|
||||
|
||||
bool bogus = false; // we don't care about type-name lookup success here
|
||||
return Branding::UploadServerInfo(
|
||||
return Branding::UploadServerInfo {
|
||||
names.find( typestring, bogus ),
|
||||
QUrl( urlstring, QUrl::ParsingMode::StrictMode ),
|
||||
sizeLimitKiB >= 0 ? CalamaresUtils::KiBtoBytes( static_cast< unsigned long long >( sizeLimitKiB ) ) : -1 );
|
||||
sizeLimitKiB >= 0 ? CalamaresUtils::KiBtoBytes( static_cast< unsigned long long >( sizeLimitKiB ) ) : -1
|
||||
};
|
||||
}
|
||||
|
||||
/** @brief Load the @p map with strings from @p config
|
||||
|
@ -227,7 +227,14 @@ public:
|
||||
* is irrelevant and usually empty), the URL for the upload and the size limit of upload
|
||||
* in bytes (for configuration value < 0, it serves -1, which stands for having no limit).
|
||||
*/
|
||||
using UploadServerInfo = std::tuple< UploadServerType, QUrl, qint64 >;
|
||||
struct UploadServerInfo
|
||||
{
|
||||
UploadServerType type;
|
||||
QUrl url;
|
||||
qint64 size;
|
||||
|
||||
operator bool() const { return type != Calamares::Branding::UploadServerType::None && size != 0; }
|
||||
};
|
||||
UploadServerInfo uploadServer() const { return m_uploadServer; }
|
||||
|
||||
/**
|
||||
|
@ -27,6 +27,7 @@ set( calamaresui_SOURCES
|
||||
viewpages/ViewStep.cpp
|
||||
|
||||
widgets/ClickableLabel.cpp
|
||||
widgets/ErrorDialog.cpp
|
||||
widgets/FixedAspectRatioLabel.cpp
|
||||
widgets/PrettyRadioButton.cpp
|
||||
widgets/TranslationFix.cpp
|
||||
@ -39,8 +40,6 @@ set( calamaresui_SOURCES
|
||||
|
||||
# Don't warn about third-party sources
|
||||
mark_thirdparty_code(
|
||||
${CMAKE_SOURCE_DIR}/3rdparty/qjsonitem.cpp
|
||||
${CMAKE_SOURCE_DIR}/3rdparty/qjsonmodel.cpp
|
||||
${CMAKE_SOURCE_DIR}/3rdparty/waitingspinnerwidget.cpp
|
||||
)
|
||||
|
||||
@ -75,6 +74,8 @@ calamares_add_library( calamaresui
|
||||
Qt5::Svg
|
||||
RESOURCES libcalamaresui.qrc
|
||||
EXPORT Calamares
|
||||
UI
|
||||
utils/ErrorDialog/ErrorDialog.ui
|
||||
VERSION ${CALAMARES_VERSION_SHORT}
|
||||
)
|
||||
target_link_libraries( calamaresui PRIVATE yamlcpp::yamlcpp )
|
||||
|
@ -24,11 +24,13 @@
|
||||
#include "viewpages/BlankViewStep.h"
|
||||
#include "viewpages/ExecutionViewStep.h"
|
||||
#include "viewpages/ViewStep.h"
|
||||
#include "widgets/ErrorDialog.h"
|
||||
#include "widgets/TranslationFix.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QBoxLayout>
|
||||
#include <QClipboard>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QFile>
|
||||
#include <QMessageBox>
|
||||
#include <QMetaObject>
|
||||
@ -150,56 +152,32 @@ ViewManager::insertViewStep( int before, ViewStep* step )
|
||||
void
|
||||
ViewManager::onInstallationFailed( const QString& message, const QString& details )
|
||||
{
|
||||
bool shouldOfferWebPaste = std::get< 0 >( Calamares::Branding::instance()->uploadServer() )
|
||||
!= Calamares::Branding::UploadServerType::None
|
||||
and std::get< 2 >( Calamares::Branding::instance()->uploadServer() ) != 0;
|
||||
|
||||
cError() << "Installation failed:" << message;
|
||||
cDebug() << Logger::SubEntry << "- message:" << message;
|
||||
cDebug() << Logger::SubEntry << "- details:" << Logger::NoQuote << details;
|
||||
|
||||
QString heading
|
||||
= Calamares::Settings::instance()->isSetupMode() ? tr( "Setup Failed" ) : tr( "Installation Failed" );
|
||||
QString pasteMsg = tr( "Would you like to paste the install log to the web?" );
|
||||
QString text = "<p>" + message + "</p>";
|
||||
if ( !details.isEmpty() )
|
||||
{
|
||||
text += "<p>"
|
||||
+ CalamaresUtils::truncateMultiLine( details, CalamaresUtils::LinesStartEnd { 6, 2 } )
|
||||
.replace( '\n', QStringLiteral( "<br/>" ) )
|
||||
+ "</p>";
|
||||
}
|
||||
if ( shouldOfferWebPaste )
|
||||
{
|
||||
text += "<p>" + pasteMsg + "</p>";
|
||||
}
|
||||
|
||||
QMessageBox* msgBox = new QMessageBox();
|
||||
msgBox->setIcon( QMessageBox::Critical );
|
||||
msgBox->setWindowTitle( tr( "Error" ) );
|
||||
msgBox->setText( "<strong>" + heading + "</strong>" );
|
||||
msgBox->setInformativeText( text );
|
||||
if ( shouldOfferWebPaste )
|
||||
{
|
||||
msgBox->setStandardButtons( QMessageBox::Yes | QMessageBox::No );
|
||||
msgBox->setDefaultButton( QMessageBox::No );
|
||||
}
|
||||
else
|
||||
{
|
||||
msgBox->setStandardButtons( QMessageBox::Close );
|
||||
msgBox->setDefaultButton( QMessageBox::Close );
|
||||
}
|
||||
Calamares::fixButtonLabels( msgBox );
|
||||
msgBox->show();
|
||||
ErrorDialog* errorDialog = new ErrorDialog();
|
||||
errorDialog->setWindowTitle( tr( "Error" ) );
|
||||
errorDialog->setHeading( "<strong>" + heading + "</strong>" );
|
||||
errorDialog->setInformativeText( message );
|
||||
errorDialog->setShouldOfferWebPaste( Calamares::Branding::instance()->uploadServer() );
|
||||
errorDialog->setDetails( details );
|
||||
errorDialog->show();
|
||||
|
||||
cDebug() << "Calamares will quit when the dialog closes.";
|
||||
connect( msgBox, &QMessageBox::buttonClicked, [msgBox]( QAbstractButton* button ) {
|
||||
if ( msgBox->buttonRole( button ) == QMessageBox::ButtonRole::YesRole )
|
||||
{
|
||||
CalamaresUtils::Paste::doLogUploadUI( msgBox );
|
||||
}
|
||||
QApplication::quit();
|
||||
} );
|
||||
connect( errorDialog,
|
||||
&QDialog::finished,
|
||||
[ errorDialog ]( int result )
|
||||
{
|
||||
if ( result == QDialog::Accepted && errorDialog->shouldOfferWebPaste() )
|
||||
{
|
||||
CalamaresUtils::Paste::doLogUploadUI( errorDialog );
|
||||
}
|
||||
QApplication::quit();
|
||||
} );
|
||||
}
|
||||
|
||||
|
||||
|
@ -69,7 +69,8 @@ STATICTEST QString
|
||||
ficheLogUpload( const QByteArray& pasteData, const QUrl& serverUrl, QObject* parent )
|
||||
{
|
||||
QTcpSocket* socket = new QTcpSocket( parent );
|
||||
socket->connectToHost( serverUrl.host(), serverUrl.port() );
|
||||
// 16 bits of port-number
|
||||
socket->connectToHost( serverUrl.host(), quint16( serverUrl.port() ) );
|
||||
|
||||
if ( !socket->waitForConnected() )
|
||||
{
|
||||
|
106
src/libcalamaresui/widgets/ErrorDialog.cpp
Normal file
106
src/libcalamaresui/widgets/ErrorDialog.cpp
Normal file
@ -0,0 +1,106 @@
|
||||
/* === This file is part of Calamares - <https://calamares.io> ===
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2021 Artem Grinev <agrinev@manjaro.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* Calamares is Free Software: see the License-Identifier above.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "ErrorDialog.h"
|
||||
#include "ui_ErrorDialog.h"
|
||||
|
||||
#include "widgets/TranslationFix.h"
|
||||
#include <QDialogButtonBox>
|
||||
#include <QIcon>
|
||||
|
||||
namespace Calamares
|
||||
{
|
||||
|
||||
ErrorDialog::ErrorDialog( QWidget* parent )
|
||||
: QDialog( parent )
|
||||
, ui( new Ui::ErrorDialog )
|
||||
{
|
||||
ui->setupUi( this );
|
||||
ui->iconLabel->setPixmap( QIcon::fromTheme( "dialog-error" ).pixmap( 64 ) );
|
||||
ui->detailsWidget->hide();
|
||||
ui->offerWebPasteLabel->hide();
|
||||
}
|
||||
|
||||
ErrorDialog::~ErrorDialog()
|
||||
{
|
||||
delete ui;
|
||||
}
|
||||
|
||||
QString
|
||||
ErrorDialog::heading() const
|
||||
{
|
||||
return ui->headingLabel->text();
|
||||
}
|
||||
|
||||
QString
|
||||
ErrorDialog::informativeText() const
|
||||
{
|
||||
return ui->informativeTextLabel->text();
|
||||
}
|
||||
|
||||
QString
|
||||
ErrorDialog::details() const
|
||||
{
|
||||
return ui->detailsBrowser->toPlainText();
|
||||
}
|
||||
|
||||
void
|
||||
ErrorDialog::setHeading( const QString& newHeading )
|
||||
{
|
||||
if ( ui->headingLabel->text() != newHeading )
|
||||
{
|
||||
ui->headingLabel->setText( newHeading );
|
||||
emit headingChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ErrorDialog::setInformativeText( const QString& newInformativeText )
|
||||
{
|
||||
if ( ui->informativeTextLabel->text() != newInformativeText )
|
||||
{
|
||||
ui->informativeTextLabel->setText( newInformativeText );
|
||||
emit informativeTextChanged();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ErrorDialog::setDetails( const QString& newDetails )
|
||||
{
|
||||
if ( ui->detailsBrowser->toPlainText() != newDetails )
|
||||
{
|
||||
ui->detailsBrowser->setPlainText( newDetails );
|
||||
ui->detailsWidget->setVisible( !ui->detailsBrowser->toPlainText().trimmed().isEmpty() );
|
||||
emit detailsChanged();
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
ErrorDialog::shouldOfferWebPaste() const
|
||||
{
|
||||
return m_shouldOfferWebPaste;
|
||||
}
|
||||
|
||||
void
|
||||
ErrorDialog::setShouldOfferWebPaste( bool newShouldOfferWebPaste )
|
||||
{
|
||||
if ( m_shouldOfferWebPaste != newShouldOfferWebPaste )
|
||||
{
|
||||
m_shouldOfferWebPaste = newShouldOfferWebPaste;
|
||||
|
||||
ui->offerWebPasteLabel->setVisible( m_shouldOfferWebPaste );
|
||||
ui->buttonBox->setStandardButtons( m_shouldOfferWebPaste ? ( QDialogButtonBox::Yes | QDialogButtonBox::No )
|
||||
: QDialogButtonBox::Close );
|
||||
fixButtonLabels( ui->buttonBox );
|
||||
|
||||
emit shouldOfferWebPasteChanged();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Calamares
|
83
src/libcalamaresui/widgets/ErrorDialog.h
Normal file
83
src/libcalamaresui/widgets/ErrorDialog.h
Normal file
@ -0,0 +1,83 @@
|
||||
/* === This file is part of Calamares - <https://calamares.io> ===
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2021 Artem Grinev <agrinev@manjaro.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* Calamares is Free Software: see the License-Identifier above.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LIBCALAMARESUI_ERRORDIALOG_H
|
||||
#define LIBCALAMARESUI_ERRORDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class ErrorDialog;
|
||||
}
|
||||
|
||||
namespace Calamares
|
||||
{
|
||||
class ErrorDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY( QString heading READ heading WRITE setHeading NOTIFY headingChanged )
|
||||
Q_PROPERTY( QString informativeText READ informativeText WRITE setInformativeText NOTIFY informativeTextChanged )
|
||||
Q_PROPERTY( QString details READ details WRITE setDetails NOTIFY detailsChanged )
|
||||
Q_PROPERTY( bool shouldOfferWebPaste READ shouldOfferWebPaste WRITE setShouldOfferWebPaste NOTIFY
|
||||
shouldOfferWebPasteChanged )
|
||||
|
||||
public:
|
||||
explicit ErrorDialog( QWidget* parent = nullptr );
|
||||
~ErrorDialog() override;
|
||||
|
||||
/** @brief The heading (title) of the error dialog
|
||||
*
|
||||
* This is a short (one-line) title. It is human-readable, so should
|
||||
* be translated at the time it is set.
|
||||
*/
|
||||
QString heading() const;
|
||||
void setHeading( const QString& newHeading );
|
||||
|
||||
/** @brief The description of the problem
|
||||
*
|
||||
* Longer, human-readable, description of the problem. This text
|
||||
* is word-wrapped as necessary.
|
||||
*/
|
||||
QString informativeText() const;
|
||||
void setInformativeText( const QString& newInformativeText );
|
||||
|
||||
/** @brief Details of the problem
|
||||
*
|
||||
* This is generally command-output; it might not be translated
|
||||
* when set. It should be considered "background to the informative
|
||||
* text", or maybe "the reasons". Write the informative text for
|
||||
* the end-user.
|
||||
*/
|
||||
QString details() const;
|
||||
void setDetails( const QString& newDetails );
|
||||
|
||||
/** @brief Enable web-paste button
|
||||
*
|
||||
* The web-paste button can be configured at a global level,
|
||||
* but each individual error dialog can be set separately.
|
||||
*/
|
||||
bool shouldOfferWebPaste() const;
|
||||
void setShouldOfferWebPaste( bool newShouldOfferWebPaste );
|
||||
|
||||
signals:
|
||||
void headingChanged();
|
||||
void informativeTextChanged();
|
||||
void detailsChanged();
|
||||
void shouldOfferWebPasteChanged();
|
||||
|
||||
private:
|
||||
Ui::ErrorDialog* ui;
|
||||
bool m_shouldOfferWebPaste = false;
|
||||
};
|
||||
|
||||
}; // namespace Calamares
|
||||
|
||||
#endif // LIBCALAMARESUI_ERRORDIALOG_H
|
133
src/libcalamaresui/widgets/ErrorDialog.ui
Normal file
133
src/libcalamaresui/widgets/ErrorDialog.ui
Normal file
@ -0,0 +1,133 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>ErrorDialog</class>
|
||||
<widget class="QDialog" name="ErrorDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>425</width>
|
||||
<height>262</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string notr="true">Dialog</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="5" column="0" colspan="2">
|
||||
<widget class="QWidget" name="detailsWidget" native="true">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QLabel" name="informativeTextLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Details:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QTextBrowser" name="detailsBrowser"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<widget class="QLabel" name="offerWebPasteLabel">
|
||||
<property name="toolTip">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Would you like to paste the install log to the web?</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0" colspan="2">
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Close</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="iconLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="headingLabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true"/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>ErrorDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>ErrorDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
@ -11,30 +11,34 @@
|
||||
|
||||
#include <QAbstractButton>
|
||||
#include <QCoreApplication>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QMessageBox>
|
||||
#include <QPushButton>
|
||||
|
||||
namespace Calamares
|
||||
{
|
||||
|
||||
//Using QMessageBox's StandardButton enum here but according to headers they should be kept in-sync between multiple classes.
|
||||
static std::pair< decltype( QMessageBox::Ok ), const char* > maps[] = {
|
||||
{ QMessageBox::Ok, QT_TRANSLATE_NOOP( "StandardButtons", "&OK" ) },
|
||||
{ QMessageBox::Yes, QT_TRANSLATE_NOOP( "StandardButtons", "&Yes" ) },
|
||||
{ QMessageBox::No, QT_TRANSLATE_NOOP( "StandardButtons", "&No" ) },
|
||||
{ QMessageBox::Cancel, QT_TRANSLATE_NOOP( "StandardButtons", "&Cancel" ) },
|
||||
{ QMessageBox::Close, QT_TRANSLATE_NOOP( "StandardButtons", "&Close" ) },
|
||||
};
|
||||
|
||||
template < typename TButtonBox >
|
||||
void
|
||||
fixButtonLabels( QMessageBox* box )
|
||||
fixButtonLabels( TButtonBox* box )
|
||||
{
|
||||
if ( !box )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static std::pair< decltype( QMessageBox::Ok ), const char* > maps[] = {
|
||||
{ QMessageBox::Ok, QT_TRANSLATE_NOOP( "StandardButtons", "&OK" ) },
|
||||
{ QMessageBox::Yes, QT_TRANSLATE_NOOP( "StandardButtons", "&Yes" ) },
|
||||
{ QMessageBox::No, QT_TRANSLATE_NOOP( "StandardButtons", "&No" ) },
|
||||
{ QMessageBox::Cancel, QT_TRANSLATE_NOOP( "StandardButtons", "&Cancel" ) },
|
||||
{ QMessageBox::Close, QT_TRANSLATE_NOOP( "StandardButtons", "&Close" ) },
|
||||
};
|
||||
|
||||
for ( auto [ sb, label ] : maps )
|
||||
{
|
||||
auto* button = box->button( sb );
|
||||
auto* button = box->button( static_cast< typename TButtonBox::StandardButton >( int( sb ) ) );
|
||||
if ( button )
|
||||
{
|
||||
button->setText( QCoreApplication::translate( "StandardButtons", label ) );
|
||||
@ -42,4 +46,16 @@ fixButtonLabels( QMessageBox* box )
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
fixButtonLabels( QMessageBox* box )
|
||||
{
|
||||
fixButtonLabels< QMessageBox >( box );
|
||||
}
|
||||
|
||||
void
|
||||
fixButtonLabels( QDialogButtonBox* box )
|
||||
{
|
||||
fixButtonLabels< QDialogButtonBox >( box );
|
||||
}
|
||||
|
||||
} // namespace Calamares
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "DllMacro.h"
|
||||
|
||||
class QMessageBox;
|
||||
class QDialogButtonBox;
|
||||
|
||||
namespace Calamares
|
||||
{
|
||||
@ -26,6 +27,8 @@ namespace Calamares
|
||||
* guess the context.
|
||||
*/
|
||||
void UIDLLEXPORT fixButtonLabels( QMessageBox* );
|
||||
|
||||
void UIDLLEXPORT fixButtonLabels( QDialogButtonBox* );
|
||||
} // namespace Calamares
|
||||
|
||||
#endif
|
||||
|
@ -224,7 +224,7 @@ def create_systemd_boot_conf(install_path, efi_dir, uuid, entry, entry_name, ker
|
||||
|
||||
# Copy kernel and initramfs to a subdirectory of /efi partition
|
||||
files_dir = os.path.join(install_path + efi_dir, entry_name)
|
||||
os.mkdir(files_dir)
|
||||
os.makedirs(files_dir, exist_ok=True)
|
||||
|
||||
kernel_path = install_path + kernel
|
||||
kernel_name = os.path.basename(kernel_path)
|
||||
|
@ -18,10 +18,16 @@
|
||||
#
|
||||
# btrfs_swap options are used when a swapfile is chosen with a btrfs root
|
||||
# the options are applied to the subvolume which holds the swap partition
|
||||
#
|
||||
# The settings shown here apply only the btrfs defaults; these
|
||||
# are generally the right ones. Commented-out lines show other
|
||||
# options wich **might** be applicable for specific situations.
|
||||
mountOptions:
|
||||
default: defaults,noatime
|
||||
btrfs: defaults,noatime,autodefrag,compress=zstd
|
||||
btrfs_swap: defaults,noatime
|
||||
# btrfs: defaults,noatime,autodefrag,compress=zstd
|
||||
btrfs: defaults
|
||||
# btrfs_swap: defaults,noatime
|
||||
btrfs_swap: defaults
|
||||
|
||||
# Mount options to use for the EFI System Partition. If not defined, the
|
||||
# *mountOptions* for *vfat* are used, or if that is not set either,
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include <KParts/ReadOnlyPart>
|
||||
#include <KParts/kde_terminal_interface.h>
|
||||
#include <KService>
|
||||
#include <kcoreaddons_version.h>
|
||||
|
||||
#include <QApplication>
|
||||
#include <QDir>
|
||||
@ -41,8 +42,10 @@ InteractiveTerminalPage::InteractiveTerminalPage( QWidget* parent )
|
||||
void
|
||||
InteractiveTerminalPage::errorKonsoleNotInstalled()
|
||||
{
|
||||
QMessageBox mb(QMessageBox::Critical,
|
||||
tr( "Konsole not installed" ), tr( "Please install KDE Konsole and try again!" ), QMessageBox::Ok );
|
||||
QMessageBox mb( QMessageBox::Critical,
|
||||
tr( "Konsole not installed" ),
|
||||
tr( "Please install KDE Konsole and try again!" ),
|
||||
QMessageBox::Ok );
|
||||
Calamares::fixButtonLabels( &mb );
|
||||
mb.exec();
|
||||
}
|
||||
@ -54,20 +57,30 @@ InteractiveTerminalPage::onActivate()
|
||||
{
|
||||
return;
|
||||
}
|
||||
// For whatever reason, instead of simply linking against a library we
|
||||
// need to do a runtime query to KService just to get a sodding terminal
|
||||
// widget.
|
||||
|
||||
#if KCOREADDONS_VERSION_MAJOR != 5
|
||||
#error Incompatible with not-KF5
|
||||
#endif
|
||||
#if KCOREADDONS_VERSION_MINOR >= 86
|
||||
// 5.86 deprecated a bunch of KService and PluginFactory and related methods
|
||||
auto md = KPluginMetaData::findPluginById( QString(), "konsolepart" );
|
||||
if ( !md.isValid() )
|
||||
{
|
||||
errorKonsoleNotInstalled();
|
||||
return;
|
||||
}
|
||||
auto* p = KPluginFactory::instantiatePlugin< KParts::ReadOnlyPart >( md, this ).plugin;
|
||||
#else
|
||||
KService::Ptr service = KService::serviceByDesktopName( "konsolepart" );
|
||||
if ( !service )
|
||||
{
|
||||
// And all of this hoping the Konsole application is installed. If not,
|
||||
// tough cookies.
|
||||
errorKonsoleNotInstalled();
|
||||
return;
|
||||
}
|
||||
|
||||
// Create one instance of konsolepart.
|
||||
KParts::ReadOnlyPart* p = service->createInstance< KParts::ReadOnlyPart >( this, this, {} );
|
||||
#endif
|
||||
if ( !p )
|
||||
{
|
||||
// One more opportunity for the loading operation to fail.
|
||||
@ -91,7 +104,6 @@ InteractiveTerminalPage::onActivate()
|
||||
|
||||
m_termHostWidget = p->widget();
|
||||
m_layout->addWidget( m_termHostWidget );
|
||||
cDebug() << "Part widget ought to be" << m_termHostWidget->metaObject()->className();
|
||||
|
||||
t->showShellInDir( QDir::home().path() );
|
||||
t->sendInput( QString( "%1\n" ).arg( m_command ) );
|
||||
|
@ -64,6 +64,11 @@ def write_openswap_conf(partitions, root_mount_point, openswap_conf_path):
|
||||
elif lines[i].startswith("keyfile_filename"):
|
||||
lines[i] = "keyfile_filename=crypto_keyfile.bin"
|
||||
|
||||
elif lines[i].startswith("#keyfile_device_mount_options"):
|
||||
if libcalamares.globalstorage.contains("btrfsRootSubvolume"):
|
||||
btrfs_root_subvolume = libcalamares.globalstorage.value("btrfsRootSubvolume")
|
||||
lines[i] = "keyfile_device_mount_options=--options=subvol=" + btrfs_root_subvolume.lstrip("/")
|
||||
|
||||
with open(os.path.join(root_mount_point,
|
||||
openswap_conf_path), 'w') as openswap_file:
|
||||
openswap_file.write("\n".join(lines) + "\n")
|
||||
@ -84,11 +89,11 @@ def run():
|
||||
if not partitions:
|
||||
libcalamares.utils.warning("partitions is empty, {!s}".format(partitions))
|
||||
return (_("Configuration Error"),
|
||||
_("No partitions are defined for <pre>{!s}</pre> to use." ).format("luksopenswaphookcfg"))
|
||||
_("No partitions are defined for <pre>{!s}</pre> to use.").format("luksopenswaphookcfg"))
|
||||
if not root_mount_point:
|
||||
libcalamares.utils.warning("rootMountPoint is empty, {!s}".format(root_mount_point))
|
||||
return (_("Configuration Error"),
|
||||
_("No root mount point is given for <pre>{!s}</pre> to use." ).format("luksopenswaphookcfg"))
|
||||
_("No root mount point is given for <pre>{!s}</pre> to use.").format("luksopenswaphookcfg"))
|
||||
|
||||
openswap_conf_path = openswap_conf_path.lstrip('/')
|
||||
|
||||
|
@ -193,6 +193,7 @@ def mount_partition(root_mount_point, partition, partitions):
|
||||
for s in btrfs_subvolumes:
|
||||
if not s["subvolume"]:
|
||||
continue
|
||||
os.makedirs(root_mount_point + os.path.dirname(s["subvolume"]), exist_ok=True)
|
||||
subprocess.check_call(["btrfs", "subvolume", "create",
|
||||
root_mount_point + s["subvolume"]])
|
||||
if s["mountPoint"] == "/":
|
||||
|
@ -146,15 +146,12 @@ modeDescription( Config::InstallChoice choice )
|
||||
case Config::InstallChoice::Alongside:
|
||||
return QCoreApplication::translate( context, "Install %1 <strong>alongside</strong> another operating system." )
|
||||
.arg( branding->shortVersionedName() );
|
||||
break;
|
||||
case Config::InstallChoice::Erase:
|
||||
return QCoreApplication::translate( context, "<strong>Erase</strong> disk and install %1." )
|
||||
.arg( branding->shortVersionedName() );
|
||||
break;
|
||||
case Config::InstallChoice::Replace:
|
||||
return QCoreApplication::translate( context, "<strong>Replace</strong> a partition with %1." )
|
||||
.arg( branding->shortVersionedName() );
|
||||
break;
|
||||
case Config::InstallChoice::NoChoice:
|
||||
case Config::InstallChoice::Manual:
|
||||
return QCoreApplication::translate( context, "<strong>Manual</strong> partitioning." );
|
||||
@ -187,21 +184,18 @@ diskDescription( int listLength, const PartitionCoreModule::SummaryInfo& info, C
|
||||
.arg( branding->shortVersionedName() )
|
||||
.arg( info.deviceNode )
|
||||
.arg( info.deviceName );
|
||||
break;
|
||||
case Config::Erase:
|
||||
return QCoreApplication::translate( context,
|
||||
"<strong>Erase</strong> disk <strong>%2</strong> (%3) and install %1." )
|
||||
.arg( branding->shortVersionedName() )
|
||||
.arg( info.deviceNode )
|
||||
.arg( info.deviceName );
|
||||
break;
|
||||
case Config::Replace:
|
||||
return QCoreApplication::translate(
|
||||
context, "<strong>Replace</strong> a partition on disk <strong>%2</strong> (%3) with %1." )
|
||||
.arg( branding->shortVersionedName() )
|
||||
.arg( info.deviceNode )
|
||||
.arg( info.deviceName );
|
||||
break;
|
||||
case Config::NoChoice:
|
||||
case Config::Manual:
|
||||
return QCoreApplication::translate(
|
||||
@ -558,7 +552,7 @@ PartitionViewStep::onLeave()
|
||||
if ( !okSize )
|
||||
{
|
||||
cDebug() << o << "ESP too small";
|
||||
const auto atLeastBytes = PartUtils::efiFilesystemMinimumSize();
|
||||
const qint64 atLeastBytes = static_cast< qint64 >( PartUtils::efiFilesystemMinimumSize() );
|
||||
const auto atLeastMiB = CalamaresUtils::BytesToMiB( atLeastBytes );
|
||||
description.append( ' ' );
|
||||
description.append( tr( "The filesystem must be at least %1 MiB in size." ).arg( atLeastMiB ) );
|
||||
|
@ -8,9 +8,10 @@
|
||||
* Calamares is Free Software: see the License-Identifier above.
|
||||
*
|
||||
*/
|
||||
#include "core/DeviceModel.h"
|
||||
#include "DeviceModel.h"
|
||||
|
||||
#include "core/PartitionModel.h"
|
||||
#include "core/SizeUtils.h"
|
||||
|
||||
#include "utils/CalamaresUtilsGui.h"
|
||||
#include "utils/Logger.h"
|
||||
@ -18,9 +19,6 @@
|
||||
// KPMcore
|
||||
#include <kpmcore/core/device.h>
|
||||
|
||||
// KF5
|
||||
#include <KFormat>
|
||||
|
||||
#include <QIcon>
|
||||
#include <QStandardItemModel>
|
||||
|
||||
@ -83,7 +81,7 @@ DeviceModel::data( const QModelIndex& index, int role ) const
|
||||
//: device[name] - size[number] (device-node[name])
|
||||
return tr( "%1 - %2 (%3)" )
|
||||
.arg( device->name() )
|
||||
.arg( KFormat().formatByteSize( device->capacity() ) )
|
||||
.arg( formatByteSize( device->capacity() ) )
|
||||
.arg( device->deviceNode() );
|
||||
}
|
||||
else
|
||||
|
@ -451,6 +451,8 @@ isEfiFilesystemSuitableType( const Partition* candidate )
|
||||
{
|
||||
auto type = candidate->fileSystem().type();
|
||||
|
||||
QT_WARNING_PUSH
|
||||
QT_WARNING_DISABLE_CLANG( "-Wswitch-enum" )
|
||||
switch ( type )
|
||||
{
|
||||
case FileSystem::Type::Fat32:
|
||||
@ -465,6 +467,7 @@ isEfiFilesystemSuitableType( const Partition* candidate )
|
||||
cWarning() << "EFI boot partition must be FAT32";
|
||||
return false;
|
||||
}
|
||||
QT_WARNING_POP
|
||||
}
|
||||
|
||||
bool
|
||||
@ -526,14 +529,15 @@ efiFilesystemMinimumSize()
|
||||
{
|
||||
using CalamaresUtils::Units::operator""_MiB;
|
||||
|
||||
auto uefisys_part_sizeB = 300_MiB;
|
||||
size_t uefisys_part_sizeB = 300_MiB;
|
||||
|
||||
// The default can be overridden; the key used here comes
|
||||
// from the partition module Config.cpp
|
||||
auto* gs = Calamares::JobQueue::instance()->globalStorage();
|
||||
if ( gs->contains( "efiSystemPartitionSize_i" ) )
|
||||
{
|
||||
uefisys_part_sizeB = gs->value( "efiSystemPartitionSize_i" ).toLongLong();
|
||||
qint64 v = gs->value( "efiSystemPartitionSize_i" ).toLongLong();
|
||||
uefisys_part_sizeB = v > 0 ? static_cast< size_t >( v ) : 0;
|
||||
}
|
||||
// There is a lower limit of what can be configured
|
||||
if ( uefisys_part_sizeB < 32_MiB )
|
||||
|
@ -71,15 +71,15 @@ swapSuggestion( const qint64 availableSpaceB, Config::SwapChoice swap )
|
||||
|
||||
|
||||
// Allow for a fudge factor
|
||||
suggestedSwapSizeB *= overestimationFactor;
|
||||
suggestedSwapSizeB = qRound( suggestedSwapSizeB * overestimationFactor );
|
||||
|
||||
// don't use more than 10% of available space
|
||||
if ( !ensureSuspendToDisk )
|
||||
{
|
||||
suggestedSwapSizeB = qMin( suggestedSwapSizeB, qint64( 0.10 * availableSpaceB ) );
|
||||
suggestedSwapSizeB = qMin( suggestedSwapSizeB, availableSpaceB / 10 /* 10% is 0.1 */ );
|
||||
}
|
||||
|
||||
cDebug() << "Suggested swap size:" << suggestedSwapSizeB / 1024. / 1024. / 1024. << "GiB";
|
||||
cDebug() << "Suggested swap size:" << CalamaresUtils::BytesToGiB( suggestedSwapSizeB ) << "GiB";
|
||||
|
||||
return suggestedSwapSizeB;
|
||||
}
|
||||
|
@ -141,6 +141,8 @@ void
|
||||
PartitionLayout::setDefaultFsType( FileSystem::Type defaultFsType )
|
||||
{
|
||||
using FileSystem = FileSystem::Type;
|
||||
QT_WARNING_PUSH
|
||||
QT_WARNING_DISABLE_CLANG( "-Wswitch-enum" )
|
||||
switch ( defaultFsType )
|
||||
{
|
||||
case FileSystem::Unknown:
|
||||
@ -196,6 +198,7 @@ PartitionLayout::setDefaultFsType( FileSystem::Type defaultFsType )
|
||||
<< "Using ext4 instead.";
|
||||
defaultFsType = FileSystem::Ext4;
|
||||
}
|
||||
QT_WARNING_POP
|
||||
|
||||
m_defaultFsType = defaultFsType;
|
||||
}
|
||||
|
@ -8,11 +8,12 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include "core/PartitionModel.h"
|
||||
#include "PartitionModel.h"
|
||||
|
||||
#include "core/ColorUtils.h"
|
||||
#include "core/KPMHelpers.h"
|
||||
#include "core/PartitionInfo.h"
|
||||
#include "core/SizeUtils.h"
|
||||
|
||||
#include "partition/FileSystem.h"
|
||||
#include "partition/PartitionQuery.h"
|
||||
@ -24,9 +25,6 @@
|
||||
#include <kpmcore/core/partitiontable.h>
|
||||
#include <kpmcore/fs/filesystem.h>
|
||||
|
||||
// KF5
|
||||
#include <KFormat>
|
||||
|
||||
// Qt
|
||||
#include <QColor>
|
||||
|
||||
@ -178,7 +176,7 @@ PartitionModel::data( const QModelIndex& index, int role ) const
|
||||
if ( col == SizeColumn )
|
||||
{
|
||||
qint64 size = ( partition->lastSector() - partition->firstSector() + 1 ) * m_device->logicalSize();
|
||||
return KFormat().formatByteSize( size );
|
||||
return formatByteSize( size );
|
||||
}
|
||||
cDebug() << "Unknown column" << col;
|
||||
return QVariant();
|
||||
@ -210,7 +208,7 @@ PartitionModel::data( const QModelIndex& index, int role ) const
|
||||
QString prettyFileSystem
|
||||
= CalamaresUtils::Partition::prettyNameForFileSystemType( partition->fileSystem().type() );
|
||||
qint64 size = ( partition->lastSector() - partition->firstSector() + 1 ) * m_device->logicalSize();
|
||||
QString prettySize = KFormat().formatByteSize( size );
|
||||
QString prettySize = formatByteSize( size );
|
||||
return QVariant( name + " " + prettyFileSystem + " " + prettySize );
|
||||
}
|
||||
case SizeRole:
|
||||
|
27
src/modules/partition/core/SizeUtils.h
Normal file
27
src/modules/partition/core/SizeUtils.h
Normal file
@ -0,0 +1,27 @@
|
||||
/* === This file is part of Calamares - <https://calamares.io> ===
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2021 Adriaan de Groot <groot@kde.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* Calamares is Free Software: see the License-Identifier above.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PARTITION_CORE_SIZEUTILS_H
|
||||
#define PARTITION_CORE_SIZEUTILS_H
|
||||
|
||||
#include <kpmcore/util/capacity.h>
|
||||
|
||||
/** @brief Helper function for printing sizes consistently.
|
||||
*
|
||||
* Most of Calamares uses a qint64 for partition sizes, so use that
|
||||
* parameter type. However, the human-visible formatting doesn't need
|
||||
* to bother with one-byte accuracy (and anyway, a double has at least 50 bits
|
||||
* at which point we're printing giga (or gibi) bytes).
|
||||
*/
|
||||
static inline QString formatByteSize( qint64 sizeValue )
|
||||
{
|
||||
return Capacity::formatByteSize( static_cast< double >( sizeValue ) );
|
||||
}
|
||||
|
||||
#endif // PARTITION_CORE_SIZEUTILS_H
|
@ -68,7 +68,8 @@ DeviceInfoWidget::setPartitionTableType( PartitionTable::TableType type )
|
||||
void
|
||||
DeviceInfoWidget::retranslateUi()
|
||||
{
|
||||
QString typeString = PartitionTable::tableTypeToName( m_tableType ).toUpper();
|
||||
QString typeString;
|
||||
QString toolTipString;
|
||||
|
||||
// fix up if the name shouldn't be uppercase:
|
||||
switch ( m_tableType )
|
||||
@ -76,38 +77,32 @@ DeviceInfoWidget::retranslateUi()
|
||||
case PartitionTable::msdos:
|
||||
case PartitionTable::msdos_sectorbased:
|
||||
typeString = "MBR";
|
||||
toolTipString += tr( "<br><br>This partition table type is only advisable on older "
|
||||
"systems which start from a <strong>BIOS</strong> boot "
|
||||
"environment. GPT is recommended in most other cases.<br><br>"
|
||||
"<strong>Warning:</strong> the MBR partition table "
|
||||
"is an obsolete MS-DOS era standard.<br>"
|
||||
"Only 4 <em>primary</em> partitions may be created, and of "
|
||||
"those 4, one can be an <em>extended</em> partition, which "
|
||||
"may in turn contain many <em>logical</em> partitions." );
|
||||
break;
|
||||
case PartitionTable::gpt:
|
||||
// TypeString is ok
|
||||
toolTipString += tr( "<br><br>This is the recommended partition table type for modern "
|
||||
"systems which start from an <strong>EFI</strong> boot "
|
||||
"environment." );
|
||||
break;
|
||||
case PartitionTable::loop:
|
||||
typeString = "loop";
|
||||
break;
|
||||
case PartitionTable::mac:
|
||||
typeString = "Mac";
|
||||
break;
|
||||
case PartitionTable::amiga:
|
||||
typeString = "Amiga";
|
||||
break;
|
||||
case PartitionTable::sun:
|
||||
typeString = "Sun";
|
||||
break;
|
||||
case PartitionTable::unknownTableType:
|
||||
typeString = " ? ";
|
||||
}
|
||||
|
||||
|
||||
QString toolTipString = tr( "This device has a <strong>%1</strong> partition "
|
||||
"table." )
|
||||
.arg( typeString );
|
||||
|
||||
switch ( m_tableType )
|
||||
{
|
||||
case PartitionTable::loop:
|
||||
toolTipString = tr( "This is a <strong>loop</strong> "
|
||||
"device.<br><br>"
|
||||
"It is a pseudo-device with no partition table "
|
||||
"that makes a file accessible as a block device. "
|
||||
"This kind of setup usually only contains a single filesystem." );
|
||||
break;
|
||||
case PartitionTable::none:
|
||||
case PartitionTable::unknownTableType:
|
||||
typeString = " ? ";
|
||||
toolTipString = tr( "This installer <strong>cannot detect a partition table</strong> on the "
|
||||
"selected storage device.<br><br>"
|
||||
"The device either has no partition "
|
||||
@ -117,21 +112,35 @@ DeviceInfoWidget::retranslateUi()
|
||||
"either automatically, or through the manual partitioning "
|
||||
"page." );
|
||||
break;
|
||||
case PartitionTable::gpt:
|
||||
toolTipString += tr( "<br><br>This is the recommended partition table type for modern "
|
||||
"systems which start from an <strong>EFI</strong> boot "
|
||||
"environment." );
|
||||
// The next ones need to have the name adjusted, but the default tooltip is OK
|
||||
case PartitionTable::mac:
|
||||
typeString = "Mac";
|
||||
break;
|
||||
case PartitionTable::msdos:
|
||||
case PartitionTable::msdos_sectorbased:
|
||||
toolTipString += tr( "<br><br>This partition table type is only advisable on older "
|
||||
"systems which start from a <strong>BIOS</strong> boot "
|
||||
"environment. GPT is recommended in most other cases.<br><br>"
|
||||
"<strong>Warning:</strong> the MBR partition table "
|
||||
"is an obsolete MS-DOS era standard.<br>"
|
||||
"Only 4 <em>primary</em> partitions may be created, and of "
|
||||
"those 4, one can be an <em>extended</em> partition, which "
|
||||
"may in turn contain many <em>logical</em> partitions." );
|
||||
case PartitionTable::amiga:
|
||||
typeString = "Amiga";
|
||||
break;
|
||||
case PartitionTable::sun:
|
||||
typeString = "Sun";
|
||||
break;
|
||||
// Peculiar tables, do nothing and use default type and tooltip strings
|
||||
case PartitionTable::aix:
|
||||
case PartitionTable::bsd:
|
||||
case PartitionTable::dasd:
|
||||
case PartitionTable::dvh:
|
||||
case PartitionTable::pc98:
|
||||
case PartitionTable::vmd:
|
||||
break;
|
||||
}
|
||||
|
||||
if ( typeString.isEmpty() )
|
||||
{
|
||||
typeString = PartitionTable::tableTypeToName( m_tableType ).toUpper();
|
||||
}
|
||||
if ( toolTipString.isEmpty() )
|
||||
{
|
||||
toolTipString = tr( "This device has a <strong>%1</strong> partition "
|
||||
"table." )
|
||||
.arg( typeString );
|
||||
}
|
||||
|
||||
m_ptLabel->setText( typeString );
|
||||
|
@ -9,11 +9,10 @@
|
||||
|
||||
#include "ListPhysicalVolumeWidgetItem.h"
|
||||
|
||||
#include <kpmcore/util/capacity.h>
|
||||
#include "core/SizeUtils.h"
|
||||
|
||||
ListPhysicalVolumeWidgetItem::ListPhysicalVolumeWidgetItem( const Partition* partition, bool checked )
|
||||
: QListWidgetItem(
|
||||
QString( "%1 | %2" ).arg( partition->deviceNode(), Capacity::formatByteSize( partition->capacity() ) ) )
|
||||
: QListWidgetItem( QString( "%1 | %2" ).arg( partition->deviceNode(), formatByteSize( partition->capacity() ) ) )
|
||||
, m_partition( partition )
|
||||
{
|
||||
setToolTip( partition->deviceNode() );
|
||||
@ -26,3 +25,5 @@ ListPhysicalVolumeWidgetItem::partition() const
|
||||
{
|
||||
return m_partition;
|
||||
}
|
||||
|
||||
ListPhysicalVolumeWidgetItem::~ListPhysicalVolumeWidgetItem() {}
|
||||
|
@ -18,6 +18,7 @@ class ListPhysicalVolumeWidgetItem : public QListWidgetItem
|
||||
{
|
||||
public:
|
||||
ListPhysicalVolumeWidgetItem( const Partition* partition, bool checked );
|
||||
~ListPhysicalVolumeWidgetItem() override;
|
||||
|
||||
const Partition* partition() const;
|
||||
|
||||
|
@ -12,6 +12,7 @@
|
||||
|
||||
#include "core/ColorUtils.h"
|
||||
#include "core/PartitionModel.h"
|
||||
#include "core/SizeUtils.h"
|
||||
|
||||
#include "utils/CalamaresUtilsGui.h"
|
||||
#include "utils/Logger.h"
|
||||
@ -20,8 +21,6 @@
|
||||
#include <kpmcore/core/device.h>
|
||||
#include <kpmcore/fs/filesystem.h>
|
||||
|
||||
#include <KFormat>
|
||||
|
||||
// Qt
|
||||
#include <QGuiApplication>
|
||||
#include <QMouseEvent>
|
||||
@ -39,7 +38,7 @@ static QStringList
|
||||
buildUnknownDisklabelTexts( Device* dev )
|
||||
{
|
||||
QStringList texts = { QObject::tr( "Unpartitioned space or unknown partition table" ),
|
||||
KFormat().formatByteSize( dev->totalLogical() * dev->logicalSize() ) };
|
||||
formatByteSize( dev->totalLogical() * dev->logicalSize() ) };
|
||||
return texts;
|
||||
}
|
||||
|
||||
|
@ -212,7 +212,8 @@ ReplaceWidget::onPartitionSelected()
|
||||
}
|
||||
}
|
||||
|
||||
if ( partition->capacity() < requiredSpaceB )
|
||||
// The loss of precision is ok; we're not going to fall over from a single byte
|
||||
if ( static_cast< double >( partition->capacity() ) < requiredSpaceB )
|
||||
{
|
||||
updateStatus( CalamaresUtils::Fail,
|
||||
tr( "<strong>%4</strong><br/><br/>"
|
||||
|
@ -10,10 +10,9 @@
|
||||
#include "VolumeGroupBaseDialog.h"
|
||||
#include "ui_VolumeGroupBaseDialog.h"
|
||||
|
||||
#include "core/SizeUtils.h"
|
||||
#include "gui/ListPhysicalVolumeWidgetItem.h"
|
||||
|
||||
#include <kpmcore/util/capacity.h>
|
||||
|
||||
#include <QComboBox>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QLabel>
|
||||
@ -100,7 +99,7 @@ VolumeGroupBaseDialog::setUsedSizeValue( qint64 usedSize )
|
||||
{
|
||||
m_usedSizeValue = usedSize;
|
||||
|
||||
ui->usedSize->setText( Capacity::formatByteSize( m_usedSizeValue ) );
|
||||
ui->usedSize->setText( formatByteSize( m_usedSizeValue ) );
|
||||
}
|
||||
|
||||
void
|
||||
@ -121,7 +120,7 @@ VolumeGroupBaseDialog::updateTotalSize()
|
||||
% ( ui->peSize->value() * Capacity::unitFactor( Capacity::Unit::Byte, Capacity::Unit::MiB ) );
|
||||
}
|
||||
|
||||
ui->totalSize->setText( Capacity::formatByteSize( m_totalSizeValue ) );
|
||||
ui->totalSize->setText( formatByteSize( m_totalSizeValue ) );
|
||||
|
||||
updateTotalSectors();
|
||||
}
|
||||
|
@ -243,14 +243,8 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
#if ( QT_VERSION < QT_VERSION_CHECK( 5, 15, 0 ) )
|
||||
// TODO: 3.3 remove because newer Qt does support constness
|
||||
const char* m_message = nullptr;
|
||||
QString m_path;
|
||||
#else
|
||||
const char* const m_message = nullptr;
|
||||
QString const m_path;
|
||||
#endif
|
||||
};
|
||||
|
||||
STATICTEST inline QDebug&
|
||||
|
@ -60,24 +60,24 @@ createZfs( Partition* partition, Device* device )
|
||||
// Now we need to do some things that would normally be done by kpmcore
|
||||
|
||||
// First we get the device node from the output and set it as the partition path
|
||||
QRegularExpression re( QStringLiteral( "Created a new partition (\\d+)" ) );
|
||||
QRegularExpressionMatch rem = re.match( r.getOutput() );
|
||||
|
||||
QString deviceNode;
|
||||
if ( rem.hasMatch() )
|
||||
{
|
||||
if ( partition->devicePath().back().isDigit() )
|
||||
QRegularExpression re( QStringLiteral( "Created a new partition (\\d+)" ) );
|
||||
QRegularExpressionMatch rem = re.match( r.getOutput() );
|
||||
|
||||
if ( rem.hasMatch() )
|
||||
{
|
||||
deviceNode = partition->devicePath() + QLatin1Char( 'p' ) + rem.captured( 1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
deviceNode = partition->devicePath() + rem.captured( 1 );
|
||||
if ( partition->devicePath().back().isDigit() )
|
||||
{
|
||||
deviceNode = partition->devicePath() + QLatin1Char( 'p' ) + rem.captured( 1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
deviceNode = partition->devicePath() + rem.captured( 1 );
|
||||
}
|
||||
}
|
||||
partition->setPartitionPath( deviceNode );
|
||||
}
|
||||
|
||||
partition->setPartitionPath( deviceNode );
|
||||
|
||||
// If it is a gpt device, set the partition UUID
|
||||
if ( device->partitionTable()->type() == PartitionTable::gpt && partition->uuid().isEmpty() )
|
||||
{
|
||||
|
@ -61,6 +61,7 @@ calamares_add_test(
|
||||
SOURCES
|
||||
${PartitionModule_SOURCE_DIR}/jobs/AutoMountManagementJob.cpp
|
||||
AutoMountTests.cpp
|
||||
DEFINITIONS ${_partition_defs}
|
||||
)
|
||||
|
||||
calamares_add_test(
|
||||
@ -70,4 +71,5 @@ calamares_add_test(
|
||||
${PartitionModule_SOURCE_DIR}/core/DeviceList.cpp
|
||||
LIBRARIES
|
||||
kpmcore
|
||||
DEFINITIONS ${_partition_defs}
|
||||
)
|
||||
|
@ -19,6 +19,8 @@
|
||||
|
||||
#include <KMacroExpander>
|
||||
|
||||
#include <QCoreApplication>
|
||||
|
||||
#include <chrono>
|
||||
|
||||
|
||||
@ -37,7 +39,6 @@ namespace
|
||||
*/
|
||||
class TrackingInstallJob : public Calamares::Job
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
TrackingInstallJob( const QString& url );
|
||||
~TrackingInstallJob() override;
|
||||
@ -58,7 +59,6 @@ private:
|
||||
*/
|
||||
class TrackingMachineUpdateManagerJob : public Calamares::Job
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
~TrackingMachineUpdateManagerJob() override;
|
||||
|
||||
@ -75,7 +75,6 @@ public:
|
||||
*/
|
||||
class TrackingKUserFeedbackJob : public Calamares::Job
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
TrackingKUserFeedbackJob( const QString& username, const QStringList& areas );
|
||||
~TrackingKUserFeedbackJob() override;
|
||||
@ -99,13 +98,13 @@ TrackingInstallJob::~TrackingInstallJob() {}
|
||||
QString
|
||||
TrackingInstallJob::prettyName() const
|
||||
{
|
||||
return tr( "Installation feedback" );
|
||||
return QCoreApplication::translate( "TrackingInstallJob", "Installation feedback" );
|
||||
}
|
||||
|
||||
QString
|
||||
TrackingInstallJob::prettyStatusMessage() const
|
||||
{
|
||||
return tr( "Sending installation feedback." );
|
||||
return QCoreApplication::translate( "TrackingInstallJob", "Sending installation feedback." );
|
||||
}
|
||||
|
||||
Calamares::JobResult
|
||||
@ -122,8 +121,9 @@ TrackingInstallJob::exec()
|
||||
if ( result.status == RequestStatus::Timeout )
|
||||
{
|
||||
cWarning() << "install-tracking request timed out.";
|
||||
return Calamares::JobResult::error( tr( "Internal error in install-tracking." ),
|
||||
tr( "HTTP request timed out." ) );
|
||||
return Calamares::JobResult::error(
|
||||
QCoreApplication::translate( "TrackingInstallJob", "Internal error in install-tracking." ),
|
||||
QCoreApplication::translate( "TrackingInstallJob", "HTTP request timed out." ) );
|
||||
}
|
||||
return Calamares::JobResult::ok();
|
||||
}
|
||||
@ -133,13 +133,13 @@ TrackingMachineUpdateManagerJob::~TrackingMachineUpdateManagerJob() {}
|
||||
QString
|
||||
TrackingMachineUpdateManagerJob::prettyName() const
|
||||
{
|
||||
return tr( "Machine feedback" );
|
||||
return QCoreApplication::translate( "TrackingMachineUpdateManagerJob", "Machine feedback" );
|
||||
}
|
||||
|
||||
QString
|
||||
TrackingMachineUpdateManagerJob::prettyStatusMessage() const
|
||||
{
|
||||
return tr( "Configuring machine feedback." );
|
||||
return QCoreApplication::translate( "TrackingMachineUpdateManagerJob", "Configuring machine feedback." );
|
||||
}
|
||||
|
||||
Calamares::JobResult
|
||||
@ -162,14 +162,20 @@ TrackingMachineUpdateManagerJob::exec()
|
||||
else if ( r > 0 )
|
||||
{
|
||||
return Calamares::JobResult::error(
|
||||
tr( "Error in machine feedback configuration." ),
|
||||
tr( "Could not configure machine feedback correctly, script error %1." ).arg( r ) );
|
||||
QCoreApplication::translate( "TrackingMachineUpdateManagerJob",
|
||||
"Error in machine feedback configuration." ),
|
||||
QCoreApplication::translate( "TrackingMachineUpdateManagerJob",
|
||||
"Could not configure machine feedback correctly, script error %1." )
|
||||
.arg( r ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
return Calamares::JobResult::error(
|
||||
tr( "Error in machine feedback configuration." ),
|
||||
tr( "Could not configure machine feedback correctly, Calamares error %1." ).arg( r ) );
|
||||
QCoreApplication::translate( "TrackingMachineUpdateManagerJob",
|
||||
"Error in machine feedback configuration." ),
|
||||
QCoreApplication::translate( "TrackingMachineUpdateManagerJob",
|
||||
"Could not configure machine feedback correctly, Calamares error %1." )
|
||||
.arg( r ) );
|
||||
}
|
||||
}
|
||||
|
||||
@ -184,13 +190,13 @@ TrackingKUserFeedbackJob::~TrackingKUserFeedbackJob() {}
|
||||
QString
|
||||
TrackingKUserFeedbackJob::prettyName() const
|
||||
{
|
||||
return tr( "KDE user feedback" );
|
||||
return QCoreApplication::translate( "TrackingKUserFeedbackJob", "KDE user feedback" );
|
||||
}
|
||||
|
||||
QString
|
||||
TrackingKUserFeedbackJob::prettyStatusMessage() const
|
||||
{
|
||||
return tr( "Configuring KDE user feedback." );
|
||||
return QCoreApplication::translate( "TrackingKUserFeedbackJob", "Configuring KDE user feedback." );
|
||||
}
|
||||
|
||||
Calamares::JobResult
|
||||
@ -212,21 +218,25 @@ FeedbackLevel=16
|
||||
if ( r > 0 )
|
||||
{
|
||||
return Calamares::JobResult::error(
|
||||
tr( "Error in KDE user feedback configuration." ),
|
||||
tr( "Could not configure KDE user feedback correctly, script error %1." ).arg( r ) );
|
||||
QCoreApplication::translate( "TrackingKUserFeedbackJob", "Error in KDE user feedback configuration." ),
|
||||
QCoreApplication::translate( "TrackingKUserFeedbackJob",
|
||||
"Could not configure KDE user feedback correctly, script error %1." )
|
||||
.arg( r ) );
|
||||
}
|
||||
else if ( r < 0 )
|
||||
{
|
||||
return Calamares::JobResult::error(
|
||||
tr( "Error in KDE user feedback configuration." ),
|
||||
tr( "Could not configure KDE user feedback correctly, Calamares error %1." ).arg( r ) );
|
||||
QCoreApplication::translate( "TrackingKUserFeedbackJob", "Error in KDE user feedback configuration." ),
|
||||
QCoreApplication::translate( "TrackingKUserFeedbackJob",
|
||||
"Could not configure KDE user feedback correctly, Calamares error %1." )
|
||||
.arg( r ) );
|
||||
}
|
||||
}
|
||||
|
||||
return Calamares::JobResult::ok();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace
|
||||
|
||||
void
|
||||
addJob( Calamares::JobList& list, InstallTrackingConfig* config )
|
||||
@ -290,7 +300,3 @@ addJob( Calamares::JobList& list, UserTrackingConfig* config )
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#include "utils/moc-warnings.h"
|
||||
|
||||
#include "TrackingJobs.moc"
|
||||
|
Loading…
Reference in New Issue
Block a user