diff --git a/CHANGES b/CHANGES index 87ba91d6c..cb363364f 100644 --- a/CHANGES +++ b/CHANGES @@ -10,9 +10,17 @@ have been shuffled around, so third-party C++ modules will need adjustment to the changed names. This release contains contributions from (alphabetically by first name): + - Arnaud Ferraris + - Kevin Kofler ## Core ## + - All user-visible texts referring to "MB" and "GB" now use the standard + "MiB" and "GiB" wording, which matches what we were actually calculating + with (i.e. 2^20 and 2^30 respectively). #1129 + - The side-pane, which shows the list of steps that will be executed, + now tries to fit the text (name of each module) into the available space + by shrinking the font as needed. #1137 - *libcalamares* (accidentally) linked with Qt's GUI libraries when PythonQt was found. This led to the odd situation where the non-GUI Calamares library depends on a bunch of GUI libraries. @@ -24,6 +32,9 @@ This release contains contributions from (alphabetically by first name): ## Modules ## + - *finished* has a new mechanism for configuring the behavior of the + *restart now* button. The old-style boolean configuration is still + supported but generates a warning. #1138 - *locale* module GeoIP configuration has a new preferred format. See `locale.conf` for details. The old configuration is still supported but will be phased out before 3.3.0 -- in particular, @@ -31,7 +42,7 @@ This release contains contributions from (alphabetically by first name): crutch for the disappearance of one GeoIP provider in 2018. - *oemid* is a new module for configuring OEM phase-0 (image pre-mastering, or pre-deployment) things. It has limited functionality at the moment, - writing only a single batch-identifier file. + writing only a single batch-identifier file. #943 - All Python modules now bail out gracefully on (at least some) bad configurations, rather than raising an exception. The pre-release scripts now test for exceptions to avoid shipping modules with diff --git a/CMakeLists.txt b/CMakeLists.txt index 4be3d23ea..b8911645a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -116,7 +116,7 @@ set( _tx_bad be eo fa fr_CH gu kk kn lo mk ne_NP ur uz ) ### Required versions # # See DEPENDENCIES section below. -set( QT_VERSION 5.10.0 ) +set( QT_VERSION 5.9.0 ) set( YAMLCPP_VERSION 0.5.1 ) set( ECM_VERSION 5.18 ) set( PYTHONLIBS_VERSION 3.3 ) diff --git a/CMakeModules/BoostPython3.cmake b/CMakeModules/BoostPython3.cmake index c128b58f1..70fb0aa49 100644 --- a/CMakeModules/BoostPython3.cmake +++ b/CMakeModules/BoostPython3.cmake @@ -15,6 +15,11 @@ # libboost_python-3.4.so # depending on what python's targets you selected during install # +# On Fedora >= 30 instead, the boost-python3-devel provides boost library with a +# name like: +# libboost_python37.so +# depending on what python's targets you selected during install +# # find_boost_python3() tries to find the package with different component # names. By default it tries "python3", "python-py$suffix" and # "python-$dotsuffix", where suffix is based on the `python_version` argument. @@ -46,6 +51,10 @@ macro( find_boost_python3 boost_version python_version found_var ) string( REGEX REPLACE "([0-9]+)\\.([0-9]+)\\..*" "\\1\\2" _fbp_python_short_version ${python_version} ) _find_boost_python3_int( ${boost_version} python-py${_fbp_python_short_version} _fbp_found ) + if (NOT _fbp_found) + _find_boost_python3_int( ${boost_version} python${_fbp_python_short_version} _fbp_found ) + endif() + if (NOT _fbp_found) # The following loop changes the searched name for Gentoo based distributions # turns "3.4.123abc" into "3.4" diff --git a/data/config-appimage/modules/finished.conf b/data/config-appimage/modules/finished.conf index 29e5e49b4..48bbdc031 100644 --- a/data/config-appimage/modules/finished.conf +++ b/data/config-appimage/modules/finished.conf @@ -1,14 +1,24 @@ # Configuration for the "finished" page, which is usually shown only at # the end of the installation (successful or not). --- -# The finished page can hold a "restart system now" checkbox. -# If this is false, no checkbox is shown and the system is not restarted -# when Calamares exits. -restartNowEnabled: true - -# Initial state of the checkbox "restart now". Only relevant when the -# checkbox is shown by restartNowEnabled. -restartNowChecked: false +# Behavior of the "restart system now" button. +# +# There are four usable values: +# - never +# Does not show the button and does not restart. +# This matches the old behavior with restartNowEnabled=false. +# - user-unchecked +# Shows the button, defaults to unchecked, restarts if it is checked. +# This matches the old behavior with restartNowEnabled=true and restartNowChecked=false. +# - user-checked +# Shows the button, defaults to checked, restarts if it is checked. +# This matches the old behavior with restartNowEnabled=true and restartNowChecked=true. +# - always +# Shows the button, checked, but the user cannot change it. +# This is new behavior. +# +# The three combinations of legacy values are still supported. +restartNowMode: user-unchecked # If the checkbox is shown, and the checkbox is checked, then when # Calamares exits from the finished-page it will run this command. diff --git a/lang/calamares_ast.ts b/lang/calamares_ast.ts index e369cfa29..d408b8ed3 100644 --- a/lang/calamares_ast.ts +++ b/lang/calamares_ast.ts @@ -200,7 +200,7 @@ System-requirements checking is complete. - Completóse la comprobación de los requirimientos del sistema + Completóse la comprobación de los requirimientos del sistema. @@ -282,12 +282,12 @@ Setup is complete. Close the setup program. - + Completóse la configuración. Zarra'l programa de configuración. Cancel setup? - + ¿Encaboxar la configuración? @@ -1102,12 +1102,12 @@ L'instalador va colar y van perdese tolos cambeos. <h1>All done.</h1><br/>%1 has been set up on your computer.<br/>You may now start using your new system. - + <h1>Too fecho.</h1><br/>%1 configuróse nel ordenador.<br/>Agora pues usar el sistema nuevu. <html><head/><body><p>When this box is checked, your system will restart immediately when you click on <span style="font-style:italic;">Done</span> or close the setup program.</p></body></html> - + <html><head/><body><p>Cuando se conseña esti caxellu, el sistema va reaniciase nel intre cuando calques en <span style="font-style:italic;">Fecho</span> o zarres el programa de configuración.</p></body></html> @@ -1117,12 +1117,12 @@ L'instalador va colar y van perdese tolos cambeos. <html><head/><body><p>When this box is checked, your system will restart immediately when you click on <span style="font-style:italic;">Done</span> or close the installer.</p></body></html> - + <html><head/><body><p>Cuando se conseña esti caxellu, el sistema va reaniciase nel intre cuando calques en <span style="font-style:italic;">Fecho</span> o zarres l'instalador.</p></body></html> <h1>Setup Failed</h1><br/>%1 has not been set up on your computer.<br/>The error message was: %2. - + <h1>Falló la configuración</h1><br/>%1 nun se configuró nel ordenador.<br/>El mensaxe de fallu foi: %2. @@ -1226,7 +1226,7 @@ L'instalador va colar y van perdese tolos cambeos. The setup program is not running with administrator rights. - + El programa de configuración nun ta executándose con drechos alministrativos. diff --git a/lang/calamares_ja.ts b/lang/calamares_ja.ts index cc45e4a1e..2503989be 100644 --- a/lang/calamares_ja.ts +++ b/lang/calamares_ja.ts @@ -115,7 +115,7 @@ Job failed (%1) - + ジョブに失敗 (%1) @@ -136,7 +136,7 @@ Example job (%1) - + ジョブの例 (%1) @@ -200,7 +200,7 @@ System-requirements checking is complete. - + 要求されるシステムの確認を終了しました。 @@ -226,7 +226,7 @@ Cancel setup without changing the system. - + システムを変更することなくセットアップを中断します。 @@ -237,7 +237,7 @@ Setup Failed - + セットアップに失敗しました。 @@ -257,22 +257,22 @@ Continue with installation? - + インストールを続行しますか? The %1 setup program is about to make changes to your disk in order to set up %2.<br/><strong>You will not be able to undo these changes.</strong> - + %1 のセットアッププログラムは %2 のセットアップのためディスクの内容を変更します。<br/><strong>これらの変更は取り消しできません。</strong> &Set up now - + セットアップ中(&S) &Set up - + セットアップ (&S) @@ -282,12 +282,12 @@ Setup is complete. Close the setup program. - + セットアップが完了しました。プログラムを閉じます。 Cancel setup? - + セットアップを中止しますか? @@ -298,7 +298,8 @@ Do you really want to cancel the current setup process? The setup program will quit and all changes will be lost. - + 本当に現在のセットアップのプロセルを中止しますか? +すべての変更が取り消されます。 @@ -391,7 +392,7 @@ The installer will quit and all changes will be lost. %1 Setup Program - + %1 セットアッププログラム @@ -815,7 +816,7 @@ The installer will quit and all changes will be lost. Create Volume Group - + ボリュームグループの作成 @@ -1091,7 +1092,7 @@ The installer will quit and all changes will be lost. <Restart checkbox tooltip> - + <Restart checkbox tooltip> @@ -1101,12 +1102,12 @@ The installer will quit and all changes will be lost. <h1>All done.</h1><br/>%1 has been set up on your computer.<br/>You may now start using your new system. - + <h1>すべて完了しました。</h1><br/>%1 はコンピュータにセットアップされました。<br/>今から新しいシステムを開始することができます。 <html><head/><body><p>When this box is checked, your system will restart immediately when you click on <span style="font-style:italic;">Done</span> or close the setup program.</p></body></html> - + <html><head/><body><p>このボックスをチェックすると、 <span style="font-style:italic;">実行</span>をクリックするかプログラムを閉じると直ちにシステムが再起動します。</p></body></html> @@ -1116,12 +1117,12 @@ The installer will quit and all changes will be lost. <html><head/><body><p>When this box is checked, your system will restart immediately when you click on <span style="font-style:italic;">Done</span> or close the installer.</p></body></html> - + <html><head/><body><p>このボックスをチェックすると、 <span style="font-style:italic;">実行</span>をクリックするかインストーラーを閉じると直ちにシステムが再起動します。</p></body></html> <h1>Setup Failed</h1><br/>%1 has not been set up on your computer.<br/>The error message was: %2. - + <h1>セットアップに失敗しました。</h1><br/>%1 はコンピュータにセットアップされていません。<br/>エラーメッセージは次のとおりです: %2 @@ -1139,7 +1140,7 @@ The installer will quit and all changes will be lost. Setup Complete - + セットアップが完了しました @@ -1150,7 +1151,7 @@ The installer will quit and all changes will be lost. The setup of %1 is complete. - + %1 のセットアップが完了しました。 @@ -1226,7 +1227,7 @@ The installer will quit and all changes will be lost. The setup program is not running with administrator rights. - + セットアッププログラムは管理者権限で実行されていません。 @@ -2952,7 +2953,7 @@ Output: Create Volume Group - + ボリュームグループの作成 diff --git a/lang/calamares_pt_PT.ts b/lang/calamares_pt_PT.ts index 3a7bff63f..8f8ca6e4f 100644 --- a/lang/calamares_pt_PT.ts +++ b/lang/calamares_pt_PT.ts @@ -226,7 +226,7 @@ Cancel setup without changing the system. - + Cancelar instalação sem alterar o sistema. @@ -237,7 +237,7 @@ Setup Failed - + Falha de Instalação @@ -267,12 +267,12 @@ &Set up now - + &Instalar agora &Set up - + &Instalar @@ -282,12 +282,12 @@ Setup is complete. Close the setup program. - + Instalação completa. Feche o programa de instalação. Cancel setup? - + Cancelar instalação? @@ -298,7 +298,8 @@ Do you really want to cancel the current setup process? The setup program will quit and all changes will be lost. - + Quer mesmo cancelar o processo de instalação atual? +O programa de instalação irá fechar todas as alterações serão perdidas. @@ -391,7 +392,7 @@ O instalador será encerrado e todas as alterações serão perdidas. %1 Setup Program - + %1 Programa de Instalação @@ -1091,7 +1092,7 @@ O instalador será encerrado e todas as alterações serão perdidas. <Restart checkbox tooltip> - + <Restart checkbox tooltip> @@ -1139,7 +1140,7 @@ O instalador será encerrado e todas as alterações serão perdidas. Setup Complete - + Instalação Completa @@ -1149,7 +1150,7 @@ O instalador será encerrado e todas as alterações serão perdidas. The setup of %1 is complete. - + A instalação de %1 está completa. @@ -1225,7 +1226,7 @@ O instalador será encerrado e todas as alterações serão perdidas. The setup program is not running with administrator rights. - + O programa de instalação está agora a correr com direitos de administrador. @@ -1235,7 +1236,7 @@ O instalador será encerrado e todas as alterações serão perdidas. The screen is too small to display the setup program. - + O ecrã é demasiado pequeno para mostrar o programa de instalação. @@ -1391,32 +1392,32 @@ O instalador será encerrado e todas as alterações serão perdidas. Shows the complete license text - + Mostra ao texto completo da licença Hide license text - + Esconder texto da licença Show license agreement - + Mostrar acordo da licença Hide license agreement - + Esconder acordo da licença Opens the license agreement in a browser window. - + Abre o acordo da licença numa janela do navegador. <a href="%1">View license agreement</a> - + <a href="%1">Ver acordo da licença</a> @@ -3020,7 +3021,7 @@ Saída de Dados: Select language - + Selecione o idioma @@ -3045,17 +3046,17 @@ Saída de Dados: <h1>Welcome to the Calamares setup program for %1.</h1> - + <h1>Bem vindo ao programa de instalação Calamares para %1.</h1> <h1>Welcome to %1 setup.</h1> - + <h1>Bem vindo à instalação de %1.</h1> About %1 setup - + Sobre a instalação de %1 diff --git a/lang/python/ast/LC_MESSAGES/python.mo b/lang/python/ast/LC_MESSAGES/python.mo index 0d64ad280..5c04defa8 100644 Binary files a/lang/python/ast/LC_MESSAGES/python.mo and b/lang/python/ast/LC_MESSAGES/python.mo differ diff --git a/lang/python/ast/LC_MESSAGES/python.po b/lang/python/ast/LC_MESSAGES/python.po index 95b8c48ef..78e690185 100644 --- a/lang/python/ast/LC_MESSAGES/python.po +++ b/lang/python/ast/LC_MESSAGES/python.po @@ -182,7 +182,7 @@ msgstr "La configuración del xestor de pantalles nun se completó" #: src/modules/initcpiocfg/main.py:36 msgid "Configuring mkinitcpio." -msgstr "" +msgstr "Configurando mkinitcpio." #: src/modules/initcpio/main.py:33 msgid "Creating initramfs with mkinitcpio." @@ -190,7 +190,7 @@ msgstr "" #: src/modules/luksopenswaphookcfg/main.py:35 msgid "Configuring encrypted swap." -msgstr "" +msgstr "Configurando l'intercambéu cifráu." #: src/modules/rawfs/main.py:35 msgid "Installing data." @@ -289,11 +289,11 @@ msgstr "" #: src/modules/initramfs/main.py:50 src/modules/dracut/main.py:59 msgid "The exit code was {}" -msgstr "" +msgstr "El códigu de salida foi {}" #: src/modules/hwclock/main.py:35 msgid "Setting hardware clock." -msgstr "" +msgstr "Configurando'l reló de hardware." #: src/modules/dracut/main.py:36 msgid "Creating initramfs with dracut." @@ -337,7 +337,7 @@ msgstr "Pasu maniquín {} en Python" #: src/modules/localecfg/main.py:37 msgid "Configuring locales." -msgstr "" +msgstr "Configurando locales." #: src/modules/networkcfg/main.py:37 msgid "Saving network configuration." diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c29a866d8..b73fecda0 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -3,15 +3,6 @@ include( CalamaresAddModuleSubdirectory ) include( CalamaresAddLibrary ) include( CalamaresAddBrandingSubdirectory ) -include_directories( - ${CMAKE_CURRENT_LIST_DIR} - ${CMAKE_CURRENT_LIST_DIR}/libcalamares - ${CMAKE_CURRENT_LIST_DIR}/libcalamaresui - ${CMAKE_CURRENT_BINARY_DIR} - ${CMAKE_CURRENT_BINARY_DIR}/libcalamares - ${CMAKE_CURRENT_BINARY_DIR}/libcalamaresui -) - # library add_subdirectory( libcalamares ) diff --git a/src/calamares/CalamaresApplication.h b/src/calamares/CalamaresApplication.h index f9c919aa6..9f53726ae 100644 --- a/src/calamares/CalamaresApplication.h +++ b/src/calamares/CalamaresApplication.h @@ -1,7 +1,7 @@ /* === This file is part of Calamares - === * * Copyright 2014-2015, Teo Mrnjavac - * Copyright 2018, Adriaan de Groot + * Copyright 2018-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 @@ -20,12 +20,8 @@ #ifndef CALAMARESAPPLICATION_H #define CALAMARESAPPLICATION_H -#include "Typedefs.h" - #include -#define APP CalamaresApplication::instance() - class CalamaresWindow; namespace Calamares diff --git a/src/calamares/progresstree/ProgressTreeDelegate.cpp b/src/calamares/progresstree/ProgressTreeDelegate.cpp index 9c6a400f6..67dfeebda 100644 --- a/src/calamares/progresstree/ProgressTreeDelegate.cpp +++ b/src/calamares/progresstree/ProgressTreeDelegate.cpp @@ -1,7 +1,7 @@ /* === This file is part of Calamares - === * * Copyright 2014-2015, Teo Mrnjavac - * Copyright 2017, Adriaan de Groot + * Copyright 2017, 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 @@ -18,28 +18,18 @@ */ #include "ProgressTreeDelegate.h" +#include "ProgressTreeModel.h" #include "Branding.h" #include "CalamaresApplication.h" #include "CalamaresWindow.h" -#include "ProgressTreeModel.h" -#include "ViewManager.h" -#include "ViewStepItem.h" #include "utils/CalamaresUtilsGui.h" -#include #include -#define ITEM_MARGIN 12 -#define VS_FONTSIZE CalamaresUtils::defaultFontSize() + 4 - -ProgressTreeDelegate::ProgressTreeDelegate( QAbstractItemView* parent ) - : QStyledItemDelegate( parent ) - , m_parent( parent ) -{ -} - +static constexpr int const item_margin = 8; +static inline int item_fontsize() { return CalamaresUtils::defaultFontSize() + 4; } QSize ProgressTreeDelegate::sizeHint( const QStyleOptionViewItem& option, @@ -50,11 +40,11 @@ ProgressTreeDelegate::sizeHint( const QStyleOptionViewItem& option, QFont font = qApp->font(); - font.setPointSize( VS_FONTSIZE ); + font.setPointSize( item_fontsize() ); QFontMetrics fm( font ); int height = fm.height(); - height += 2*ITEM_MARGIN; //margin + height += 2 * item_margin; return QSize( option.rect.width(), height ); } @@ -88,12 +78,9 @@ ProgressTreeDelegate::paintViewStep( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const { - QRect textRect = option.rect.adjusted( ITEM_MARGIN, - ITEM_MARGIN, - ITEM_MARGIN, - ITEM_MARGIN ); + QRect textRect = option.rect.adjusted( item_margin, item_margin, -item_margin, -item_margin ); QFont font = qApp->font(); - font.setPointSize( VS_FONTSIZE ); + font.setPointSize( item_fontsize() ); font.setBold( false ); painter->setFont( font ); @@ -107,11 +94,37 @@ ProgressTreeDelegate::paintViewStep( QPainter* painter, QString textHighlight = Calamares::Branding::instance()-> styleString( Calamares::Branding::SidebarTextHighlight ); if ( textHighlight.isEmpty() ) - painter->setBrush( APP->mainWindow()->palette().background() ); + painter->setBrush( CalamaresApplication::instance()->mainWindow()->palette().background() ); else painter->setBrush( QColor( textHighlight ) ); } - painter->fillRect( option.rect, painter->brush().color() ); - painter->drawText( textRect, index.data().toString() ); + + // Draw the text at least once. If it doesn't fit, then shrink the font + // being used by 1 pt on each iteration, up to a maximum of maximumShrink + // times. On each loop, we'll have to blank out the rectangle again, so this + // is an expensive (in terms of drawing operations) thing to do. + // + // (The loop uses <= because the counter is incremented at the start). + static constexpr int const maximumShrink = 4; + int shrinkSteps = 0; + do + { + painter->fillRect( option.rect, painter->brush().color() ); + shrinkSteps++; + + QRectF boundingBox; + painter->drawText( textRect, Qt::AlignHCenter | Qt::AlignVCenter | Qt::TextSingleLine, index.data().toString(), &boundingBox ); + + // The extra check here is to avoid the changing-font-size if we're not going to use + // it in the next iteration of the loop anyway. + if ( ( shrinkSteps <= maximumShrink ) && (boundingBox.width() > textRect.width() ) ) + { + font.setPointSize( item_fontsize() - shrinkSteps ); + painter->setFont( font ); + } + else + break; // It fits + } + while ( shrinkSteps <= maximumShrink ); } diff --git a/src/calamares/progresstree/ProgressTreeDelegate.h b/src/calamares/progresstree/ProgressTreeDelegate.h index 371f5193f..83b281696 100644 --- a/src/calamares/progresstree/ProgressTreeDelegate.h +++ b/src/calamares/progresstree/ProgressTreeDelegate.h @@ -1,6 +1,7 @@ /* === This file is part of Calamares - === * * Copyright 2014-2015, Teo Mrnjavac + * 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 @@ -21,7 +22,6 @@ #include - /** * @brief The ProgressTreeDelegate class customizes the look and feel of the * ProgressTreeView elements. @@ -29,9 +29,8 @@ */ class ProgressTreeDelegate : public QStyledItemDelegate { - Q_OBJECT public: - explicit ProgressTreeDelegate( QAbstractItemView* parent = nullptr ); + using QStyledItemDelegate::QStyledItemDelegate; protected: QSize sizeHint( const QStyleOptionViewItem& option, @@ -44,8 +43,6 @@ private: void paintViewStep( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const; - - QAbstractItemView* m_parent; }; #endif // PROGRESSTREEDELEGATE_H diff --git a/src/libcalamares/CMakeLists.txt b/src/libcalamares/CMakeLists.txt index 2173c825c..585ab7b6b 100644 --- a/src/libcalamares/CMakeLists.txt +++ b/src/libcalamares/CMakeLists.txt @@ -1,3 +1,6 @@ +# libcalamares is the non-GUI part of Calamares, which includes handling +# translations, configurations, logging, utilities, global storage, and (non-GUI) jobs. + add_definitions( ${QT_DEFINITIONS} -DQT_SHARED @@ -10,6 +13,8 @@ configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/CalamaresConfig.h.in configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/../calamares/CalamaresVersion.h.in ${CMAKE_CURRENT_BINARY_DIR}/CalamaresVersion.h ) +set( OPTIONAL_PRIVATE_LIBRARIES "" ) + set( libSources CppJob.cpp GlobalStorage.cpp @@ -18,8 +23,19 @@ set( libSources JobQueue.cpp ProcessJob.cpp Settings.cpp -) -set( utilsSources + + # GeoIP services + geoip/Interface.cpp + geoip/GeoIPJSON.cpp + geoip/Handler.cpp + + # Locale-data service + locale/Lookup.cpp + + # Partition service + partition/PartitionSize.cpp + + # Utility service utils/CalamaresUtilsSystem.cpp utils/CommandList.cpp utils/Dirs.cpp @@ -45,9 +61,11 @@ include_directories( ${YAMLCPP_INCLUDE_DIR} ) +### OPTIONAL Python support +# +# if( WITH_PYTHON ) - set( libSources - ${libSources} + list( APPEND libSources PythonHelper.cpp PythonJob.cpp PythonJobApi.cpp @@ -62,27 +80,25 @@ if( WITH_PYTHON ) include_directories(${Boost_INCLUDE_DIRS}) link_directories(${Boost_LIBRARY_DIRS}) - set( OPTIONAL_PRIVATE_LIBRARIES - ${OPTIONAL_PRIVATE_LIBRARIES} + list( APPEND OPTIONAL_PRIVATE_LIBRARIES ${PYTHON_LIBRARIES} ${Boost_LIBRARIES} ) endif() -set( geoipSources - geoip/Interface.cpp - geoip/Handler.cpp -) -set( geoipImplementations geoip/GeoIPJSON.cpp ) -set( geoip_libs ) - +### OPTIONAL GeoIP XML support +# +# find_package(Qt5 COMPONENTS Xml) if( Qt5Xml_FOUND ) - list( APPEND geoipImplementations geoip/GeoIPXML.cpp ) - list( APPEND geoip_libs Qt5::Network Qt5::Xml ) + list( APPEND libSources geoip/GeoIPXML.cpp ) + list( APPEND OPTIONAL_PRIVATE_LIBRARIES Qt5::Network Qt5::Xml ) endif() -add_library( calamares SHARED ${libSources} ${kdsagSources} ${utilsSources} ${geoipSources} ${geoipImplementations} ) +### LIBRARY +# +# +add_library( calamares SHARED ${libSources} ${kdsagSources} ) set_target_properties( calamares PROPERTIES VERSION ${CALAMARES_VERSION_SHORT} @@ -95,7 +111,6 @@ target_link_libraries( calamares ${OPTIONAL_PRIVATE_LIBRARIES} LINK_PUBLIC ${YAMLCPP_LIBRARY} - ${geoip_libs} Qt5::Core ) @@ -106,6 +121,26 @@ install( TARGETS calamares ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} ) +# Make symlink lib/calamares/libcalamares.so to lib/libcalamares.so.VERSION so +# lib/calamares can be used as module path for the Python interpreter. +install( CODE " + file( MAKE_DIRECTORY \"\$ENV{DESTDIR}/${CMAKE_INSTALL_FULL_LIBDIR}/calamares\" ) + execute_process( COMMAND \"${CMAKE_COMMAND}\" -E create_symlink ../libcalamares.so.${CALAMARES_VERSION_SHORT} libcalamares.so WORKING_DIRECTORY \"\$ENV{DESTDIR}/${CMAKE_INSTALL_FULL_LIBDIR}/calamares\" ) +") + +# Install header files +file( GLOB rootHeaders "*.h" ) +file( GLOB kdsingleapplicationguardHeaders "kdsingleapplicationguard/*.h" ) +file( GLOB utilsHeaders "utils/*.h" ) + +install( FILES ${CMAKE_CURRENT_BINARY_DIR}/CalamaresConfig.h DESTINATION include/libcalamares ) +install( FILES ${rootHeaders} DESTINATION include/libcalamares ) +install( FILES ${kdsingleapplicationguardHeaders} DESTINATION include/libcalamares/kdsingleapplicationguard ) +install( FILES ${utilsHeaders} DESTINATION include/libcalamares/utils ) + +### TESTING +# +# if ( ECM_FOUND AND BUILD_TESTING ) ecm_add_test( Tests.cpp @@ -136,20 +171,3 @@ if( BUILD_TESTING ) target_link_libraries( test_geoip calamares Qt5::Network ${YAMLCPP_LIBRARY} ) calamares_automoc( test_geoip ) endif() - -# Make symlink lib/calamares/libcalamares.so to lib/libcalamares.so.VERSION so -# lib/calamares can be used as module path for the Python interpreter. -install( CODE " - file( MAKE_DIRECTORY \"\$ENV{DESTDIR}/${CMAKE_INSTALL_FULL_LIBDIR}/calamares\" ) - execute_process( COMMAND \"${CMAKE_COMMAND}\" -E create_symlink ../libcalamares.so.${CALAMARES_VERSION_SHORT} libcalamares.so WORKING_DIRECTORY \"\$ENV{DESTDIR}/${CMAKE_INSTALL_FULL_LIBDIR}/calamares\" ) -") - -# Install header files -file( GLOB rootHeaders "*.h" ) -file( GLOB kdsingleapplicationguardHeaders "kdsingleapplicationguard/*.h" ) -file( GLOB utilsHeaders "utils/*.h" ) - -install( FILES ${CMAKE_CURRENT_BINARY_DIR}/CalamaresConfig.h DESTINATION include/libcalamares ) -install( FILES ${rootHeaders} DESTINATION include/libcalamares ) -install( FILES ${kdsingleapplicationguardHeaders} DESTINATION include/libcalamares/kdsingleapplicationguard ) -install( FILES ${utilsHeaders} DESTINATION include/libcalamares/utils ) diff --git a/src/libcalamares/CppJob.h b/src/libcalamares/CppJob.h index d2f5c0f79..36116b3e7 100644 --- a/src/libcalamares/CppJob.h +++ b/src/libcalamares/CppJob.h @@ -24,7 +24,6 @@ #include #include "DllMacro.h" -#include "Typedefs.h" #include "Job.h" namespace Calamares diff --git a/src/libcalamares/Job.h b/src/libcalamares/Job.h index 04b4560a4..f590ef0ee 100644 --- a/src/libcalamares/Job.h +++ b/src/libcalamares/Job.h @@ -20,9 +20,10 @@ #define CALAMARES_JOB_H #include "DllMacro.h" -#include "Typedefs.h" +#include #include +#include namespace Calamares { @@ -40,7 +41,8 @@ public: { NoError = 0, GenericError = -1, - PythonUncaughtException = 1 + PythonUncaughtException = 1, + InvalidConfiguration = 2 } ; JobResult( const JobResult& rhs ) = delete; @@ -96,6 +98,9 @@ private: bool m_emergency = false; }; +using job_ptr = QSharedPointer< Job >; +using JobList = QList< job_ptr >; + } // namespace Calamares #endif // CALAMARES_JOB_H diff --git a/src/libcalamares/JobQueue.h b/src/libcalamares/JobQueue.h index 5273e0043..4e5dffe8a 100644 --- a/src/libcalamares/JobQueue.h +++ b/src/libcalamares/JobQueue.h @@ -20,7 +20,7 @@ #define CALAMARES_JOBQUEUE_H #include "DllMacro.h" -#include "Typedefs.h" +#include "Job.h" #include diff --git a/src/libcalamares/Settings.cpp b/src/libcalamares/Settings.cpp index 0b12d87fb..0089b2ef2 100644 --- a/src/libcalamares/Settings.cpp +++ b/src/libcalamares/Settings.cpp @@ -21,7 +21,6 @@ #include "Settings.h" -// #include "utils/CalamaresUtils.h" #include "utils/Dirs.h" #include "utils/Logger.h" #include "utils/Yaml.h" diff --git a/src/libcalamares/Settings.h b/src/libcalamares/Settings.h index da3f46921..ca77859c3 100644 --- a/src/libcalamares/Settings.h +++ b/src/libcalamares/Settings.h @@ -22,8 +22,8 @@ #ifndef SETTINGS_H #define SETTINGS_H -#include "UiDllMacro.h" -#include "Typedefs.h" +#include "DllMacro.h" +#include "modulesystem/Actions.h" #include #include @@ -32,7 +32,7 @@ namespace Calamares { -class UIDLLEXPORT Settings : public QObject +class DLLEXPORT Settings : public QObject { Q_OBJECT public: @@ -41,7 +41,6 @@ public: QObject* parent = nullptr ); static Settings* instance(); - //TODO: load from YAML then emit ready QStringList modulesSearchPaths() const; @@ -63,9 +62,6 @@ public: * * This influences user-visible strings, for instance using the * word "setup" instead of "install" where relevant. - * - * NOTE: it's a synonym for !doChroot() for now, but may become - * an independent setting. */ bool isSetupMode() const { return m_isSetupMode; } diff --git a/src/libcalamares/locale/CountryData_p.cpp b/src/libcalamares/locale/CountryData_p.cpp new file mode 100644 index 000000000..a6e9b3a95 --- /dev/null +++ b/src/libcalamares/locale/CountryData_p.cpp @@ -0,0 +1,235 @@ +/* GENERATED FILE DO NOT EDIT +* +* === This file is part of Calamares - === +* +* This file is derived from CLDR data from Unicode, Inc. Applicable terms: +* +* A. Unicode Copyright +* 1. Copyright © 1991-2019 Unicode, Inc. All rights reserved. +* B. Definitions +* Unicode Data Files ("DATA FILES") include all data files under the directories: +* https://www.unicode.org/Public/ +* C. Terms of Use +* 2. Any person is hereby authorized, without fee, to view, use, reproduce, +* and distribute all documents and files, subject to the Terms and +* Conditions herein. +*/ + +// BEGIN Generated from CLDR data + + +struct CountryData +{ + QLocale::Language l; + QLocale::Country c; + char cc1; + char cc2; +}; + +static constexpr int const country_data_size = 198; + +static const CountryData country_data_table[] = { +{ QLocale::Language::Catalan, QLocale::Country::Andorra, 'A', 'D' }, +{ QLocale::Language::Arabic, QLocale::Country::UnitedArabEmirates, 'A', 'E' }, +{ QLocale::Language::Persian, QLocale::Country::Afghanistan, 'A', 'F' }, +{ QLocale::Language::Albanian, QLocale::Country::Albania, 'A', 'L' }, +{ QLocale::Language::Armenian, QLocale::Country::Armenia, 'A', 'M' }, +{ QLocale::Language::Portuguese, QLocale::Country::Angola, 'A', 'O' }, +{ QLocale::Language::AnyLanguage, QLocale::Country::Antarctica, 'A', 'Q' }, +{ QLocale::Language::Spanish, QLocale::Country::Argentina, 'A', 'R' }, +{ QLocale::Language::Samoan, QLocale::Country::AmericanSamoa, 'A', 'S' }, +{ QLocale::Language::German, QLocale::Country::Austria, 'A', 'T' }, +{ QLocale::Language::Dutch, QLocale::Country::Aruba, 'A', 'W' }, +{ QLocale::Language::Swedish, QLocale::Country::AlandIslands, 'A', 'X' }, +{ QLocale::Language::Azerbaijani, QLocale::Country::Azerbaijan, 'A', 'Z' }, +{ QLocale::Language::Bosnian, QLocale::Country::BosniaAndHerzegowina, 'B', 'A' }, +{ QLocale::Language::Bengali, QLocale::Country::Bangladesh, 'B', 'D' }, +{ QLocale::Language::Dutch, QLocale::Country::Belgium, 'B', 'E' }, +{ QLocale::Language::French, QLocale::Country::BurkinaFaso, 'B', 'F' }, +{ QLocale::Language::Bulgarian, QLocale::Country::Bulgaria, 'B', 'G' }, +{ QLocale::Language::Arabic, QLocale::Country::Bahrain, 'B', 'H' }, +{ QLocale::Language::Rundi, QLocale::Country::Burundi, 'B', 'I' }, +{ QLocale::Language::French, QLocale::Country::Benin, 'B', 'J' }, +{ QLocale::Language::French, QLocale::Country::SaintBarthelemy, 'B', 'L' }, +{ QLocale::Language::Malay, QLocale::Country::Brunei, 'B', 'N' }, +{ QLocale::Language::Spanish, QLocale::Country::Bolivia, 'B', 'O' }, +{ QLocale::Language::Papiamento, QLocale::Country::Bonaire, 'B', 'Q' }, +{ QLocale::Language::Portuguese, QLocale::Country::Brazil, 'B', 'R' }, +{ QLocale::Language::Dzongkha, QLocale::Country::Bhutan, 'B', 'T' }, +{ QLocale::Language::AnyLanguage, QLocale::Country::BouvetIsland, 'B', 'V' }, +{ QLocale::Language::Belarusian, QLocale::Country::Belarus, 'B', 'Y' }, +{ QLocale::Language::Swahili, QLocale::Country::CongoKinshasa, 'C', 'D' }, +{ QLocale::Language::French, QLocale::Country::CentralAfricanRepublic, 'C', 'F' }, +{ QLocale::Language::French, QLocale::Country::CongoBrazzaville, 'C', 'G' }, +{ QLocale::Language::German, QLocale::Country::Switzerland, 'C', 'H' }, +{ QLocale::Language::French, QLocale::Country::IvoryCoast, 'C', 'I' }, +{ QLocale::Language::Spanish, QLocale::Country::Chile, 'C', 'L' }, +{ QLocale::Language::French, QLocale::Country::Cameroon, 'C', 'M' }, +{ QLocale::Language::Chinese, QLocale::Country::China, 'C', 'N' }, +{ QLocale::Language::Spanish, QLocale::Country::Colombia, 'C', 'O' }, +{ QLocale::Language::AnyLanguage, QLocale::Country::ClippertonIsland, 'C', 'P' }, +{ QLocale::Language::Spanish, QLocale::Country::CostaRica, 'C', 'R' }, +{ QLocale::Language::Spanish, QLocale::Country::Cuba, 'C', 'U' }, +{ QLocale::Language::Portuguese, QLocale::Country::CapeVerde, 'C', 'V' }, +{ QLocale::Language::Papiamento, QLocale::Country::CuraSao, 'C', 'W' }, +{ QLocale::Language::Greek, QLocale::Country::Cyprus, 'C', 'Y' }, +{ QLocale::Language::Czech, QLocale::Country::CzechRepublic, 'C', 'Z' }, +{ QLocale::Language::German, QLocale::Country::Germany, 'D', 'E' }, +{ QLocale::Language::Afar, QLocale::Country::Djibouti, 'D', 'J' }, +{ QLocale::Language::Danish, QLocale::Country::Denmark, 'D', 'K' }, +{ QLocale::Language::Spanish, QLocale::Country::DominicanRepublic, 'D', 'O' }, +{ QLocale::Language::Arabic, QLocale::Country::Algeria, 'D', 'Z' }, +{ QLocale::Language::Spanish, QLocale::Country::CeutaAndMelilla, 'E', 'A' }, +{ QLocale::Language::Spanish, QLocale::Country::Ecuador, 'E', 'C' }, +{ QLocale::Language::Estonian, QLocale::Country::Estonia, 'E', 'E' }, +{ QLocale::Language::Arabic, QLocale::Country::Egypt, 'E', 'G' }, +{ QLocale::Language::Arabic, QLocale::Country::WesternSahara, 'E', 'H' }, +{ QLocale::Language::Tigrinya, QLocale::Country::Eritrea, 'E', 'R' }, +{ QLocale::Language::Spanish, QLocale::Country::Spain, 'E', 'S' }, +{ QLocale::Language::Amharic, QLocale::Country::Ethiopia, 'E', 'T' }, +{ QLocale::Language::English, QLocale::Country::EuropeanUnion, 'E', 'U' }, +{ QLocale::Language::German, QLocale::Country::AnyCountry, 'E', 'Z' }, +{ QLocale::Language::Finnish, QLocale::Country::Finland, 'F', 'I' }, +{ QLocale::Language::Faroese, QLocale::Country::FaroeIslands, 'F', 'O' }, +{ QLocale::Language::French, QLocale::Country::France, 'F', 'R' }, +{ QLocale::Language::French, QLocale::Country::Gabon, 'G', 'A' }, +{ QLocale::Language::Georgian, QLocale::Country::Georgia, 'G', 'E' }, +{ QLocale::Language::French, QLocale::Country::FrenchGuiana, 'G', 'F' }, +{ QLocale::Language::Akan, QLocale::Country::Ghana, 'G', 'H' }, +{ QLocale::Language::Greenlandic, QLocale::Country::Greenland, 'G', 'L' }, +{ QLocale::Language::French, QLocale::Country::Guinea, 'G', 'N' }, +{ QLocale::Language::French, QLocale::Country::Guadeloupe, 'G', 'P' }, +{ QLocale::Language::Spanish, QLocale::Country::EquatorialGuinea, 'G', 'Q' }, +{ QLocale::Language::Greek, QLocale::Country::Greece, 'G', 'R' }, +{ QLocale::Language::AnyLanguage, QLocale::Country::SouthGeorgiaAndTheSouthSandwichIslands, 'G', 'S' }, +{ QLocale::Language::Spanish, QLocale::Country::Guatemala, 'G', 'T' }, +{ QLocale::Language::Portuguese, QLocale::Country::GuineaBissau, 'G', 'W' }, +{ QLocale::Language::Chinese, QLocale::Country::HongKong, 'H', 'K' }, +{ QLocale::Language::AnyLanguage, QLocale::Country::HeardAndMcDonaldIslands, 'H', 'M' }, +{ QLocale::Language::Spanish, QLocale::Country::Honduras, 'H', 'N' }, +{ QLocale::Language::Croatian, QLocale::Country::Croatia, 'H', 'R' }, +{ QLocale::Language::Haitian, QLocale::Country::Haiti, 'H', 'T' }, +{ QLocale::Language::Hungarian, QLocale::Country::Hungary, 'H', 'U' }, +{ QLocale::Language::Spanish, QLocale::Country::CanaryIslands, 'I', 'C' }, +{ QLocale::Language::Indonesian, QLocale::Country::Indonesia, 'I', 'D' }, +{ QLocale::Language::Hebrew, QLocale::Country::Israel, 'I', 'L' }, +{ QLocale::Language::Hindi, QLocale::Country::India, 'I', 'N' }, +{ QLocale::Language::Arabic, QLocale::Country::Iraq, 'I', 'Q' }, +{ QLocale::Language::Persian, QLocale::Country::Iran, 'I', 'R' }, +{ QLocale::Language::Icelandic, QLocale::Country::Iceland, 'I', 'S' }, +{ QLocale::Language::Italian, QLocale::Country::Italy, 'I', 'T' }, +{ QLocale::Language::Arabic, QLocale::Country::Jordan, 'J', 'O' }, +{ QLocale::Language::Japanese, QLocale::Country::Japan, 'J', 'P' }, +{ QLocale::Language::Swahili, QLocale::Country::Kenya, 'K', 'E' }, +{ QLocale::Language::Kirghiz, QLocale::Country::Kyrgyzstan, 'K', 'G' }, +{ QLocale::Language::Khmer, QLocale::Country::Cambodia, 'K', 'H' }, +{ QLocale::Language::Arabic, QLocale::Country::Comoros, 'K', 'M' }, +{ QLocale::Language::Korean, QLocale::Country::NorthKorea, 'K', 'P' }, +{ QLocale::Language::Korean, QLocale::Country::SouthKorea, 'K', 'R' }, +{ QLocale::Language::Arabic, QLocale::Country::Kuwait, 'K', 'W' }, +{ QLocale::Language::Russian, QLocale::Country::Kazakhstan, 'K', 'Z' }, +{ QLocale::Language::Lao, QLocale::Country::Laos, 'L', 'A' }, +{ QLocale::Language::Arabic, QLocale::Country::Lebanon, 'L', 'B' }, +{ QLocale::Language::German, QLocale::Country::Liechtenstein, 'L', 'I' }, +{ QLocale::Language::Sinhala, QLocale::Country::SriLanka, 'L', 'K' }, +{ QLocale::Language::SouthernSotho, QLocale::Country::Lesotho, 'L', 'S' }, +{ QLocale::Language::Lithuanian, QLocale::Country::Lithuania, 'L', 'T' }, +{ QLocale::Language::French, QLocale::Country::Luxembourg, 'L', 'U' }, +{ QLocale::Language::Latvian, QLocale::Country::Latvia, 'L', 'V' }, +{ QLocale::Language::Arabic, QLocale::Country::Libya, 'L', 'Y' }, +{ QLocale::Language::Arabic, QLocale::Country::Morocco, 'M', 'A' }, +{ QLocale::Language::French, QLocale::Country::Monaco, 'M', 'C' }, +{ QLocale::Language::Romanian, QLocale::Country::Moldova, 'M', 'D' }, +{ QLocale::Language::Serbian, QLocale::Country::Montenegro, 'M', 'E' }, +{ QLocale::Language::French, QLocale::Country::SaintMartin, 'M', 'F' }, +{ QLocale::Language::Malagasy, QLocale::Country::Madagascar, 'M', 'G' }, +{ QLocale::Language::Macedonian, QLocale::Country::Macedonia, 'M', 'K' }, +{ QLocale::Language::Bambara, QLocale::Country::Mali, 'M', 'L' }, +{ QLocale::Language::Burmese, QLocale::Country::Myanmar, 'M', 'M' }, +{ QLocale::Language::Mongolian, QLocale::Country::Mongolia, 'M', 'N' }, +{ QLocale::Language::Chinese, QLocale::Country::Macau, 'M', 'O' }, +{ QLocale::Language::French, QLocale::Country::Martinique, 'M', 'Q' }, +{ QLocale::Language::Arabic, QLocale::Country::Mauritania, 'M', 'R' }, +{ QLocale::Language::Maltese, QLocale::Country::Malta, 'M', 'T' }, +{ QLocale::Language::Morisyen, QLocale::Country::Mauritius, 'M', 'U' }, +{ QLocale::Language::Divehi, QLocale::Country::Maldives, 'M', 'V' }, +{ QLocale::Language::Spanish, QLocale::Country::Mexico, 'M', 'X' }, +{ QLocale::Language::Malay, QLocale::Country::Malaysia, 'M', 'Y' }, +{ QLocale::Language::Portuguese, QLocale::Country::Mozambique, 'M', 'Z' }, +{ QLocale::Language::Afrikaans, QLocale::Country::Namibia, 'N', 'A' }, +{ QLocale::Language::French, QLocale::Country::NewCaledonia, 'N', 'C' }, +{ QLocale::Language::Hausa, QLocale::Country::Niger, 'N', 'E' }, +{ QLocale::Language::Spanish, QLocale::Country::Nicaragua, 'N', 'I' }, +{ QLocale::Language::Dutch, QLocale::Country::Netherlands, 'N', 'L' }, +{ QLocale::Language::NorwegianBokmal, QLocale::Country::Norway, 'N', 'O' }, +{ QLocale::Language::Nepali, QLocale::Country::Nepal, 'N', 'P' }, +{ QLocale::Language::Arabic, QLocale::Country::Oman, 'O', 'M' }, +{ QLocale::Language::Spanish, QLocale::Country::Panama, 'P', 'A' }, +{ QLocale::Language::Spanish, QLocale::Country::Peru, 'P', 'E' }, +{ QLocale::Language::French, QLocale::Country::FrenchPolynesia, 'P', 'F' }, +{ QLocale::Language::TokPisin, QLocale::Country::PapuaNewGuinea, 'P', 'G' }, +{ QLocale::Language::Filipino, QLocale::Country::Philippines, 'P', 'H' }, +{ QLocale::Language::Urdu, QLocale::Country::Pakistan, 'P', 'K' }, +{ QLocale::Language::Polish, QLocale::Country::Poland, 'P', 'L' }, +{ QLocale::Language::French, QLocale::Country::SaintPierreAndMiquelon, 'P', 'M' }, +{ QLocale::Language::Spanish, QLocale::Country::PuertoRico, 'P', 'R' }, +{ QLocale::Language::Arabic, QLocale::Country::PalestinianTerritories, 'P', 'S' }, +{ QLocale::Language::Portuguese, QLocale::Country::Portugal, 'P', 'T' }, +{ QLocale::Language::Palauan, QLocale::Country::Palau, 'P', 'W' }, +{ QLocale::Language::Guarani, QLocale::Country::Paraguay, 'P', 'Y' }, +{ QLocale::Language::Arabic, QLocale::Country::Qatar, 'Q', 'A' }, +{ QLocale::Language::English, QLocale::Country::OutlyingOceania, 'Q', 'O' }, +{ QLocale::Language::French, QLocale::Country::Reunion, 'R', 'E' }, +{ QLocale::Language::Romanian, QLocale::Country::Romania, 'R', 'O' }, +{ QLocale::Language::Serbian, QLocale::Country::Serbia, 'R', 'S' }, +{ QLocale::Language::Russian, QLocale::Country::Russia, 'R', 'U' }, +{ QLocale::Language::Kinyarwanda, QLocale::Country::Rwanda, 'R', 'W' }, +{ QLocale::Language::Arabic, QLocale::Country::SaudiArabia, 'S', 'A' }, +{ QLocale::Language::French, QLocale::Country::Seychelles, 'S', 'C' }, +{ QLocale::Language::Arabic, QLocale::Country::Sudan, 'S', 'D' }, +{ QLocale::Language::Swedish, QLocale::Country::Sweden, 'S', 'E' }, +{ QLocale::Language::Slovenian, QLocale::Country::Slovenia, 'S', 'I' }, +{ QLocale::Language::NorwegianBokmal, QLocale::Country::SvalbardAndJanMayenIslands, 'S', 'J' }, +{ QLocale::Language::Slovak, QLocale::Country::Slovakia, 'S', 'K' }, +{ QLocale::Language::Italian, QLocale::Country::SanMarino, 'S', 'M' }, +{ QLocale::Language::French, QLocale::Country::Senegal, 'S', 'N' }, +{ QLocale::Language::Somali, QLocale::Country::Somalia, 'S', 'O' }, +{ QLocale::Language::Dutch, QLocale::Country::Suriname, 'S', 'R' }, +{ QLocale::Language::Portuguese, QLocale::Country::SaoTomeAndPrincipe, 'S', 'T' }, +{ QLocale::Language::Spanish, QLocale::Country::ElSalvador, 'S', 'V' }, +{ QLocale::Language::Arabic, QLocale::Country::Syria, 'S', 'Y' }, +{ QLocale::Language::French, QLocale::Country::Chad, 'T', 'D' }, +{ QLocale::Language::French, QLocale::Country::FrenchSouthernTerritories, 'T', 'F' }, +{ QLocale::Language::French, QLocale::Country::Togo, 'T', 'G' }, +{ QLocale::Language::Thai, QLocale::Country::Thailand, 'T', 'H' }, +{ QLocale::Language::Tajik, QLocale::Country::Tajikistan, 'T', 'J' }, +{ QLocale::Language::TokelauLanguage, QLocale::Country::Tokelau, 'T', 'K' }, +{ QLocale::Language::Portuguese, QLocale::Country::EastTimor, 'T', 'L' }, +{ QLocale::Language::Turkmen, QLocale::Country::Turkmenistan, 'T', 'M' }, +{ QLocale::Language::Arabic, QLocale::Country::Tunisia, 'T', 'N' }, +{ QLocale::Language::Tongan, QLocale::Country::Tonga, 'T', 'O' }, +{ QLocale::Language::Turkish, QLocale::Country::Turkey, 'T', 'R' }, +{ QLocale::Language::TuvaluLanguage, QLocale::Country::Tuvalu, 'T', 'V' }, +{ QLocale::Language::Chinese, QLocale::Country::Taiwan, 'T', 'W' }, +{ QLocale::Language::Swahili, QLocale::Country::Tanzania, 'T', 'Z' }, +{ QLocale::Language::Ukrainian, QLocale::Country::Ukraine, 'U', 'A' }, +{ QLocale::Language::Swahili, QLocale::Country::Uganda, 'U', 'G' }, +{ QLocale::Language::Spanish, QLocale::Country::Uruguay, 'U', 'Y' }, +{ QLocale::Language::Uzbek, QLocale::Country::Uzbekistan, 'U', 'Z' }, +{ QLocale::Language::Italian, QLocale::Country::VaticanCityState, 'V', 'A' }, +{ QLocale::Language::Spanish, QLocale::Country::Venezuela, 'V', 'E' }, +{ QLocale::Language::Vietnamese, QLocale::Country::Vietnam, 'V', 'N' }, +{ QLocale::Language::Bislama, QLocale::Country::Vanuatu, 'V', 'U' }, +{ QLocale::Language::French, QLocale::Country::WallisAndFutunaIslands, 'W', 'F' }, +{ QLocale::Language::Samoan, QLocale::Country::Samoa, 'W', 'S' }, +{ QLocale::Language::Albanian, QLocale::Country::Kosovo, 'X', 'K' }, +{ QLocale::Language::Arabic, QLocale::Country::Yemen, 'Y', 'E' }, +{ QLocale::Language::French, QLocale::Country::Mayotte, 'Y', 'T' }, +{ QLocale::Language::Shona, QLocale::Country::Zimbabwe, 'Z', 'W' }, +{ QLocale::Language::AnyLanguage, QLocale::Country::AnyCountry, 0, 0 }, +}; + +static_assert( (sizeof(country_data_table) / sizeof(CountryData)) == country_data_size, "Table size mismatch for CountryData" ); + + +// END Generated from CLDR data diff --git a/src/libcalamares/locale/Lookup.cpp b/src/libcalamares/locale/Lookup.cpp new file mode 100644 index 000000000..d38d417d4 --- /dev/null +++ b/src/libcalamares/locale/Lookup.cpp @@ -0,0 +1,90 @@ +/* === 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 "Lookup.h" + +#include "CountryData_p.cpp" + +namespace Calamares +{ + +struct TwoChar +{ + TwoChar( const QString& code ) + : cc1(0) + , cc2(0) + { + if ( code.length() == 2 ) + { + cc1 = code[0].toLatin1(); + cc2 = code[1].toLatin1(); + } + } + + char cc1; + char cc2; +}; + +static const CountryData* lookup( TwoChar c ) +{ + if ( !c.cc1 ) + return nullptr; + + const CountryData* p = std::find_if(country_data_table, country_data_table + country_data_size, + [c=c]( const CountryData& d ){ return (d.cc1 == c.cc1) && (d.cc2 == c.cc2); } + ); + if ( p == country_data_table + country_data_size ) + return nullptr; + return p; +} + +QLocale::Country countryForCode(const QString& code) +{ + const CountryData* p = lookup( TwoChar( code ) ); + return p ? p->c : QLocale::Country::AnyCountry; +} + +QLocale::Language languageForCountry(const QString& code) +{ + const CountryData* p = lookup( TwoChar( code ) ); + return p ? p->l : QLocale::Language::AnyLanguage; +} + +QPair countryData(const QString& code) +{ + const CountryData* p = lookup( TwoChar( code ) ); + return p ? qMakePair( p->c, p->l ) : qMakePair( QLocale::Country::AnyCountry, QLocale::Language::AnyLanguage ); +} + +QLocale countryLocale(const QString& code) +{ + auto p = countryData( code ); + return QLocale( p.second, p.first ); +} + +QLocale::Language languageForCountry(QLocale::Country country) +{ + const CountryData* p = std::find_if(country_data_table, country_data_table + country_data_size, + [c=country]( const CountryData& d ){ return d.c == c; } + ); + if ( p == country_data_table + country_data_size ) + return QLocale::Language::AnyLanguage; + return p->l; +} + +} // namespace diff --git a/src/libcalamares/locale/Lookup.h b/src/libcalamares/locale/Lookup.h new file mode 100644 index 000000000..976c4dc21 --- /dev/null +++ b/src/libcalamares/locale/Lookup.h @@ -0,0 +1,52 @@ +/* === 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 . + */ + +#ifndef LOCALE_LOOKUP_H +#define LOCALE_LOOKUP_H + +#include "DllMacro.h" + +#include +#include + +namespace Calamares +{ + /* All the functions in this file do lookups of locale data + * based on CLDR tables; these are lookups that you can't (easily) + * do with just QLocale (e.g. from 2-letter country code to a likely + * locale). + */ + + /// @brief Map a 2-letter code to a Country, or AnyCountry if not found + DLLEXPORT QLocale::Country countryForCode( const QString& code ); + /** @brief Map a Country to a Language, or AnyLanguage if not found + * + * This is a *likely* language for the given country, based on the + * CLDR tables. For instance, this maps Belgium to Dutch. + */ + DLLEXPORT QLocale::Language languageForCountry( QLocale::Country country ); + /// @brief Map a 2-letter code to a Language, or AnyLanguage if not found + DLLEXPORT QLocale::Language languageForCountry( const QString& code ); + + /// @brief Get both Country and Language for a 2-letter code + DLLEXPORT QPair< QLocale::Country, QLocale::Language > countryData( const QString& code ); + /// @brief Get a likely locale for a 2-letter country code + DLLEXPORT QLocale countryLocale( const QString& code ); +} // namespace + +#endif diff --git a/src/libcalamares/locale/cldr-extractor.py b/src/libcalamares/locale/cldr-extractor.py new file mode 100644 index 000000000..4e279337b --- /dev/null +++ b/src/libcalamares/locale/cldr-extractor.py @@ -0,0 +1,287 @@ +#! /usr/bin/env python3 +# +# === This file is part of Calamares - === +# +# Python3 script to scrape some data out of ICU CLDR supplemental data. +# +### BEGIN LICENSES +# +# Copyright 2019 Adriaan de Groot +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +### END LICENSES + +### BEGIN USAGE +# +""" +Python3 script to scrape some data out of ICU CLDR supplemental data. + +To use this script, you must have downloaded the CLDR data, e.g. +http://unicode.org/Public/cldr/35.1/, and extracted the zip file. +Run the script from **inside** the common/ durectory that is created +(or fix the hard-coded path). + +The script tries to print C++ code that compiles; if there are encoding +problems, it will print some kind of representation of the problematic +lines. + +To avoid having to cross-reference multiple XML files, the script +cheats: it reads the comments as well to get names. So it looks for +pairs of lines like this: + + + + +It extracts the 2-character country code "BQ" from the sub-tag, and +parses the comment to get a language and country name (instead of looking up +"pap" and "BQ" in other tables). This may be considered a hack. + +A large collection of exceptions can be found in the two *_mapper tables, +which massage the CLDR names to Qt enum values. +""" +# +### END USAGE + +import sys + +# These are languages listed in CLDR that don't match +# the enum-values in QLocale::Language. +language_mapper = { + "?" : "AnyLanguage", + "Bangla" : "Bengali", + "Kalaallisut" : "Greenlandic", + "Haitian Creole" : "Haitian", + "Kyrgyz" : "Kirghiz", + "Norwegian Bokmål" : "NorwegianBokmal", + "Tokelau" : "TokelauLanguage", + "Tuvalu" : "TuvaluLanguage", + } + +country_mapper = { + "Åland Islands" : "AlandIslands", + "St. Barthélemy" : "SaintBarthelemy", + "Côte d’Ivoire" : "IvoryCoast", + "Curaçao" : "CuraSao", + "Réunion" : "Reunion", + "São Tomé & Príncipe" : "SaoTomeAndPrincipe", + "Bosnia & Herzegovina" : "BosniaAndHerzegowina", + "Czechia" : "CzechRepublic", + "St. Pierre & Miquelon" : "SaintPierreAndMiquelon", + "Vatican City" : "VaticanCityState", + "South Georgia & South Sandwich Islands" : "SouthGeorgiaAndTheSouthSandwichIslands", + "Timor-Leste" : "EastTimor", + "Wallis & Futuna" : "WallisAndFutunaIslands", + "Myanmar (Burma)" : "Myanmar", + "Svalbard & Jan Mayen" : "SvalbardAndJanMayenIslands", + "St. Martin" : "SaintMartin", + "North Macedonia" : "Macedonia", + "Hong Kong SAR China" : "HongKong", + "Macao SAR China" : "Macau", + "Eurozone" : "AnyCountry", # Not likely for GeoIP + "Caribbean Netherlands" : "Bonaire", # Bonaire, Saba, St.Eustatius + } + +class CountryData: + def __init__(self, country_code, language_name, country_name): + """ + Takes a 2-letter country name, and enum names from + QLocale::Language and QLocale::Country. An empty + @p country code is acceptable, for the terminating + entry in the data array (and yields a 0,0 code). + """ + if country_code: + assert len(country_code) == 2 + self.country_code = country_code + self.language_enum = language_name + self.country_enum = country_name + else: + self.country_code = "" + self.language_enum = "AnyLanguage" + self.country_enum = "AnyCountry" + + def __str__(self): + if self.country_code: + char0 = "'{!s}'".format(self.country_code[0]) + char1 = "'{!s}'".format(self.country_code[1]) + else: + char0 = "0" + char1 = "0" + + return "{!s} QLocale::Language::{!s}, QLocale::Country::{!s}, {!s}, {!s} {!s},".format( + "{", + self.language_enum, + self.country_enum, + char0, + char1, + "}") + + # Must match type name below + cpp_classname = "CountryData" + + # Must match the output format of __str__ above + cpp_declaration = """ +struct CountryData +{ + QLocale::Language l; + QLocale::Country c; + char cc1; + char cc2; +}; +""" + + +def extricate_subtags(l1, l2): + """ + Given two lines @p l1 and @p l2 which are the element-line + and the comment-line underneath it, return a CountryData for them, + or None if the two lines are not relevant (e.g. not the right subtag from, + or 3-letter country codes. + """ + if 'from="und_' not in l1: + return + if '{ ?; ?;' not in l2: + return + + # This is extremely crude "parsing" which chops up the string + # by delimiter and then extracts some substring. + l1_parts = l1.split("und_") + l2_parts = l2.split(";") + + l1_first_quote = l1_parts[1].find('"') + l1_code = l1_parts[1][:l1_first_quote] + if len(l1_code) != 2: + return + + l2_brace = l2_parts[2].find("{") + l2_language = l2_parts[2][l2_brace+1:].strip() + l2_brace = l2_parts[2].find("}") + l2_country = l2_parts[2][:l2_brace-1].strip() + + # Handle mapped cases + l2_language = language_mapper.get(l2_language, l2_language) + l2_language = l2_language.replace(" ", "") + + # Handle mapped cases and then do a bunch of standard replacements. + l2_country = country_mapper.get(l2_country, l2_country) + l2_country = l2_country.replace(" ", "").replace("-", "").replace(".","").replace("&","And") + + return CountryData(l1_code, l2_language, l2_country) + + +def read_subtags_file(): + """ + Returns a list of CountryData objects from the likelySubtags file. + """ + data = [] + + with open("supplemental/likelySubtags.xml", "rt", encoding="UTF-8") as f: + l1 = "a line" + while l1: + l1 = f.readline() + if ' === +* +* This file is derived from CLDR data from Unicode, Inc. Applicable terms: +* +* A. Unicode Copyright +* 1. Copyright © 1991-2019 Unicode, Inc. All rights reserved. +* B. Definitions +* Unicode Data Files ("DATA FILES") include all data files under the directories: +* https://www.unicode.org/Public/ +* C. Terms of Use +* 2. Any person is hereby authorized, without fee, to view, use, reproduce, +* and distribute all documents and files, subject to the Terms and +* Conditions herein. +*/ + +// BEGIN Generated from CLDR data + +""" + +cpp_footer_comment = """ +// END Generated from CLDR data +""" + + +def make_identifier(classname): + """ + Given a class name (e.g. CountryData) return an identifer + for the data-table for that class. + """ + identifier = [ classname[0].lower() ] + for c in classname[1:]: + if c.isupper(): + identifier.extend(["_", c.lower()]) + else: + identifier.append(c) + + return "".join(identifier) + + +def export_class(cls, data): + """ + Given a @p cls and a list of @p data objects from that class, + print (to stdout) a C++ file for that data. + """ + identifier = make_identifier(cls.cpp_classname) + + with open("{!s}_p.cpp".format(cls.cpp_classname), "wt", encoding="UTF-8") as f: + f.write(cpp_header_comment) + f.write(cls.cpp_declaration) + f.write("\nstatic constexpr int const {!s}_size = {!s};\n".format( + identifier, + len(data))) + f.write("\nstatic const {!s} {!s}_table[] = {!s}\n".format( + cls.cpp_classname, + identifier, + "{")) + for d in data: + f.write(str(d)) + f.write("\n") + f.write("};\n\n"); + f.write("static_assert( (sizeof({!s}_table) / sizeof({!s})) == {!s}_size, \"Table size mismatch for {!s}\" );\n\n".format( + identifier, + cls.cpp_classname, + identifier, + cls.cpp_classname)) + f.write(cpp_footer_comment) + + +if __name__ == "__main__": + export_class(CountryData, read_subtags_file()) diff --git a/src/libcalamares/Typedefs.h b/src/libcalamares/modulesystem/Actions.h similarity index 75% rename from src/libcalamares/Typedefs.h rename to src/libcalamares/modulesystem/Actions.h index 324f2b155..069937235 100644 --- a/src/libcalamares/Typedefs.h +++ b/src/libcalamares/modulesystem/Actions.h @@ -1,6 +1,7 @@ /* === This file is part of Calamares - === * * Copyright 2014, Teo Mrnjavac + * 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 @@ -16,28 +17,18 @@ * along with Calamares. If not, see . */ -#ifndef TYPEDEFS_H -#define TYPEDEFS_H - -#include -#include +#ifndef MODULESYSTEM_ACTIONS_H +#define MODULESYSTEM_ACTIONS_H namespace Calamares { -class Job; -typedef QSharedPointer< Job > job_ptr; -using JobList = QList< job_ptr >; - -enum ModuleAction : char +enum class ModuleAction : char { Show, Exec }; -class ViewStep; -typedef QList< ViewStep* > ViewStepList; +} // namespace -} //ns - -#endif // TYPEDEFS_H +#endif diff --git a/src/libcalamares/partition/PartitionSize.cpp b/src/libcalamares/partition/PartitionSize.cpp new file mode 100644 index 000000000..edff0fe1e --- /dev/null +++ b/src/libcalamares/partition/PartitionSize.cpp @@ -0,0 +1,238 @@ +/* === This file is part of Calamares - === + * + * Copyright 2019, Collabora Ltd + * + * 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 "partition/PartitionSize.h" +#include "utils/Logger.h" +#include "utils/Units.h" + +namespace Calamares +{ + +static const NamedEnumTable& +unitSuffixes() +{ + static const NamedEnumTable names{ + { QStringLiteral( "%" ), SizeUnit::Percent }, + { QStringLiteral( "K" ), SizeUnit::KiB }, + { QStringLiteral( "KiB" ), SizeUnit::KiB }, + { QStringLiteral( "M" ), SizeUnit::MiB }, + { QStringLiteral( "MiB" ), SizeUnit::MiB }, + { QStringLiteral( "G" ), SizeUnit::GiB }, + { QStringLiteral( "GiB" ), SizeUnit::GiB } + }; + + return names; +} + +PartitionSize::PartitionSize( const QString& s ) + : NamedSuffix( unitSuffixes(), s ) +{ + if ( ( unit() == unit_t::Percent ) && ( value() > 100 || value() < 0 ) ) + { + cDebug() << "Percent value" << value() << "is not valid."; + m_value = 0; + } + + if ( m_unit == unit_t::None ) + { + m_value = s.toInt(); + if ( m_value > 0 ) + m_unit = unit_t::Byte; + } + + if ( m_value <= 0 ) + { + m_value = 0; + m_unit = unit_t::None; + } +} + +qint64 +PartitionSize::toSectors( qint64 totalSectors, qint64 sectorSize ) const +{ + if ( !isValid() ) + return -1; + if ( totalSectors < 1 || sectorSize < 1 ) + return -1; + + switch ( m_unit ) + { + case unit_t::None: + return -1; + case unit_t::Percent: + if ( value() == 100 ) + return totalSectors; // Common-case, avoid futzing around + else + return totalSectors * value() / 100; + case unit_t::Byte: + case unit_t::KiB: + case unit_t::MiB: + case unit_t::GiB: + return CalamaresUtils::bytesToSectors ( toBytes(), sectorSize ); + } + + return -1; +} + +qint64 +PartitionSize::toBytes( qint64 totalSectors, qint64 sectorSize ) const +{ + if ( !isValid() ) + return -1; + + switch ( m_unit ) + { + case unit_t::None: + return -1; + case unit_t::Percent: + if ( totalSectors < 1 || sectorSize < 1 ) + return -1; + if ( value() == 100 ) + return totalSectors * sectorSize; // Common-case, avoid futzing around + else + return totalSectors * value() / 100; + case unit_t::Byte: + case unit_t::KiB: + case unit_t::MiB: + case unit_t::GiB: + return toBytes(); + } + + // notreached + return -1; +} + +qint64 +PartitionSize::toBytes( qint64 totalBytes ) const +{ + if ( !isValid() ) + return -1; + + switch ( m_unit ) + { + case unit_t::None: + return -1; + case unit_t::Percent: + if ( totalBytes < 1 ) + return -1; + if ( value() == 100 ) + return totalBytes; // Common-case, avoid futzing around + else + return totalBytes * value() / 100; + case unit_t::Byte: + case unit_t::KiB: + case unit_t::MiB: + case unit_t::GiB: + return toBytes(); + } + + // notreached + return -1; +} + +qint64 +PartitionSize::toBytes() const +{ + if ( !isValid() ) + return -1; + + switch ( m_unit ) + { + case unit_t::Byte: + return value(); + case unit_t::KiB: + return CalamaresUtils::KiBtoBytes( static_cast( value() ) ); + case unit_t::MiB: + return CalamaresUtils::MiBtoBytes( static_cast( value() ) ); + case unit_t::GiB: + return CalamaresUtils::GiBtoBytes( static_cast( value() ) ); + default: + break; + } + + // Reached only when unit is Percent or None + return -1; +} + +bool +PartitionSize::operator< ( const PartitionSize& other ) const +{ + if ( ( m_unit == unit_t::None || other.m_unit == unit_t::None ) || + ( m_unit == unit_t::Percent && other.m_unit != unit_t::Percent ) || + ( m_unit != unit_t::Percent && other.m_unit == unit_t::Percent ) ) + return false; + + switch ( m_unit ) + { + case unit_t::Percent: + return ( m_value < other.m_value ); + case unit_t::Byte: + case unit_t::KiB: + case unit_t::MiB: + case unit_t::GiB: + return ( toBytes() < other.toBytes () ); + } + + return false; +} + +bool +PartitionSize::operator> ( const PartitionSize& other ) const +{ + if ( ( m_unit == unit_t::None || other.m_unit == unit_t::None ) || + ( m_unit == unit_t::Percent && other.m_unit != unit_t::Percent ) || + ( m_unit != unit_t::Percent && other.m_unit == unit_t::Percent ) ) + return false; + + switch ( m_unit ) + { + case unit_t::Percent: + return ( m_value > other.m_value ); + case unit_t::Byte: + case unit_t::KiB: + case unit_t::MiB: + case unit_t::GiB: + return ( toBytes() > other.toBytes () ); + } + + return false; +} + +bool +PartitionSize::operator== ( const PartitionSize& other ) const +{ + if ( ( m_unit == unit_t::None || other.m_unit == unit_t::None ) || + ( m_unit == unit_t::Percent && other.m_unit != unit_t::Percent ) || + ( m_unit != unit_t::Percent && other.m_unit == unit_t::Percent ) ) + return false; + + switch ( m_unit ) + { + case unit_t::Percent: + return ( m_value == other.m_value ); + case unit_t::Byte: + case unit_t::KiB: + case unit_t::MiB: + case unit_t::GiB: + return ( toBytes() == other.toBytes () ); + } + + return false; +} + +} // namespace Calamares diff --git a/src/libcalamares/partition/PartitionSize.h b/src/libcalamares/partition/PartitionSize.h new file mode 100644 index 000000000..13ffa5c70 --- /dev/null +++ b/src/libcalamares/partition/PartitionSize.h @@ -0,0 +1,103 @@ +/* === This file is part of Calamares - === + * + * Copyright 2019, Collabora Ltd + * + * 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 . + */ + +#ifndef PARTITION_PARTITIONSIZE_H +#define PARTITION_PARTITIONSIZE_H + +#include "utils/Units.h" +#include "utils/NamedSuffix.h" + +// Qt +#include + +namespace Calamares +{ + +enum class SizeUnit +{ + None, + Percent, + Byte, + KiB, + MiB, + GiB +}; + +/** @brief Partition size expressions + * + * Sizes can be specified in bytes, KiB, MiB, GiB or percent (of + * the available drive space are on). This class handles parsing + * of such strings from the config file. + */ +class PartitionSize : public NamedSuffix +{ +public: + PartitionSize() : NamedSuffix() { } + PartitionSize( int v, unit_t u ) : NamedSuffix( v, u ) { } + PartitionSize( const QString& ); + + bool isValid() const + { + return ( unit() != SizeUnit::None ) && ( value() > 0 ); + } + + bool operator< ( const PartitionSize& other ) const; + bool operator> ( const PartitionSize& other ) const; + bool operator== ( const PartitionSize& other ) const; + + /** @brief Convert the size to the number of sectors @p totalSectors . + * + * Each sector has size @p sectorSize, for converting sizes in Bytes, + * KiB, MiB or GiB to sector counts. + * + * @return the number of sectors needed, or -1 for invalid sizes. + */ + qint64 toSectors( qint64 totalSectors, qint64 sectorSize ) const; + + /** @brief Convert the size to bytes. + * + * The device's sectors count @p totalSectors and sector size + * @p sectoreSize are used to calculated the total size, which + * is then used to calculate the size when using Percent. + * + * @return the size in bytes, or -1 for invalid sizes. + */ + qint64 toBytes( qint64 totalSectors, qint64 sectorSize ) const; + + /** @brief Convert the size to bytes. + * + * Total size @p totalBytes is needed for sizes in Percent. This + * parameter is unused in any other case. + * + * @return the size in bytes, or -1 for invalid sizes. + */ + qint64 toBytes( qint64 totalBytes ) const; + + /** @brief Convert the size to bytes. + * + * This method is only valid for sizes in Bytes, KiB, MiB or GiB. + * It will return -1 in any other case. + * + * @return the size in bytes, or -1 if it cannot be calculated. + */ + qint64 toBytes() const; +}; + +} // namespace Calamares + +#endif // PARTITION_PARTITIONSIZE_H diff --git a/src/libcalamares/utils/Units.h b/src/libcalamares/utils/Units.h index 74c809362..e6d46aaed 100644 --- a/src/libcalamares/utils/Units.h +++ b/src/libcalamares/utils/Units.h @@ -78,5 +78,19 @@ constexpr int BytesToMiB( qint64 b ) return int( b / 1024 / 1024 ); } +constexpr qint64 alignBytesToBlockSize( qint64 bytes, qint64 blocksize ) +{ + qint64 blocks = bytes / blocksize; + + if ( blocks * blocksize != bytes ) + ++blocks; + return blocks * blocksize; +} + +constexpr qint64 bytesToSectors( qint64 bytes, qint64 blocksize ) +{ + return alignBytesToBlockSize( alignBytesToBlockSize( bytes, blocksize), MiBtoBytes(1ULL) ) / blocksize; +} + } // namespace #endif diff --git a/src/libcalamaresui/Branding.h b/src/libcalamaresui/Branding.h index 572cd3682..29a39f103 100644 --- a/src/libcalamaresui/Branding.h +++ b/src/libcalamaresui/Branding.h @@ -22,7 +22,6 @@ #define BRANDING_H #include "UiDllMacro.h" -#include "Typedefs.h" #include "utils/NamedSuffix.h" diff --git a/src/libcalamaresui/CMakeLists.txt b/src/libcalamaresui/CMakeLists.txt index 80220da64..aaa383fde 100644 --- a/src/libcalamaresui/CMakeLists.txt +++ b/src/libcalamaresui/CMakeLists.txt @@ -1,3 +1,9 @@ +# libcalamaresui is the GUI part of Calamares, which includes handling +# view modules, view steps, widgets, and branding. + +# The UI libs use the non-UI library +include_directories( ${CMAKE_SOURCE_DIR}/src/libcalamares ${CMAKE_BINARY_DIR}/src/libcalamares ) + set( calamaresui_SOURCES modulesystem/CppJobModule.cpp modulesystem/Module.cpp diff --git a/src/libcalamaresui/ExecutionViewStep.cpp b/src/libcalamaresui/ExecutionViewStep.cpp index 2010bf120..a65ab3a1c 100644 --- a/src/libcalamaresui/ExecutionViewStep.cpp +++ b/src/libcalamaresui/ExecutionViewStep.cpp @@ -78,7 +78,9 @@ ExecutionViewStep::ExecutionViewStep( QObject* parent ) QString ExecutionViewStep::prettyName() const { - return tr( "Install" ); + return Calamares::Settings::instance()->isSetupMode() + ? tr( "Set up" ) + : tr( "Install" ); } diff --git a/src/libcalamaresui/ViewManager.h b/src/libcalamaresui/ViewManager.h index ee199f725..65d787e44 100644 --- a/src/libcalamaresui/ViewManager.h +++ b/src/libcalamaresui/ViewManager.h @@ -21,19 +21,14 @@ #define VIEWMANAGER_H #include "UiDllMacro.h" -#include "Typedefs.h" +#include "viewpages/ViewStep.h" #include #include #include - namespace Calamares { - -class ViewStep; -class ExecutionViewStep; - /** * @brief The ViewManager class handles progression through view pages. * @note Singleton object, only use through ViewManager::instance(). diff --git a/src/libcalamaresui/modulesystem/CppJobModule.cpp b/src/libcalamaresui/modulesystem/CppJobModule.cpp index 3a48e29f2..22d9a0524 100644 --- a/src/libcalamaresui/modulesystem/CppJobModule.cpp +++ b/src/libcalamaresui/modulesystem/CppJobModule.cpp @@ -33,14 +33,14 @@ namespace Calamares Module::Type CppJobModule::type() const { - return Job; + return Module::Type::Job; } Module::Interface CppJobModule::interface() const { - return QtPluginInterface; + return Module::Interface::QtPlugin; } diff --git a/src/libcalamaresui/modulesystem/Module.cpp b/src/libcalamaresui/modulesystem/Module.cpp index 133ee5438..d05245384 100644 --- a/src/libcalamaresui/modulesystem/Module.cpp +++ b/src/libcalamaresui/modulesystem/Module.cpp @@ -235,9 +235,9 @@ Module::typeString() const { switch ( type() ) { - case Job: + case Type::Job: return "Job Module"; - case View: + case Type::View: return "View Module"; } return QString(); @@ -249,13 +249,13 @@ Module::interfaceString() const { switch ( interface() ) { - case ProcessInterface: + case Interface::Process: return "External process"; - case PythonInterface: + case Interface::Python: return "Python (Boost.Python)"; - case PythonQtInterface: + case Interface::PythonQt: return "Python (experimental)"; - case QtPluginInterface: + case Interface::QtPlugin: return "Qt Plugin"; } return QString(); diff --git a/src/libcalamaresui/modulesystem/Module.h b/src/libcalamaresui/modulesystem/Module.h index 218270825..6da9c0ce4 100644 --- a/src/libcalamaresui/modulesystem/Module.h +++ b/src/libcalamaresui/modulesystem/Module.h @@ -20,11 +20,10 @@ #ifndef CALAMARES_MODULE_H #define CALAMARES_MODULE_H +#include "Job.h" #include "Requirement.h" #include "UiDllMacro.h" -#include - #include #include @@ -54,7 +53,7 @@ public: * A job module is a single Calamares job. * A view module has a UI (one or more view pages) and zero-to-many jobs. */ - enum Type + enum class Type { Job, View @@ -65,12 +64,12 @@ public: * talks to Calamares. * Not all Type-Interface associations are valid. */ - enum Interface + enum class Interface { - QtPluginInterface, - PythonInterface, - ProcessInterface, - PythonQtInterface + QtPlugin, // Jobs or Views + Python, // Jobs only + Process, // Deprecated interface + PythonQt // Views only, available as enum even if PythonQt isn't used }; /** diff --git a/src/libcalamaresui/modulesystem/ModuleManager.cpp b/src/libcalamaresui/modulesystem/ModuleManager.cpp index 32fe09033..852f41445 100644 --- a/src/libcalamaresui/modulesystem/ModuleManager.cpp +++ b/src/libcalamaresui/modulesystem/ModuleManager.cpp @@ -277,7 +277,7 @@ ModuleManager::loadModules() // At this point we most certainly have a pointer to a loaded module in // thisModule. We now need to enqueue jobs info into an EVS. - if ( currentAction == Calamares::Exec ) + if ( currentAction == ModuleAction::Exec ) { ExecutionViewStep* evs = qobject_cast< ExecutionViewStep* >( diff --git a/src/libcalamaresui/modulesystem/ModuleManager.h b/src/libcalamaresui/modulesystem/ModuleManager.h index 689d61a77..64db75b6a 100644 --- a/src/libcalamaresui/modulesystem/ModuleManager.h +++ b/src/libcalamaresui/modulesystem/ModuleManager.h @@ -21,7 +21,6 @@ #define MODULELOADER_H #include "Requirement.h" -#include "Typedefs.h" #include #include diff --git a/src/libcalamaresui/modulesystem/ProcessJobModule.cpp b/src/libcalamaresui/modulesystem/ProcessJobModule.cpp index 9037d85a6..85bdfa4de 100644 --- a/src/libcalamaresui/modulesystem/ProcessJobModule.cpp +++ b/src/libcalamaresui/modulesystem/ProcessJobModule.cpp @@ -29,14 +29,14 @@ namespace Calamares Module::Type ProcessJobModule::type() const { - return Job; + return Module::Type::Job; } Module::Interface ProcessJobModule::interface() const { - return ProcessInterface; + return Module::Interface::Process; } diff --git a/src/libcalamaresui/modulesystem/PythonJobModule.cpp b/src/libcalamaresui/modulesystem/PythonJobModule.cpp index 7099a3f72..e910a4c80 100644 --- a/src/libcalamaresui/modulesystem/PythonJobModule.cpp +++ b/src/libcalamaresui/modulesystem/PythonJobModule.cpp @@ -30,14 +30,14 @@ namespace Calamares Module::Type PythonJobModule::type() const { - return Job; + return Module::Type::Job; } Module::Interface PythonJobModule::interface() const { - return PythonInterface; + return Module::Interface::Python; } diff --git a/src/libcalamaresui/modulesystem/PythonQtViewModule.cpp b/src/libcalamaresui/modulesystem/PythonQtViewModule.cpp index 2af6d81e7..ec9f3c805 100644 --- a/src/libcalamaresui/modulesystem/PythonQtViewModule.cpp +++ b/src/libcalamaresui/modulesystem/PythonQtViewModule.cpp @@ -46,14 +46,14 @@ namespace Calamares Module::Type PythonQtViewModule::type() const { - return View; + return Module::Type::View; } Module::Interface PythonQtViewModule::interface() const { - return PythonQtInterface; + return Module::Interface::PythonQt; } diff --git a/src/libcalamaresui/modulesystem/ViewModule.cpp b/src/libcalamaresui/modulesystem/ViewModule.cpp index e24014621..2789dcfe3 100644 --- a/src/libcalamaresui/modulesystem/ViewModule.cpp +++ b/src/libcalamaresui/modulesystem/ViewModule.cpp @@ -34,14 +34,14 @@ namespace Calamares Module::Type ViewModule::type() const { - return View; + return Module::Type::View; } Module::Interface ViewModule::interface() const { - return QtPluginInterface; + return Module::Interface::QtPlugin; } @@ -65,9 +65,6 @@ ViewModule::loadSelf() } } - // TODO: allow internal view steps to be created here; they would - // have to be linked into the main application somehow. - // If any method created the view step, use it now. if ( m_viewStep ) { diff --git a/src/libcalamaresui/utils/DebugWindow.cpp b/src/libcalamaresui/utils/DebugWindow.cpp index 22986014e..164da02d9 100644 --- a/src/libcalamaresui/utils/DebugWindow.cpp +++ b/src/libcalamaresui/utils/DebugWindow.cpp @@ -1,6 +1,7 @@ /* === This file is part of Calamares - === * * Copyright 2015-2016, Teo Mrnjavac + * 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 @@ -17,6 +18,8 @@ */ #include "DebugWindow.h" +#include "ui_DebugWindow.h" + #include "utils/Retranslator.h" #include "utils/qjsonmodel.h" #include "JobQueue.h" @@ -51,26 +54,27 @@ namespace Calamares { DebugWindow::DebugWindow() : QWidget( nullptr ) + , m_ui( new Ui::DebugWindow ) { - setupUi( this ); + m_ui->setupUi( this ); // GlobalStorage page QJsonModel* jsonModel = new QJsonModel( this ); - globalStorageView->setModel( jsonModel ); + m_ui->globalStorageView->setModel( jsonModel ); GlobalStorage* gs = JobQueue::instance()->globalStorage(); connect( gs, &GlobalStorage::changed, this, [ = ] { jsonModel->loadJson( QJsonDocument::fromVariant( gs->m ).toJson() ); - globalStorageView->expandAll(); + m_ui->globalStorageView->expandAll(); } ); jsonModel->loadJson( QJsonDocument::fromVariant( gs->m ).toJson() ); - globalStorageView->expandAll(); + m_ui->globalStorageView->expandAll(); // JobQueue page - jobQueueText->setReadOnly( true ); + m_ui->jobQueueText->setReadOnly( true ); connect( JobQueue::instance(), &JobQueue::queueChanged, this, [ this ]( const JobList& jobs ) { @@ -80,30 +84,30 @@ DebugWindow::DebugWindow() text.append( job->prettyName() ); } - jobQueueText->setText( text.join( '\n' ) ); + m_ui->jobQueueText->setText( text.join( '\n' ) ); } ); // Modules page QStringListModel* modulesModel = new QStringListModel( ModuleManager::instance()->loadedInstanceKeys() ); - modulesListView->setModel( modulesModel ); - modulesListView->setSelectionMode( QAbstractItemView::SingleSelection ); + m_ui->modulesListView->setModel( modulesModel ); + m_ui->modulesListView->setSelectionMode( QAbstractItemView::SingleSelection ); QJsonModel* moduleConfigModel = new QJsonModel( this ); - moduleConfigView->setModel( moduleConfigModel ); + m_ui->moduleConfigView->setModel( moduleConfigModel ); #ifdef WITH_PYTHONQT QPushButton* pythonConsoleButton = new QPushButton; pythonConsoleButton->setText( "Attach Python console" ); - modulesVerticalLayout->insertWidget( 1, pythonConsoleButton ); + m_ui->modulesVerticalLayout->insertWidget( 1, pythonConsoleButton ); pythonConsoleButton->hide(); QObject::connect( pythonConsoleButton, &QPushButton::clicked, this, [ this, moduleConfigModel ] { - QString moduleName = modulesListView->currentIndex().data().toString(); + QString moduleName = m_ui->modulesListView->currentIndex().data().toString(); Module* module = ModuleManager::instance()->moduleInstance( moduleName ); - if ( module->interface() != Module::PythonQtInterface || - module->type() != Module::View ) + if ( module->interface() != Module::Interface::PythonQt || + module->type() != Module::Type::View ) return; for ( ViewStep* step : ViewManager::instance()->viewSteps() ) @@ -159,33 +163,33 @@ DebugWindow::DebugWindow() #endif - connect( modulesListView->selectionModel(), &QItemSelectionModel::selectionChanged, + connect( m_ui->modulesListView->selectionModel(), &QItemSelectionModel::selectionChanged, this, [ this, moduleConfigModel #ifdef WITH_PYTHONQT , pythonConsoleButton #endif ] { - QString moduleName = modulesListView->currentIndex().data().toString(); + QString moduleName = m_ui->modulesListView->currentIndex().data().toString(); Module* module = ModuleManager::instance()->moduleInstance( moduleName ); if ( module ) { moduleConfigModel->loadJson( QJsonDocument::fromVariant( module->configurationMap() ).toJson() ); - moduleConfigView->expandAll(); - moduleTypeLabel->setText( module->typeString() ); - moduleInterfaceLabel->setText( module->interfaceString() ); + m_ui->moduleConfigView->expandAll(); + m_ui->moduleTypeLabel->setText( module->typeString() ); + m_ui->moduleInterfaceLabel->setText( module->interfaceString() ); #ifdef WITH_PYTHONQT pythonConsoleButton->setVisible( - module->interface() == Module::PythonQtInterface && - module->type() == Module::View ); + module->interface() == Module::Interface::PythonQt && + module->type() == Module::Type::View ); #endif } } ); - connect( crashButton, &QPushButton::clicked, this, [] { ::crash(); } ); + connect( m_ui->crashButton, &QPushButton::clicked, this, [] { ::crash(); } ); CALAMARES_RETRANSLATE( - retranslateUi( this ); + m_ui->retranslateUi( this ); setWindowTitle( tr( "Debug information" ) ); ) } diff --git a/src/libcalamaresui/utils/DebugWindow.h b/src/libcalamaresui/utils/DebugWindow.h index 444fe6231..e97f5727b 100644 --- a/src/libcalamaresui/utils/DebugWindow.h +++ b/src/libcalamaresui/utils/DebugWindow.h @@ -1,6 +1,7 @@ /* === This file is part of Calamares - === * * Copyright 2015, Teo Mrnjavac + * 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 @@ -19,13 +20,18 @@ #ifndef CALAMARES_DEBUGWINDOW_H #define CALAMARES_DEBUGWINDOW_H -#include "ui_DebugWindow.h" - #include + namespace Calamares { -class DebugWindow : public QWidget, private Ui::DebugWindow +// From the .ui file +namespace Ui +{ + class DebugWindow; +} + +class DebugWindow : public QWidget { Q_OBJECT @@ -38,8 +44,10 @@ signals: protected: void closeEvent( QCloseEvent* e ) override; +private: + Ui::DebugWindow *m_ui; }; -} // namespace Calamares -#endif // CALAMARES_DEBUGWINDOW_H +} // namespace +#endif diff --git a/src/libcalamaresui/viewpages/ViewStep.h b/src/libcalamaresui/viewpages/ViewStep.h index 631c41314..e3d5a021e 100644 --- a/src/libcalamaresui/viewpages/ViewStep.h +++ b/src/libcalamaresui/viewpages/ViewStep.h @@ -20,10 +20,11 @@ #ifndef VIEWSTEP_H #define VIEWSTEP_H +#include #include #include -#include "Typedefs.h" +#include "Job.h" #include "UiDllMacro.h" #include "modulesystem/Requirement.h" @@ -159,6 +160,7 @@ protected: QString m_instanceKey; }; +using ViewStepList = QList< ViewStep* >; } #endif // VIEWSTEP_H diff --git a/src/modules/CMakeLists.txt b/src/modules/CMakeLists.txt index 0a8d1db70..9e9621106 100644 --- a/src/modules/CMakeLists.txt +++ b/src/modules/CMakeLists.txt @@ -4,6 +4,12 @@ # in this list. set( LIST_SKIPPED_MODULES "" ) +include_directories( + ${CMAKE_SOURCE_DIR}/src/libcalamares + ${CMAKE_BINARY_DIR}/src/libcalamares + ${CMAKE_SOURCE_DIR}/src/libcalamaresui +) + if( BUILD_TESTING ) add_executable( test_conf test_conf.cpp ) target_link_libraries( test_conf ${YAMLCPP_LIBRARY} Qt5::Core ) diff --git a/src/modules/finished/FinishedPage.cpp b/src/modules/finished/FinishedPage.cpp index 1bc935d0d..c49bb9538 100644 --- a/src/modules/finished/FinishedPage.cpp +++ b/src/modules/finished/FinishedPage.cpp @@ -79,16 +79,13 @@ FinishedPage::FinishedPage( QWidget* parent ) void -FinishedPage::setRestartNowEnabled( bool enabled ) +FinishedPage::setRestart( FinishedViewStep::RestartMode mode ) { - ui->restartCheckBox->setVisible( enabled ); -} + using Mode = FinishedViewStep::RestartMode; - -void -FinishedPage::setRestartNowChecked( bool checked ) -{ - ui->restartCheckBox->setChecked( checked ); + ui->restartCheckBox->setVisible( mode != Mode::Never ); + ui->restartCheckBox->setEnabled( mode != Mode::Always ); + ui->restartCheckBox->setChecked( ( mode == Mode::Always ) || ( mode == Mode::UserChecked ) ); } @@ -138,5 +135,5 @@ FinishedPage::onInstallationFailed( const QString& message, const QString& detai "The error message was: %2." ) .arg( *Calamares::Branding::VersionedName ) .arg( message ) ); - setRestartNowEnabled( false ); + setRestart( FinishedViewStep::RestartMode::Never ); } diff --git a/src/modules/finished/FinishedPage.h b/src/modules/finished/FinishedPage.h index 493c29f34..9954e6fa0 100644 --- a/src/modules/finished/FinishedPage.h +++ b/src/modules/finished/FinishedPage.h @@ -22,6 +22,8 @@ #include +#include "FinishedViewStep.h" + namespace Ui { class FinishedPage; @@ -33,8 +35,7 @@ class FinishedPage : public QWidget public: explicit FinishedPage( QWidget* parent = nullptr ); - void setRestartNowEnabled( bool enabled ); - void setRestartNowChecked( bool checked ); + void setRestart( FinishedViewStep::RestartMode mode ); void setRestartNowCommand( const QString& command ); void setUpRestart(); diff --git a/src/modules/finished/FinishedViewStep.cpp b/src/modules/finished/FinishedViewStep.cpp index d01a99ce9..d5c3c3f69 100644 --- a/src/modules/finished/FinishedViewStep.cpp +++ b/src/modules/finished/FinishedViewStep.cpp @@ -1,7 +1,7 @@ /* === This file is part of Calamares - === * * Copyright 2014-2015, Teo Mrnjavac - * Copyright 2017, Adriaan de Groot + * Copyright 2017, 2019, Adriaan de Groot * Copyright 2019, Collabora Ltd * * Calamares is free software: you can redistribute it and/or modify @@ -20,17 +20,34 @@ #include "FinishedViewStep.h" #include "FinishedPage.h" + +#include "Branding.h" #include "JobQueue.h" +#include "Settings.h" #include "utils/Logger.h" +#include "utils/NamedEnum.h" +#include "utils/Variant.h" #include #include #include #include -#include "Branding.h" -#include "Settings.h" +static const NamedEnumTable< FinishedViewStep::RestartMode >& +modeNames() +{ + using Mode = FinishedViewStep::RestartMode; + + static const NamedEnumTable< Mode > names{ + { QStringLiteral( "never" ), Mode::Never }, + { QStringLiteral( "user-unchecked" ), Mode::UserUnchecked }, + { QStringLiteral( "user-checked" ), Mode::UserChecked }, + { QStringLiteral( "always" ), Mode::Always } + } ; + + return names; +} FinishedViewStep::FinishedViewStep( QObject* parent ) : Calamares::ViewStep( parent ) @@ -122,10 +139,10 @@ FinishedViewStep::sendNotification() QVariant( 0 ) ); if ( !r.isValid() ) - cDebug() << "Could not call notify for end of installation." << r.error(); + cWarning() << "Could not call org.freedesktop.Notifications.Notify at end of installation." << r.error(); } else - cDebug() << "Could not get dbus interface for notifications." << notify.lastError(); + cWarning() << "Could not get dbus interface for notifications at end of installation." << notify.lastError(); } @@ -156,28 +173,41 @@ FinishedViewStep::onInstallationFailed( const QString& message, const QString& d void FinishedViewStep::setConfigurationMap( const QVariantMap& configurationMap ) { - if ( configurationMap.contains( "restartNowEnabled" ) && - configurationMap.value( "restartNowEnabled" ).type() == QVariant::Bool ) + RestartMode mode = RestartMode::Never; + + QString restartMode = CalamaresUtils::getString( configurationMap, "restartNowMode" ); + if ( restartMode.isEmpty() ) { - bool restartNowEnabled = configurationMap.value( "restartNowEnabled" ).toBool(); + if ( configurationMap.contains( "restartNowEnabled" ) ) + cWarning() << "Configuring the finished module with deprecated restartNowEnabled settings"; - m_widget->setRestartNowEnabled( restartNowEnabled ); - if ( restartNowEnabled ) - { - if ( configurationMap.contains( "restartNowChecked" ) && - configurationMap.value( "restartNowChecked" ).type() == QVariant::Bool ) - m_widget->setRestartNowChecked( configurationMap.value( "restartNowChecked" ).toBool() ); + bool restartNowEnabled = CalamaresUtils::getBool( configurationMap, "restartNowEnabled", false ); + bool restartNowChecked = CalamaresUtils::getBool( configurationMap, "restartNowChecked", false ); - if ( configurationMap.contains( "restartNowCommand" ) && - configurationMap.value( "restartNowCommand" ).type() == QVariant::String ) - m_widget->setRestartNowCommand( configurationMap.value( "restartNowCommand" ).toString() ); - else - m_widget->setRestartNowCommand( "shutdown -r now" ); - } + if ( !restartNowEnabled ) + mode = RestartMode::Never; + else + mode = restartNowChecked ? RestartMode::UserChecked : RestartMode::UserUnchecked; } - if ( configurationMap.contains( "notifyOnFinished" ) && - configurationMap.value( "notifyOnFinished" ).type() == QVariant::Bool ) - m_notifyOnFinished = configurationMap.value( "notifyOnFinished" ).toBool(); + else + { + bool ok = false; + mode = modeNames().find( restartMode, ok ); + if ( !ok ) + cWarning() << "Configuring the finished module with bad restartNowMode" << restartMode; + } + + m_widget->setRestart( mode ); + + if ( mode != RestartMode::Never ) + { + QString restartNowCommand = CalamaresUtils::getString( configurationMap, "restartNowCommand" ); + if ( restartNowCommand.isEmpty() ) + restartNowCommand = QStringLiteral( "shutdown -r now" ); + m_widget->setRestartNowCommand( restartNowCommand ); + } + + m_notifyOnFinished = CalamaresUtils::getBool( configurationMap, "notifyOnFinished", false ); } CALAMARES_PLUGIN_FACTORY_DEFINITION( FinishedViewStepFactory, registerPlugin(); ) diff --git a/src/modules/finished/FinishedViewStep.h b/src/modules/finished/FinishedViewStep.h index b1af598c7..314f6acc6 100644 --- a/src/modules/finished/FinishedViewStep.h +++ b/src/modules/finished/FinishedViewStep.h @@ -1,6 +1,7 @@ /* === This file is part of Calamares - === * * Copyright 2014-2015, Teo Mrnjavac + * 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 @@ -16,15 +17,15 @@ * along with Calamares. If not, see . */ -#ifndef FINISHEDPAGEPLUGIN_H -#define FINISHEDPAGEPLUGIN_H +#ifndef FINISHEDVIEWSTEP_H +#define FINISHEDVIEWSTEP_H #include -#include -#include +#include "utils/PluginFactory.h" +#include "viewpages/ViewStep.h" -#include +#include "PluginDllMacro.h" class FinishedPage; @@ -33,6 +34,14 @@ class PLUGINDLLEXPORT FinishedViewStep : public Calamares::ViewStep Q_OBJECT public: + enum class RestartMode + { + Never=0, ///< @brief Don't show button, just exit + UserUnchecked, ///< @brief Show button, starts unchecked + UserChecked, ///< @brief Show button, starts checked + Always ///< @brief Show button, can't change, checked + }; + explicit FinishedViewStep( QObject* parent = nullptr ); virtual ~FinishedViewStep() override; @@ -70,4 +79,4 @@ private: CALAMARES_PLUGIN_FACTORY_DECLARATION( FinishedViewStepFactory ) -#endif // FINISHEDPAGEPLUGIN_H +#endif diff --git a/src/modules/finished/finished.conf b/src/modules/finished/finished.conf index 29e5e49b4..3b6dd9dd1 100644 --- a/src/modules/finished/finished.conf +++ b/src/modules/finished/finished.conf @@ -1,14 +1,37 @@ # Configuration for the "finished" page, which is usually shown only at # the end of the installation (successful or not). --- +# DEPRECATED +# # The finished page can hold a "restart system now" checkbox. # If this is false, no checkbox is shown and the system is not restarted # when Calamares exits. -restartNowEnabled: true +# restartNowEnabled: true +# DEPRECATED +# # Initial state of the checkbox "restart now". Only relevant when the # checkbox is shown by restartNowEnabled. -restartNowChecked: false +# restartNowChecked: false + +# Behavior of the "restart system now" button. +# +# There are four usable values: +# - never +# Does not show the button and does not restart. +# This matches the old behavior with restartNowEnabled=false. +# - user-unchecked +# Shows the button, defaults to unchecked, restarts if it is checked. +# This matches the old behavior with restartNowEnabled=true and restartNowChecked=false. +# - user-checked +# Shows the button, defaults to checked, restarts if it is checked. +# This matches the old behavior with restartNowEnabled=true and restartNowChecked=true. +# - always +# Shows the button, checked, but the user cannot change it. +# This is new behavior. +# +# The three combinations of legacy values are still supported. +restartNowMode: user-unchecked # If the checkbox is shown, and the checkbox is checked, then when # Calamares exits from the finished-page it will run this command. diff --git a/src/modules/fsresizer/CMakeLists.txt b/src/modules/fsresizer/CMakeLists.txt index 9c1da386b..ba9c81f4c 100644 --- a/src/modules/fsresizer/CMakeLists.txt +++ b/src/modules/fsresizer/CMakeLists.txt @@ -6,8 +6,7 @@ if ( KPMcore_FOUND ) find_package( Qt5 REQUIRED DBus ) # Needed for KPMCore find_package( KF5 REQUIRED I18n WidgetsAddons ) # Needed for KPMCore - include_directories( ${KPMCORE_INCLUDE_DIR} ) - include_directories( ${PROJECT_BINARY_DIR}/src/libcalamares ) + include_directories( ${KPMCORE_INCLUDE_DIR} ${CMAKE_SOURCE_DIR}/src/modules/partition ) if ( KPMcore_VERSION VERSION_GREATER "3.3.0") list( APPEND _partition_defs WITH_KPMCORE331API) # kpmcore > 3.3.0 with deprecations diff --git a/src/modules/fsresizer/ResizeFSJob.cpp b/src/modules/fsresizer/ResizeFSJob.cpp index c8224a4c4..0ab583367 100644 --- a/src/modules/fsresizer/ResizeFSJob.cpp +++ b/src/modules/fsresizer/ResizeFSJob.cpp @@ -37,67 +37,10 @@ #include "utils/Units.h" #include "utils/Variant.h" -#include "modules/partition/core/PartitionIterator.h" +// From partition module +#include "core/PartitionIterator.h" -static const NamedEnumTable& -unitSuffixes() -{ - using Unit = ResizeFSJob::RelativeUnit; - - static const NamedEnumTable names{ - { QStringLiteral( "%" ), Unit::Percent }, - { QStringLiteral( "MiB" ), Unit::Absolute } - }; - - return names; -} - -ResizeFSJob::RelativeSize::RelativeSize( const QString& s ) - : NamedSuffix( unitSuffixes(), s ) -{ - if ( ( unit() == RelativeUnit::Percent ) && ( value() > 100 ) ) - { - cDebug() << "Percent value" << value() << "is not valid."; - m_value = 0; - m_unit = RelativeUnit::None; - } - - if ( !m_value ) - m_unit = RelativeUnit::None; -} - -qint64 -ResizeFSJob::RelativeSize::apply( qint64 totalSectors, qint64 sectorSize ) -{ - if ( !isValid() ) - return -1; - if ( sectorSize < 1 ) - return -1; - - switch ( m_unit ) - { - case unit_t::None: - return -1; - case unit_t::Absolute: - return CalamaresUtils::MiBtoBytes( static_cast( value() ) ) / sectorSize; - case unit_t::Percent: - if ( value() == 100 ) - return totalSectors; // Common-case, avoid futzing around - else - return totalSectors * value() / 100; - } - - // notreached - return -1; -} - -qint64 -ResizeFSJob::RelativeSize::apply( Device* d ) -{ - return apply( d->totalLogical(), d->logicalSize() ); -} - ResizeFSJob::ResizeFSJob( QObject* parent ) : Calamares::CppJob( parent ) , m_required( false ) @@ -202,7 +145,7 @@ ResizeFSJob::findGrownEnd( ResizeFSJob::PartitionMatch m ) qint64 expand = last_available - last_currently; // number of sectors if ( m_atleast.isValid() ) { - qint64 required = m_atleast.apply( m.first ); + qint64 required = m_atleast.toSectors( m.first->totalLogical(), m.first->logicalSize() ); if ( expand < required ) { cDebug() << Logger::SubEntry << "need to expand by" << required << "but only" << expand << "is available."; @@ -210,7 +153,7 @@ ResizeFSJob::findGrownEnd( ResizeFSJob::PartitionMatch m ) } } - qint64 wanted = m_size.apply( expand, m.first->logicalSize() ); + qint64 wanted = m_size.toSectors( expand, m.first->logicalSize() ); if ( wanted < expand ) { cDebug() << Logger::SubEntry << "only growing by" << wanted << "instead of full" << expand; @@ -329,8 +272,8 @@ ResizeFSJob::setConfigurationMap( const QVariantMap& configurationMap ) return; } - m_size = RelativeSize( configurationMap["size"].toString() ); - m_atleast = RelativeSize( configurationMap["atleast"].toString() ); + m_size = Calamares::PartitionSize( configurationMap["size"].toString() ); + m_atleast = Calamares::PartitionSize( configurationMap["atleast"].toString() ); m_required = CalamaresUtils::getBool( configurationMap, "required", false ); } diff --git a/src/modules/fsresizer/ResizeFSJob.h b/src/modules/fsresizer/ResizeFSJob.h index d575f18a9..97696e40b 100644 --- a/src/modules/fsresizer/ResizeFSJob.h +++ b/src/modules/fsresizer/ResizeFSJob.h @@ -24,7 +24,7 @@ #include -#include "utils/NamedSuffix.h" +#include "partition/PartitionSize.h" #include "utils/PluginFactory.h" #include @@ -38,48 +38,6 @@ class PLUGINDLLEXPORT ResizeFSJob : public Calamares::CppJob Q_OBJECT public: - enum class RelativeUnit - { - None, - Percent, - Absolute - }; - - /** @brief Size expressions - * - * Sizes can be specified in MiB or percent (of the device they - * are on). This class handles parsing of such strings from the - * config file. - */ - class RelativeSize : public NamedSuffix - { - public: - RelativeSize() : NamedSuffix() { }; - RelativeSize( const QString& ); - - bool isValid() const - { - return ( unit() != RelativeUnit::None ) && ( value() > 0 ); - } - - /** @brief Apply this size to the number of sectors @p totalSectors . - * - * Each sector has size @p sectorSize , for converting absolute - * sizes in MiB to sector counts. - * - * For invalid sizes, returns -1. - * For absolute sizes, returns the number of sectors needed. - * For percent sizes, returns that percent of the number of sectors. - */ - qint64 apply( qint64 totalSectors, qint64 sectorSize ); - - /** @brief Apply this size to the given device. - * - * Equivalent to apply( d->totalLogical(), d->logicalSize() ) - */ - qint64 apply( Device* d ); - } ; - explicit ResizeFSJob( QObject* parent = nullptr ); virtual ~ResizeFSJob() override; @@ -97,8 +55,8 @@ public: } private: - RelativeSize m_size; - RelativeSize m_atleast; + Calamares::PartitionSize m_size; + Calamares::PartitionSize m_atleast; QString m_fsname; // Either this, or devicename, is set, not both QString m_devicename; bool m_required; diff --git a/src/modules/fsresizer/Tests.cpp b/src/modules/fsresizer/Tests.cpp index 190a1d279..417d30c33 100644 --- a/src/modules/fsresizer/Tests.cpp +++ b/src/modules/fsresizer/Tests.cpp @@ -57,8 +57,8 @@ void FSResizerTests::testConfigurationRobust() j.setConfigurationMap( QVariantMap() ); QVERIFY( j.m_fsname.isEmpty() ); QVERIFY( j.m_devicename.isEmpty() ); - QCOMPARE( j.m_size.unit(), ResizeFSJob::RelativeUnit::None ); - QCOMPARE( j.m_atleast.unit(), ResizeFSJob::RelativeUnit::None ); + QCOMPARE( j.m_size.unit(), Calamares::SizeUnit::None ); + QCOMPARE( j.m_atleast.unit(), Calamares::SizeUnit::None ); // Config is missing fs and dev, so it isn't valid YAML::Node doc0 = YAML::Load( R"(--- @@ -68,8 +68,8 @@ atleast: 600MiB j.setConfigurationMap( CalamaresUtils::yamlMapToVariant( doc0 ).toMap() ); QVERIFY( j.m_fsname.isEmpty() ); QVERIFY( j.m_devicename.isEmpty() ); - QCOMPARE( j.m_size.unit(), ResizeFSJob::RelativeUnit::None ); - QCOMPARE( j.m_atleast.unit(), ResizeFSJob::RelativeUnit::None ); + QCOMPARE( j.m_size.unit(), Calamares::SizeUnit::None ); + QCOMPARE( j.m_atleast.unit(), Calamares::SizeUnit::None ); QCOMPARE( j.m_size.value(), 0 ); QCOMPARE( j.m_atleast.value(), 0 ); } @@ -87,8 +87,8 @@ atleast: 600MiB j.setConfigurationMap( CalamaresUtils::yamlMapToVariant( doc0 ).toMap() ); QVERIFY( !j.m_fsname.isEmpty() ); QVERIFY( j.m_devicename.isEmpty() ); - QCOMPARE( j.m_size.unit(), ResizeFSJob::RelativeUnit::Percent ); - QCOMPARE( j.m_atleast.unit(), ResizeFSJob::RelativeUnit::Absolute ); + QCOMPARE( j.m_size.unit(), Calamares::SizeUnit::Percent ); + QCOMPARE( j.m_atleast.unit(), Calamares::SizeUnit::Percent ); QCOMPARE( j.m_size.value(), 100 ); QCOMPARE( j.m_atleast.value(), 600 ); @@ -102,8 +102,8 @@ atleast: 127 % j.setConfigurationMap( CalamaresUtils::yamlMapToVariant( doc0 ).toMap() ); QVERIFY( !j.m_fsname.isEmpty() ); QVERIFY( !j.m_devicename.isEmpty() ); - QCOMPARE( j.m_size.unit(), ResizeFSJob::RelativeUnit::Absolute ); - QCOMPARE( j.m_atleast.unit(), ResizeFSJob::RelativeUnit::None ); + QCOMPARE( j.m_size.unit(), Calamares::SizeUnit::Percent ); + QCOMPARE( j.m_atleast.unit(), Calamares::SizeUnit::None ); QCOMPARE( j.m_size.value(), 72 ); QCOMPARE( j.m_atleast.value(), 0 ); @@ -117,8 +117,8 @@ size: 71MiB j.setConfigurationMap( CalamaresUtils::yamlMapToVariant( doc0 ).toMap() ); QVERIFY( !j.m_fsname.isEmpty() ); QVERIFY( j.m_devicename.isEmpty() ); - QCOMPARE( j.m_size.unit(), ResizeFSJob::RelativeUnit::Absolute ); - QCOMPARE( j.m_atleast.unit(), ResizeFSJob::RelativeUnit::None ); + QCOMPARE( j.m_size.unit(), Calamares::SizeUnit::Percent ); + QCOMPARE( j.m_atleast.unit(), Calamares::SizeUnit::None ); QCOMPARE( j.m_size.value(), 71 ); QCOMPARE( j.m_atleast.value(), 0 ); } diff --git a/src/modules/keyboard/KeyboardPage.h b/src/modules/keyboard/KeyboardPage.h index 99f8ee449..dca8b869a 100644 --- a/src/modules/keyboard/KeyboardPage.h +++ b/src/modules/keyboard/KeyboardPage.h @@ -24,13 +24,11 @@ #ifndef KEYBOARDPAGE_H #define KEYBOARDPAGE_H -#include "keyboardwidget/keyboardglobal.h" - -#include "Typedefs.h" +#include "Job.h" #include -#include #include +#include namespace Ui { @@ -50,7 +48,7 @@ public: QString prettyStatus() const; - QList< Calamares::job_ptr > createJobs( const QString& xOrgConfFileName, + Calamares::JobList createJobs( const QString& xOrgConfFileName, const QString& convertedKeymapPath, bool writeEtcDefaultKeyboard ); diff --git a/src/modules/locale/LocalePage.h b/src/modules/locale/LocalePage.h index 2a9dc8b60..20ad444c9 100644 --- a/src/modules/locale/LocalePage.h +++ b/src/modules/locale/LocalePage.h @@ -20,9 +20,8 @@ #ifndef LOCALEPAGE_H #define LOCALEPAGE_H -#include "Typedefs.h" - #include "LocaleConfiguration.h" +#include "Job.h" #include @@ -44,7 +43,7 @@ public: QString prettyStatus() const; - QList< Calamares::job_ptr > createJobs(); + Calamares::JobList createJobs(); QMap< QString, QString > localesMap(); diff --git a/src/modules/mount/main.py b/src/modules/mount/main.py index aab3568d1..ed649aead 100644 --- a/src/modules/mount/main.py +++ b/src/modules/mount/main.py @@ -6,6 +6,7 @@ # Copyright 2014, Aurélien Gâteau # Copyright 2017, Alf Gaida # Copyright 2019, Adriaan de Groot +# Copyright 2019, Kevin Kofler # # Calamares is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -22,6 +23,7 @@ import tempfile import subprocess +import os import libcalamares @@ -48,7 +50,15 @@ def mount_partitions(root_mount_point, partitions): continue # Create mount point with `+` rather than `os.path.join()` because # `partition["mountPoint"]` starts with a '/'. - mount_point = root_mount_point + partition["mountPoint"] + raw_mount_point = partition["mountPoint"] + mount_point = root_mount_point + raw_mount_point + + # Ensure that the created directory has the correct SELinux context on + # SELinux-enabled systems. + os.makedirs(mount_point, exist_ok=True) + subprocess.call(['chcon', '--reference=' + raw_mount_point, + mount_point]) + fstype = partition.get("fs", "").lower() if fstype == "fat16" or fstype == "fat32": diff --git a/src/modules/netinstall/NetInstallPage.h b/src/modules/netinstall/NetInstallPage.h index 7ec37e7ac..b2887304b 100644 --- a/src/modules/netinstall/NetInstallPage.h +++ b/src/modules/netinstall/NetInstallPage.h @@ -23,7 +23,6 @@ #include "PackageModel.h" #include "PackageTreeItem.h" -#include "Typedefs.h" #include #include diff --git a/src/modules/oemid/IDJob.cpp b/src/modules/oemid/IDJob.cpp index 07ce1efad..16461b191 100644 --- a/src/modules/oemid/IDJob.cpp +++ b/src/modules/oemid/IDJob.cpp @@ -82,13 +82,12 @@ Calamares::JobResult IDJob::exec() QString targetFile = QStringLiteral( "oem-id" ); QString rootMount = gs->value( "rootMountPoint" ).toString(); - static const char noRoot[] = "No rootMountPoint is set."; - static const char yesRoot[] = "rootMountPoint is set:"; - - QString targetPath; - + // Don't bother translating internal errors if ( rootMount.isEmpty() && Calamares::Settings::instance()->doChroot() ) - cWarning() << Logger::SubEntry << noRoot; - + return Calamares::JobResult::internalError( + "OEM Batch Identifier", + "No rootMountPoint is set, but a chroot is required. " + "Is there a module before oemid that sets up the partitions?", + Calamares::JobResult::InvalidConfiguration ); return writeId( Calamares::Settings::instance()->doChroot() ? rootMount + targetDir : targetDir, targetFile, m_batchIdentifier ); } diff --git a/src/modules/partition/core/PartUtils.cpp b/src/modules/partition/core/PartUtils.cpp index 251fc62db..7b44d3d64 100644 --- a/src/modules/partition/core/PartUtils.cpp +++ b/src/modules/partition/core/PartUtils.cpp @@ -43,216 +43,6 @@ namespace PartUtils { -static const NamedEnumTable& -unitSuffixes() -{ - static const NamedEnumTable names{ - { QStringLiteral( "%" ), SizeUnit::Percent }, - { QStringLiteral( "B" ), SizeUnit::Byte }, - { QStringLiteral( "K" ), SizeUnit::KiB }, - { QStringLiteral( "M" ), SizeUnit::MiB }, - { QStringLiteral( "G" ), SizeUnit::GiB } - }; - - return names; -} - -PartSize::PartSize( const QString& s ) - : NamedSuffix( unitSuffixes(), s ) -{ - if ( ( unit() == SizeUnit::Percent ) && ( value() > 100 || value() < 0 ) ) - { - cDebug() << "Percent value" << value() << "is not valid."; - m_value = 0; - } - - if ( m_unit == SizeUnit::None ) - { - m_value = s.toInt(); - if ( m_value > 0 ) - m_unit = SizeUnit::Byte; - } - - if ( m_value <= 0 ) - { - m_value = 0; - m_unit = SizeUnit::None; - } -} - -qint64 -PartSize::toSectors( qint64 totalSectors, qint64 sectorSize ) const -{ - if ( !isValid() ) - return -1; - if ( totalSectors < 1 || sectorSize < 1 ) - return -1; - - switch ( m_unit ) - { - case unit_t::None: - return -1; - case unit_t::Percent: - if ( value() == 100 ) - return totalSectors; // Common-case, avoid futzing around - else - return totalSectors * value() / 100; - case unit_t::Byte: - case unit_t::KiB: - case unit_t::MiB: - case unit_t::GiB: - return bytesToSectors ( toBytes(), sectorSize ); - } - - return -1; -} - -qint64 -PartSize::toBytes( qint64 totalSectors, qint64 sectorSize ) const -{ - if ( !isValid() ) - return -1; - - switch ( m_unit ) - { - case unit_t::None: - return -1; - case unit_t::Percent: - if ( totalSectors < 1 || sectorSize < 1 ) - return -1; - if ( value() == 100 ) - return totalSectors * sectorSize; // Common-case, avoid futzing around - else - return totalSectors * value() / 100; - case unit_t::Byte: - case unit_t::KiB: - case unit_t::MiB: - case unit_t::GiB: - return toBytes(); - } - - // notreached - return -1; -} - -qint64 -PartSize::toBytes( qint64 totalBytes ) const -{ - if ( !isValid() ) - return -1; - - switch ( m_unit ) - { - case unit_t::None: - return -1; - case unit_t::Percent: - if ( totalBytes < 1 ) - return -1; - if ( value() == 100 ) - return totalBytes; // Common-case, avoid futzing around - else - return totalBytes * value() / 100; - case unit_t::Byte: - case unit_t::KiB: - case unit_t::MiB: - case unit_t::GiB: - return toBytes(); - } - - // notreached - return -1; -} - -qint64 -PartSize::toBytes() const -{ - if ( !isValid() ) - return -1; - - switch ( m_unit ) - { - case unit_t::Byte: - return value(); - case unit_t::KiB: - return CalamaresUtils::KiBtoBytes( static_cast( value() ) ); - case unit_t::MiB: - return CalamaresUtils::MiBtoBytes( static_cast( value() ) ); - case unit_t::GiB: - return CalamaresUtils::GiBtoBytes( static_cast( value() ) ); - default: - break; - } - - // Reached only when unit is Percent or None - return -1; -} - -bool -PartSize::operator< ( const PartSize& other ) const -{ - if ( ( m_unit == SizeUnit::None || other.m_unit == SizeUnit::None ) || - ( m_unit == SizeUnit::Percent && other.m_unit != SizeUnit::Percent ) || - ( m_unit != SizeUnit::Percent && other.m_unit == SizeUnit::Percent ) ) - return false; - - switch ( m_unit ) - { - case SizeUnit::Percent: - return ( m_value < other.m_value ); - case SizeUnit::Byte: - case SizeUnit::KiB: - case SizeUnit::MiB: - case SizeUnit::GiB: - return ( toBytes() < other.toBytes () ); - } - - return false; -} - -bool -PartSize::operator> ( const PartSize& other ) const -{ - if ( ( m_unit == SizeUnit::None || other.m_unit == SizeUnit::None ) || - ( m_unit == SizeUnit::Percent && other.m_unit != SizeUnit::Percent ) || - ( m_unit != SizeUnit::Percent && other.m_unit == SizeUnit::Percent ) ) - return false; - - switch ( m_unit ) - { - case SizeUnit::Percent: - return ( m_value > other.m_value ); - case SizeUnit::Byte: - case SizeUnit::KiB: - case SizeUnit::MiB: - case SizeUnit::GiB: - return ( toBytes() > other.toBytes () ); - } - - return false; -} - -bool -PartSize::operator== ( const PartSize& other ) const -{ - if ( ( m_unit == SizeUnit::None || other.m_unit == SizeUnit::None ) || - ( m_unit == SizeUnit::Percent && other.m_unit != SizeUnit::Percent ) || - ( m_unit != SizeUnit::Percent && other.m_unit == SizeUnit::Percent ) ) - return false; - - switch ( m_unit ) - { - case SizeUnit::Percent: - return ( m_value == other.m_value ); - case SizeUnit::Byte: - case SizeUnit::KiB: - case SizeUnit::MiB: - case SizeUnit::GiB: - return ( toBytes() == other.toBytes () ); - } - - return false; -} - QString convenienceName( const Partition* const candidate ) { @@ -284,7 +74,7 @@ canBeReplaced( Partition* candidate ) bool ok = false; double requiredStorageGB = Calamares::JobQueue::instance() ->globalStorage() - ->value( "requiredStorageGB" ) + ->value( "requiredStorageGiB" ) .toDouble( &ok ); qint64 availableStorageB = candidate->capacity(); @@ -356,7 +146,7 @@ canBeResized( Partition* candidate ) bool ok = false; double requiredStorageGB = Calamares::JobQueue::instance() ->globalStorage() - ->value( "requiredStorageGB" ) + ->value( "requiredStorageGiB" ) .toDouble( &ok ); // We require a little more for partitioning overhead and swap file double advisedStorageGB = requiredStorageGB + 0.5 + 2.0; diff --git a/src/modules/partition/core/PartUtils.h b/src/modules/partition/core/PartUtils.h index 4653468c3..1b4ee0b71 100644 --- a/src/modules/partition/core/PartUtils.h +++ b/src/modules/partition/core/PartUtils.h @@ -36,78 +36,6 @@ class Partition; namespace PartUtils { -using CalamaresUtils::MiBtoBytes; - -enum class SizeUnit -{ - None, - Percent, - Byte, - KiB, - MiB, - GiB -}; - -/** @brief Partition size expressions - * - * Sizes can be specified in bytes, KiB, MiB, GiB or percent (of - * the available drive space are on). This class handles parsing - * of such strings from the config file. - */ -class PartSize : public NamedSuffix -{ -public: - PartSize() : NamedSuffix() { } - PartSize( int v, unit_t u ) : NamedSuffix( v, u ) { } - PartSize( const QString& ); - - bool isValid() const - { - return ( unit() != SizeUnit::None ) && ( value() > 0 ); - } - - bool operator< ( const PartSize& other ) const; - bool operator> ( const PartSize& other ) const; - bool operator== ( const PartSize& other ) const; - - /** @brief Convert the size to the number of sectors @p totalSectors . - * - * Each sector has size @p sectorSize, for converting sizes in Bytes, - * KiB, MiB or GiB to sector counts. - * - * @return the number of sectors needed, or -1 for invalid sizes. - */ - qint64 toSectors( qint64 totalSectors, qint64 sectorSize ) const; - - /** @brief Convert the size to bytes. - * - * The device's sectors count @p totalSectors and sector size - * @p sectoreSize are used to calculated the total size, which - * is then used to calculate the size when using Percent. - * - * @return the size in bytes, or -1 for invalid sizes. - */ - qint64 toBytes( qint64 totalSectors, qint64 sectorSize ) const; - - /** @brief Convert the size to bytes. - * - * Total size @p totalBytes is needed for sizes in Percent. This - * parameter is unused in any other case. - * - * @return the size in bytes, or -1 for invalid sizes. - */ - qint64 toBytes( qint64 totalBytes ) const; - - /** @brief Convert the size to bytes. - * - * This method is only valid for sizes in Bytes, KiB, MiB or GiB. - * It will return -1 in any other case. - * - * @return the size in bytes, or -1 if it cannot be calculated. - */ - qint64 toBytes() const; -}; - /** * @brief Provides a nice human-readable name for @p candidate @@ -171,30 +99,6 @@ bool isEfiBootable( const Partition* candidate ); */ QString findFS( QString fsName, FileSystem::Type* fsType ); -/** - * @brief Convert a partition size to a sectors count. - * @param size the partition size. - * @param unit the partition size unit. - * @param totalSectors the total number of sectors of the selected drive. - * @param logicalSize the sector size, in bytes. - * @return the number of sectors to be used for the given partition size. - */ -qint64 sizeToSectors( double size, SizeUnit unit, qint64 totalSectors, qint64 logicalSize ); - -constexpr qint64 alignBytesToBlockSize( qint64 bytes, qint64 blocksize ) -{ - qint64 blocks = bytes / blocksize; - - if ( blocks * blocksize != bytes ) - ++blocks; - return blocks * blocksize; -} - -constexpr qint64 bytesToSectors( qint64 bytes, qint64 blocksize ) -{ - return alignBytesToBlockSize( alignBytesToBlockSize( bytes, blocksize), MiBtoBytes(1ULL) ) / blocksize; -} - } #endif // PARTUTILS_H diff --git a/src/modules/partition/core/PartitionActions.cpp b/src/modules/partition/core/PartitionActions.cpp index 761b8e4e3..1c89a5b7f 100644 --- a/src/modules/partition/core/PartitionActions.cpp +++ b/src/modules/partition/core/PartitionActions.cpp @@ -103,7 +103,8 @@ doAutopartition( PartitionCoreModule* core, Device* dev, Choices::AutoPartitionO { if ( gs->contains( "efiSystemPartitionSize" ) ) { - PartUtils::PartSize part_size = PartUtils::PartSize( gs->value( "efiSystemPartitionSize" ).toString() ); + Calamares::PartitionSize part_size = Calamares::PartitionSize( + gs->value( "efiSystemPartitionSize" ).toString() ); uefisys_part_sizeB = part_size.toBytes( dev->capacity() ); } else @@ -115,11 +116,11 @@ doAutopartition( PartitionCoreModule* core, Device* dev, Choices::AutoPartitionO // Since sectors count from 0, if the space is 2048 sectors in size, // the first free sector has number 2048 (and there are 2048 sectors // before that one, numbered 0..2047). - qint64 firstFreeSector = PartUtils::bytesToSectors( empty_space_sizeB, dev->logicalSize() ); + qint64 firstFreeSector = CalamaresUtils::bytesToSectors( empty_space_sizeB, dev->logicalSize() ); if ( isEfi ) { - qint64 efiSectorCount = PartUtils::bytesToSectors( uefisys_part_sizeB, dev->logicalSize() ); + qint64 efiSectorCount = CalamaresUtils::bytesToSectors( uefisys_part_sizeB, dev->logicalSize() ); Q_ASSERT( efiSectorCount > 0 ); // Since sectors count from 0, and this partition is created starting diff --git a/src/modules/partition/core/PartitionCoreModule.cpp b/src/modules/partition/core/PartitionCoreModule.cpp index 183fdfcac..6dd2b6faf 100644 --- a/src/modules/partition/core/PartitionCoreModule.cpp +++ b/src/modules/partition/core/PartitionCoreModule.cpp @@ -50,7 +50,6 @@ #ifdef DEBUG_PARTITION_LAME #include "JobExample.h" #endif -#include "Typedefs.h" #include "utils/Logger.h" // KPMcore @@ -946,9 +945,12 @@ PartitionCoreModule::revertDevice( Device* dev, bool individualRevert ) m_deviceModel->swapDevice( dev, newDev ); QList< Device* > devices; - for ( auto info : m_deviceInfos ) + for ( DeviceInfo* const info : m_deviceInfos ) { - if ( info->device.data()->type() != Device::Type::Disk_Device ) + // device is a QScopedPointer + if ( !info || info->device.isNull() ) + continue; + if ( info->device->type() != Device::Type::Disk_Device ) continue; else devices.append( info->device.data() ); diff --git a/src/modules/partition/core/PartitionCoreModule.h b/src/modules/partition/core/PartitionCoreModule.h index aebf9835f..906119a74 100644 --- a/src/modules/partition/core/PartitionCoreModule.h +++ b/src/modules/partition/core/PartitionCoreModule.h @@ -24,7 +24,8 @@ #include "core/KPMHelpers.h" #include "core/PartitionLayout.h" #include "core/PartitionModel.h" -#include "Typedefs.h" + +#include "Job.h" // KPMcore #include @@ -172,7 +173,7 @@ public: * requested by the user. * @return a list of jobs. */ - QList< Calamares::job_ptr > jobs() const; + Calamares::JobList jobs() const; bool hasRootMountPoint() const; diff --git a/src/modules/partition/core/PartitionIterator.cpp b/src/modules/partition/core/PartitionIterator.cpp index 8301835c6..34471f6f2 100644 --- a/src/modules/partition/core/PartitionIterator.cpp +++ b/src/modules/partition/core/PartitionIterator.cpp @@ -98,7 +98,7 @@ PartitionIterator::begin( PartitionTable* table ) { auto it = PartitionIterator( table ); QList< Partition* > children = table->children(); - // Does not usually happen, but it did happen on a 10MB disk with an MBR + // Does not usually happen, but it did happen on a tiny (10MiB) disk with an MBR // partition table. if ( children.isEmpty() ) return it; diff --git a/src/modules/partition/core/PartitionLayout.cpp b/src/modules/partition/core/PartitionLayout.cpp index 35a540a96..a988da3f7 100644 --- a/src/modules/partition/core/PartitionLayout.cpp +++ b/src/modules/partition/core/PartitionLayout.cpp @@ -87,9 +87,9 @@ PartitionLayout::addEntry( PartitionLayout::PartitionEntry entry ) PartitionLayout::PartitionEntry::PartitionEntry( const QString& size, const QString& min, const QString& max ) { - partSize = PartUtils::PartSize( size ); - partMinSize = PartUtils::PartSize( min ); - partMaxSize = PartUtils::PartSize( max ); + partSize = Calamares::PartitionSize( size ); + partMinSize = Calamares::PartitionSize( min ); + partMaxSize = Calamares::PartitionSize( max ); } bool diff --git a/src/modules/partition/core/PartitionLayout.h b/src/modules/partition/core/PartitionLayout.h index 626c90b66..74bc09873 100644 --- a/src/modules/partition/core/PartitionLayout.h +++ b/src/modules/partition/core/PartitionLayout.h @@ -20,9 +20,9 @@ #ifndef PARTITIONLAYOUT_H #define PARTITIONLAYOUT_H -#include "core/PartUtils.h" +#include "partition/PartitionSize.h" -#include "Typedefs.h" +#include "core/PartUtils.h" // KPMcore #include @@ -43,9 +43,9 @@ public: QString partLabel; QString partMountPoint; FileSystem::Type partFileSystem = FileSystem::Unknown; - PartUtils::PartSize partSize; - PartUtils::PartSize partMinSize; - PartUtils::PartSize partMaxSize; + Calamares::PartitionSize partSize; + Calamares::PartitionSize partMinSize; + Calamares::PartitionSize partMaxSize; /// @brief All-zeroes PartitionEntry PartitionEntry() {} diff --git a/src/modules/partition/gui/ChoicePage.cpp b/src/modules/partition/gui/ChoicePage.cpp index 8ec048f0e..04eec56ed 100644 --- a/src/modules/partition/gui/ChoicePage.cpp +++ b/src/modules/partition/gui/ChoicePage.cpp @@ -462,7 +462,7 @@ ChoicePage::applyActionChoice( ChoicePage::InstallChoice choice ) gs->value( "defaultFileSystemType" ).toString(), m_encryptWidget->passphrase(), gs->value( "efiSystemPartition" ).toString(), - CalamaresUtils::GiBtoBytes( gs->value( "requiredStorageGB" ).toDouble() ), + CalamaresUtils::GiBtoBytes( gs->value( "requiredStorageGiB" ).toDouble() ), m_eraseSwapChoice }; @@ -560,11 +560,10 @@ ChoicePage::doAlongsideSetupSplitter( const QModelIndex& current, double requiredStorageGB = Calamares::JobQueue::instance() ->globalStorage() - ->value( "requiredStorageGB" ) + ->value( "requiredStorageGiB" ) .toDouble(); - // TODO: make this consistent - qint64 requiredStorageB = qRound64( requiredStorageGB + 0.1 + 2.0 ) * 1024 * 1024 * 1024; + qint64 requiredStorageB = CalamaresUtils::GiBtoBytes( requiredStorageGB + 0.1 + 2.0 ); m_afterPartitionSplitterWidget->setSplitPartition( part->partitionPath(), @@ -967,11 +966,11 @@ ChoicePage::updateActionChoicePreview( ChoicePage::InstallChoice choice ) qint64 sizeNext ) { Q_UNUSED( path ) - sizeLabel->setText( tr( "%1 will be shrunk to %2MB and a new " - "%3MB partition will be created for %4." ) + sizeLabel->setText( tr( "%1 will be shrunk to %2MiB and a new " + "%3MiB partition will be created for %4." ) .arg( m_beforePartitionBarsView->selectionModel()->currentIndex().data().toString() ) - .arg( size / ( 1024 * 1024 ) ) - .arg( sizeNext / ( 1024 * 1024 ) ) + .arg( CalamaresUtils::BytesToMiB( size ) ) + .arg( CalamaresUtils::BytesToMiB( sizeNext ) ) .arg( *Calamares::Branding::ShortProductName ) ); } ); diff --git a/src/modules/partition/gui/PartitionLabelsView.cpp b/src/modules/partition/gui/PartitionLabelsView.cpp index b5fd0fc91..f47dc41e1 100644 --- a/src/modules/partition/gui/PartitionLabelsView.cpp +++ b/src/modules/partition/gui/PartitionLabelsView.cpp @@ -19,11 +19,12 @@ #include "PartitionLabelsView.h" -#include -#include +#include "core/PartitionModel.h" +#include "core/ColorUtils.h" -#include -#include +#include "utils/CalamaresUtilsGui.h" +#include "utils/Logger.h" +#include "utils/Units.h" #include #include @@ -35,6 +36,7 @@ #include #include +using CalamaresUtils::operator""_MiB; static const int LAYOUT_MARGIN = 4; static const int LABEL_PARTITION_SQUARE_MARGIN = @@ -62,12 +64,6 @@ PartitionLabelsView::PartitionLabelsView( QWidget* parent ) setSelectionBehavior( QAbstractItemView::SelectRows ); setSelectionMode( QAbstractItemView::SingleSelection ); this->setObjectName("partitionLabel"); - // Debug - connect( this, &PartitionLabelsView::clicked, - this, [=]( const QModelIndex& index ) - { - cDebug() << "Clicked row" << index.row(); - } ); setMouseTracking( true ); } @@ -162,8 +158,8 @@ PartitionLabelsView::getIndexesToDraw( const QModelIndex& parent ) const //HACK: horrible special casing follows. // To save vertical space, we choose to hide short instances of free space. - // Arbitrary limit: 10MB. - const qint64 maxHiddenB = 10000000; + // Arbitrary limit: 10MiB. + const qint64 maxHiddenB = 10_MiB; if ( index.data( PartitionModel::IsFreeSpaceRole ).toBool() && index.data( PartitionModel::SizeRole ).toLongLong() < maxHiddenB ) continue; diff --git a/src/modules/partition/gui/ReplaceWidget.cpp b/src/modules/partition/gui/ReplaceWidget.cpp index 13001468f..2ee360ced 100644 --- a/src/modules/partition/gui/ReplaceWidget.cpp +++ b/src/modules/partition/gui/ReplaceWidget.cpp @@ -143,7 +143,7 @@ ReplaceWidget::onPartitionSelected() bool ok = false; double requiredSpaceB = Calamares::JobQueue::instance() ->globalStorage() - ->value( "requiredStorageGB" ) + ->value( "requiredStorageGiB" ) .toDouble( &ok ) * 1024 * 1024 * 1024; PartitionModel* model = qobject_cast< PartitionModel* >( m_ui->partitionTreeView->model() ); diff --git a/src/modules/partition/jobs/ClearMountsJob.cpp b/src/modules/partition/jobs/ClearMountsJob.cpp index da6bee325..605087147 100644 --- a/src/modules/partition/jobs/ClearMountsJob.cpp +++ b/src/modules/partition/jobs/ClearMountsJob.cpp @@ -2,6 +2,7 @@ * * Copyright 2014-2015, Teo Mrnjavac * Copyright 2018, Adriaan de Groot + * Copyright 2019, Kevin Kofler * * Calamares is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -258,7 +259,11 @@ ClearMountsJob::getCryptoDevices() const QProcess process; for ( const QFileInfo &fi : fiList ) { - if ( fi.baseName() == "control" ) + QString baseName = fi.baseName(); + // Fedora live images use /dev/mapper/live-* internally. We must not + // unmount those devices, because they are used by the live image and + // because we need /dev/mapper/live-base in the unpackfs module. + if ( baseName == "control" || baseName.startsWith( "live-" ) ) continue; list.append( fi.absoluteFilePath() ); } diff --git a/src/modules/partition/jobs/CreatePartitionJob.cpp b/src/modules/partition/jobs/CreatePartitionJob.cpp index 119ecb12c..9f8a01004 100644 --- a/src/modules/partition/jobs/CreatePartitionJob.cpp +++ b/src/modules/partition/jobs/CreatePartitionJob.cpp @@ -41,7 +41,7 @@ CreatePartitionJob::CreatePartitionJob( Device* device, Partition* partition ) QString CreatePartitionJob::prettyName() const { - return tr( "Create new %2MB partition on %4 (%3) with file system %1." ) + return tr( "Create new %2MiB partition on %4 (%3) with file system %1." ) .arg( m_partition->fileSystem().name() ) .arg( CalamaresUtils::BytesToMiB( m_partition->capacity() ) ) .arg( m_device->name() ) @@ -52,7 +52,7 @@ CreatePartitionJob::prettyName() const QString CreatePartitionJob::prettyDescription() const { - return tr( "Create new %2MB partition on %4 " + return tr( "Create new %2MiB partition on %4 " "(%3) with file system %1." ) .arg( m_partition->fileSystem().name() ) .arg( CalamaresUtils::BytesToMiB( m_partition->capacity() ) ) diff --git a/src/modules/partition/jobs/FormatPartitionJob.cpp b/src/modules/partition/jobs/FormatPartitionJob.cpp index dcc1c7142..0d43dfdb3 100644 --- a/src/modules/partition/jobs/FormatPartitionJob.cpp +++ b/src/modules/partition/jobs/FormatPartitionJob.cpp @@ -38,7 +38,7 @@ FormatPartitionJob::FormatPartitionJob( Device* device, Partition* partition ) QString FormatPartitionJob::prettyName() const { - return tr( "Format partition %1 (file system: %2, size: %3 MB) on %4." ) + return tr( "Format partition %1 (file system: %2, size: %3 MiB) on %4." ) .arg( m_partition->partitionPath() ) .arg( m_partition->fileSystem().name() ) .arg( m_partition->capacity() / 1024 / 1024 ) @@ -49,7 +49,7 @@ FormatPartitionJob::prettyName() const QString FormatPartitionJob::prettyDescription() const { - return tr( "Format %3MB partition %1 with " + return tr( "Format %3MiB partition %1 with " "file system %2." ) .arg( m_partition->partitionPath() ) .arg( m_partition->fileSystem().name() ) diff --git a/src/modules/partition/jobs/ResizePartitionJob.cpp b/src/modules/partition/jobs/ResizePartitionJob.cpp index c0477cafe..bac4c7a6c 100644 --- a/src/modules/partition/jobs/ResizePartitionJob.cpp +++ b/src/modules/partition/jobs/ResizePartitionJob.cpp @@ -52,8 +52,8 @@ ResizePartitionJob::prettyName() const QString ResizePartitionJob::prettyDescription() const { - return tr( "Resize %2MB partition %1 to " - "%3MB." ) + return tr( "Resize %2MiB partition %1 to " + "%3MiB." ) .arg( partition()->partitionPath() ) .arg( ( BytesToMiB( m_oldLastSector - m_oldFirstSector + 1 ) * partition()->sectorSize() ) ) .arg( ( BytesToMiB( m_newLastSector - m_newFirstSector + 1 ) * partition()->sectorSize() ) ); @@ -63,8 +63,8 @@ ResizePartitionJob::prettyDescription() const QString ResizePartitionJob::prettyStatusMessage() const { - return tr( "Resizing %2MB partition %1 to " - "%3MB." ) + return tr( "Resizing %2MiB partition %1 to " + "%3MiB." ) .arg( partition()->partitionPath() ) .arg( ( BytesToMiB( m_oldLastSector - m_oldFirstSector + 1 ) * partition()->sectorSize() ) ) .arg( ( BytesToMiB( m_newLastSector - m_newFirstSector + 1 ) * partition()->sectorSize() ) ); diff --git a/src/modules/partition/jobs/SetPartitionFlagsJob.cpp b/src/modules/partition/jobs/SetPartitionFlagsJob.cpp index fee987479..d79f70479 100644 --- a/src/modules/partition/jobs/SetPartitionFlagsJob.cpp +++ b/src/modules/partition/jobs/SetPartitionFlagsJob.cpp @@ -49,7 +49,7 @@ SetPartFlagsJob::prettyName() const return tr( "Set flags on partition %1." ).arg( partition()->partitionPath() ); if ( !partition()->fileSystem().name().isEmpty() ) - return tr( "Set flags on %1MB %2 partition." ) + return tr( "Set flags on %1MiB %2 partition." ) .arg( BytesToMiB( partition()->capacity() ) ) .arg( partition()->fileSystem().name() ); @@ -68,7 +68,7 @@ SetPartFlagsJob::prettyDescription() const .arg( partition()->partitionPath() ); if ( !partition()->fileSystem().name().isEmpty() ) - return tr( "Clear flags on %1MB %2 partition." ) + return tr( "Clear flags on %1MiB %2 partition." ) .arg( BytesToMiB( partition()->capacity() ) ) .arg( partition()->fileSystem().name() ); @@ -82,7 +82,7 @@ SetPartFlagsJob::prettyDescription() const .arg( flagsList.join( ", " ) ); if ( !partition()->fileSystem().name().isEmpty() ) - return tr( "Flag %1MB %2 partition as " + return tr( "Flag %1MiB %2 partition as " "%3." ) .arg( BytesToMiB( partition()->capacity() ) ) .arg( partition()->fileSystem().name() ) @@ -104,7 +104,7 @@ SetPartFlagsJob::prettyStatusMessage() const .arg( partition()->partitionPath() ); if ( !partition()->fileSystem().name().isEmpty() ) - return tr( "Clearing flags on %1MB %2 partition." ) + return tr( "Clearing flags on %1MiB %2 partition." ) .arg( BytesToMiB( partition()->capacity() ) ) .arg( partition()->fileSystem().name() ); @@ -119,7 +119,7 @@ SetPartFlagsJob::prettyStatusMessage() const if ( !partition()->fileSystem().name().isEmpty() ) return tr( "Setting flags %3 on " - "%1MB %2 partition." ) + "%1MiB %2 partition." ) .arg( BytesToMiB( partition()->capacity() ) ) .arg( partition()->fileSystem().name() ) .arg( flagsList.join( ", " ) ); diff --git a/src/modules/partition/tests/PartitionJobTests.cpp b/src/modules/partition/tests/PartitionJobTests.cpp index ac867bcb0..e4707accf 100644 --- a/src/modules/partition/tests/PartitionJobTests.cpp +++ b/src/modules/partition/tests/PartitionJobTests.cpp @@ -72,6 +72,7 @@ private: bool m_mounted; }; +/// @brief Generate random data of given @p size as a QByteArray static QByteArray generateTestData( qint64 size ) { @@ -321,10 +322,10 @@ PartitionJobTests::testCreatePartitionExtended() void PartitionJobTests::testResizePartition_data() { - QTest::addColumn< int >( "oldStartMB" ); - QTest::addColumn< int >( "oldSizeMB" ); - QTest::addColumn< int >( "newStartMB" ); - QTest::addColumn< int >( "newSizeMB" ); + QTest::addColumn< int >( "oldStartMiB" ); + QTest::addColumn< int >( "oldSizeMiB" ); + QTest::addColumn< int >( "newStartMiB" ); + QTest::addColumn< int >( "newSizeMiB" ); QTest::newRow("grow") << 10 << 50 << 10 << 70; QTest::newRow("shrink") << 10 << 70 << 10 << 50; @@ -335,22 +336,22 @@ PartitionJobTests::testResizePartition_data() void PartitionJobTests::testResizePartition() { - QFETCH( int, oldStartMB ); - QFETCH( int, oldSizeMB ); - QFETCH( int, newStartMB ); - QFETCH( int, newSizeMB ); + QFETCH( int, oldStartMiB ); + QFETCH( int, oldSizeMiB ); + QFETCH( int, newStartMiB ); + QFETCH( int, newSizeMiB ); - const qint64 sectorForMB = 1_MiB / m_device->logicalSize(); + const qint64 sectorsPerMiB = 1_MiB / m_device->logicalSize(); - qint64 oldFirst = sectorForMB * oldStartMB; - qint64 oldLast = oldFirst + sectorForMB * oldSizeMB - 1; - qint64 newFirst = sectorForMB * newStartMB; - qint64 newLast = newFirst + sectorForMB * newSizeMB - 1; + qint64 oldFirst = sectorsPerMiB * oldStartMiB; + qint64 oldLast = oldFirst + sectorsPerMiB * oldSizeMiB - 1; + qint64 newFirst = sectorsPerMiB * newStartMiB; + qint64 newLast = newFirst + sectorsPerMiB * newSizeMiB - 1; // Make the test data file smaller than the full size of the partition to // accomodate for the file system overhead - const unsigned long long minSizeMB = qMin( oldSizeMB, newSizeMB ); - const QByteArray testData = generateTestData( CalamaresUtils::MiBtoBytes( minSizeMB ) * 3 / 4 ); + const unsigned long long minSizeMiB = qMin( oldSizeMiB, newSizeMiB ); + const QByteArray testData = generateTestData( CalamaresUtils::MiBtoBytes( minSizeMiB ) * 3 / 4 ); const QString testName = "test.data"; // Setup: create the test partition diff --git a/src/modules/summary/SummaryPage.h b/src/modules/summary/SummaryPage.h index c165d3e33..b9a98f2a1 100644 --- a/src/modules/summary/SummaryPage.h +++ b/src/modules/summary/SummaryPage.h @@ -19,7 +19,7 @@ #ifndef SUMMARYPAGE_H #define SUMMARYPAGE_H -#include "Typedefs.h" +#include "viewpages/ViewStep.h" #include diff --git a/src/modules/umount/umount.conf b/src/modules/umount/umount.conf index 798dfc3f5..22a2e7441 100644 --- a/src/modules/umount/umount.conf +++ b/src/modules/umount/umount.conf @@ -10,7 +10,7 @@ # destLog location in the target system to copy the log # # You can either use the default source path (which is -# `/root/.cache/Calamares/Calamares/Calamares.log` ) to copy the regular log, +# `/root/.cache/calamares/session.log` ) to copy the regular log, # or if you want to use the full output of `sudo calamares -d` you will need # to redirect standard output, for instance in a launcher script or # in the desktop file. @@ -34,7 +34,7 @@ --- # example when using the normal Calamares log: -srcLog: "/root/.cache/Calamares/Calamares/Calamares.log" +srcLog: "/root/.cache/calamares/session.log" destLog: "/var/log/Calamares.log" # example when using a log created by `sudo calamares -d`: diff --git a/src/modules/unpackfs/main.py b/src/modules/unpackfs/main.py index dd9439a2c..ac90a994e 100644 --- a/src/modules/unpackfs/main.py +++ b/src/modules/unpackfs/main.py @@ -7,6 +7,7 @@ # Copyright 2014, Daniel Hillenbrand # Copyright 2014, Philip Müller # Copyright 2017, Alf Gaida +# Copyright 2019, Kevin Kofler # # Calamares is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -252,13 +253,19 @@ class UnpackOperation: subprocess.check_call(["mount", "--bind", entry.source, imgmountdir]) - else: + elif os.path.isfile(entry.source): subprocess.check_call(["mount", entry.source, imgmountdir, "-t", entry.sourcefs, "-o", "loop" ]) + else: # entry.source is a device + subprocess.check_call(["mount", + entry.source, + imgmountdir, + "-t", entry.sourcefs + ]) def unpack_image(self, entry, imgmountdir): """ diff --git a/src/modules/users/UsersPage.h b/src/modules/users/UsersPage.h index a238461ec..ac1e1f9db 100644 --- a/src/modules/users/UsersPage.h +++ b/src/modules/users/UsersPage.h @@ -24,9 +24,8 @@ #ifndef USERSPAGE_H #define USERSPAGE_H -#include "Typedefs.h" - #include "CheckPWQuality.h" +#include "Job.h" #include @@ -44,7 +43,7 @@ public: bool isReady(); - QList< Calamares::job_ptr > createJobs( const QStringList& defaultGroupsList ); + Calamares::JobList createJobs( const QStringList& defaultGroupsList ); void onActivate(); diff --git a/src/modules/welcome/checker/GeneralRequirements.cpp b/src/modules/welcome/checker/GeneralRequirements.cpp index 675d43ed4..812605091 100644 --- a/src/modules/welcome/checker/GeneralRequirements.cpp +++ b/src/modules/welcome/checker/GeneralRequirements.cpp @@ -56,8 +56,8 @@ GeneralRequirements::GeneralRequirements( QObject* parent ) : QObject( parent ) - , m_requiredStorageGB( -1 ) - , m_requiredRamGB( -1 ) + , m_requiredStorageGiB( -1 ) + , m_requiredRamGiB( -1 ) { } @@ -72,12 +72,12 @@ Calamares::RequirementsList GeneralRequirements::checkRequirements() bool isRoot = false; bool enoughScreen = (availableSize.width() >= CalamaresUtils::windowMinimumWidth) && (availableSize.height() >= CalamaresUtils::windowMinimumHeight); - qint64 requiredStorageB = CalamaresUtils::GiBtoBytes(m_requiredStorageGB); + qint64 requiredStorageB = CalamaresUtils::GiBtoBytes(m_requiredStorageGiB); cDebug() << "Need at least storage bytes:" << requiredStorageB; if ( m_entriesToCheck.contains( "storage" ) ) enoughStorage = checkEnoughStorage( requiredStorageB ); - qint64 requiredRamB = CalamaresUtils::GiBtoBytes(m_requiredRamGB); + qint64 requiredRamB = CalamaresUtils::GiBtoBytes(m_requiredRamGiB); cDebug() << "Need at least ram bytes:" << requiredRamB; if ( m_entriesToCheck.contains( "ram" ) ) enoughRam = checkEnoughRam( requiredRamB ); @@ -105,16 +105,16 @@ Calamares::RequirementsList GeneralRequirements::checkRequirements() if ( entry == "storage" ) checkEntries.append( { entry, - [req=m_requiredStorageGB]{ return tr( "has at least %1 GB available drive space" ).arg( req ); }, - [req=m_requiredStorageGB]{ return tr( "There is not enough drive space. At least %1 GB is required." ).arg( req ); }, + [req=m_requiredStorageGiB]{ return tr( "has at least %1 GiB available drive space" ).arg( req ); }, + [req=m_requiredStorageGiB]{ return tr( "There is not enough drive space. At least %1 GiB is required." ).arg( req ); }, enoughStorage, m_entriesToRequire.contains( entry ) } ); else if ( entry == "ram" ) checkEntries.append( { entry, - [req=m_requiredRamGB]{ return tr( "has at least %1 GB working memory" ).arg( req ); }, - [req=m_requiredRamGB]{ return tr( "The system does not have enough working memory. At least %1 GB is required." ).arg( req ); }, + [req=m_requiredRamGiB]{ return tr( "has at least %1 GiB working memory" ).arg( req ); }, + [req=m_requiredRamGiB]{ return tr( "The system does not have enough working memory. At least %1 GiB is required." ).arg( req ); }, enoughRam, m_entriesToRequire.contains( entry ) } ); @@ -209,19 +209,19 @@ GeneralRequirements::setConfigurationMap( const QVariantMap& configurationMap ) configurationMap.value( "requiredStorage" ).type() == QVariant::Int ) ) { bool ok = false; - m_requiredStorageGB = configurationMap.value( "requiredStorage" ).toDouble( &ok ); + m_requiredStorageGiB = configurationMap.value( "requiredStorage" ).toDouble( &ok ); if ( !ok ) { cWarning() << "GeneralRequirements entry 'requiredStorage' is invalid."; - m_requiredStorageGB = 3.; + m_requiredStorageGiB = 3.; } - Calamares::JobQueue::instance()->globalStorage()->insert( "requiredStorageGB", m_requiredStorageGB ); + Calamares::JobQueue::instance()->globalStorage()->insert( "requiredStorageGiB", m_requiredStorageGiB ); } else { cWarning() << "GeneralRequirements entry 'requiredStorage' is missing."; - m_requiredStorageGB = 3.; + m_requiredStorageGiB = 3.; incompleteConfiguration = true; } @@ -230,18 +230,18 @@ GeneralRequirements::setConfigurationMap( const QVariantMap& configurationMap ) configurationMap.value( "requiredRam" ).type() == QVariant::Int ) ) { bool ok = false; - m_requiredRamGB = configurationMap.value( "requiredRam" ).toDouble( &ok ); + m_requiredRamGiB = configurationMap.value( "requiredRam" ).toDouble( &ok ); if ( !ok ) { cWarning() << "GeneralRequirements entry 'requiredRam' is invalid."; - m_requiredRamGB = 1.; + m_requiredRamGiB = 1.; incompleteConfiguration = true; } } else { cWarning() << "GeneralRequirements entry 'requiredRam' is missing."; - m_requiredRamGB = 1.; + m_requiredRamGiB = 1.; incompleteConfiguration = true; } diff --git a/src/modules/welcome/checker/GeneralRequirements.h b/src/modules/welcome/checker/GeneralRequirements.h index fe0d7a94d..1efe118a6 100644 --- a/src/modules/welcome/checker/GeneralRequirements.h +++ b/src/modules/welcome/checker/GeneralRequirements.h @@ -46,8 +46,8 @@ private: bool checkHasInternet(); bool checkIsRoot(); - qreal m_requiredStorageGB; - qreal m_requiredRamGB; + qreal m_requiredStorageGiB; + qreal m_requiredRamGiB; QString m_checkHasInternetUrl; }; diff --git a/src/modules/welcome/checker/partman_devices.c b/src/modules/welcome/checker/partman_devices.c index 7a7463857..4fd3dd4c0 100644 --- a/src/modules/welcome/checker/partman_devices.c +++ b/src/modules/welcome/checker/partman_devices.c @@ -66,7 +66,7 @@ is_cdrom(const char *path) int fd; fd = open(path, O_RDONLY | O_NONBLOCK); - ioctl(fd, CDIOCCAPABILITY, NULL); + ioctl(fd, CDIOCCAPABILITY, NULL); close(fd); if (errno != EBADF && errno != ENOTTY) @@ -120,7 +120,7 @@ check_big_enough(long long required_space) for (dev = NULL; NULL != (dev = ped_device_get_next(dev));) { long long dev_size = process_device(dev); - if (dev_size > required_space) + if (dev_size >= required_space) { big_enough = true; break; diff --git a/src/modules/welcome/welcome.conf b/src/modules/welcome/welcome.conf index fcef45a59..6d9a307fc 100644 --- a/src/modules/welcome/welcome.conf +++ b/src/modules/welcome/welcome.conf @@ -15,12 +15,12 @@ showReleaseNotesUrl: true # that are checked. They may not match with the actual requirements # imposed by other modules in the system. requirements: - # Amount of available disk, in GB. Floating-point is allowed here. + # Amount of available disk, in GiB. Floating-point is allowed here. # Note that this does not account for *usable* disk, so it is possible # to pass this requirement, yet have no space to install to. requiredStorage: 5.5 - # Amount of available RAM, in GB. Floating-point is allowed here. + # Amount of available RAM, in GiB. Floating-point is allowed here. requiredRam: 1.0 # To check for internet connectivity, Calamares does a HTTP GET