Merge branch 'calamares' of https://github.com/calamares/calamares into development
This commit is contained in:
commit
3e130c3e36
@ -28,8 +28,9 @@ PointerAlignment: Left
|
||||
ReflowComments: "false"
|
||||
SortIncludes: "true"
|
||||
SpaceAfterCStyleCast: "false"
|
||||
SpaceInEmptyBlock: "false"
|
||||
SpacesBeforeTrailingComments: "2"
|
||||
SpacesInAngles: "true"
|
||||
SpacesInParentheses: "true"
|
||||
SpacesInSquareBrackets: "true"
|
||||
Standard: Cpp11
|
||||
Standard: c++17
|
||||
|
@ -1,35 +0,0 @@
|
||||
# SPDX-FileCopyrightText: no
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
---
|
||||
BasedOnStyle: WebKit
|
||||
|
||||
AlignAfterOpenBracket: Align
|
||||
AlignEscapedNewlines: DontAlign
|
||||
AllowAllParametersOfDeclarationOnNextLine: "false"
|
||||
AllowShortFunctionsOnASingleLine: Inline
|
||||
AllowShortIfStatementsOnASingleLine: "false"
|
||||
AllowShortLambdasOnASingleLine: All
|
||||
AllowShortLoopsOnASingleLine: "false"
|
||||
AlwaysBreakAfterReturnType: TopLevelDefinitions
|
||||
AlwaysBreakTemplateDeclarations: Yes
|
||||
BinPackArguments: "false"
|
||||
BinPackParameters: "false"
|
||||
BreakBeforeBraces: Allman
|
||||
BreakBeforeTernaryOperators: "true"
|
||||
BreakConstructorInitializers: BeforeComma
|
||||
ColumnLimit: 120
|
||||
Cpp11BracedListStyle: "false"
|
||||
FixNamespaceComments: "true"
|
||||
IncludeBlocks: Preserve
|
||||
IndentWidth: "4"
|
||||
MaxEmptyLinesToKeep: "2"
|
||||
NamespaceIndentation: None
|
||||
PointerAlignment: Left
|
||||
ReflowComments: "false"
|
||||
SortIncludes: "true"
|
||||
SpaceAfterCStyleCast: "false"
|
||||
SpacesBeforeTrailingComments: "2"
|
||||
SpacesInAngles: "true"
|
||||
SpacesInParentheses: "true"
|
||||
SpacesInSquareBrackets: "true"
|
||||
Standard: Cpp11
|
31
CHANGES-3.2
31
CHANGES-3.2
@ -7,7 +7,7 @@ contributors are listed. Note that Calamares does not have a historical
|
||||
changelog -- this log starts with version 3.2.0. The release notes on the
|
||||
website will have to do for older versions.
|
||||
|
||||
# 3.2.51 (unreleased) #
|
||||
# 3.2.52 (unreleased) #
|
||||
|
||||
This release contains contributions from (alphabetically by first name):
|
||||
- No external contributors yet
|
||||
@ -16,6 +16,35 @@ This release contains contributions from (alphabetically by first name):
|
||||
- No core changes yet
|
||||
|
||||
## Modules ##
|
||||
- No module changes yet
|
||||
|
||||
|
||||
# 3.2.51 (2022-02-01) #
|
||||
|
||||
This release contains contributions from (alphabetically by first name):
|
||||
- Evan James
|
||||
|
||||
**WARNING** The *umount* module has been rewritten in C++. Check your
|
||||
configuration if you previously used the copy-a-log functionality.
|
||||
|
||||
## Core ##
|
||||
- Evan has made a start on documenting which Global Storage keys there
|
||||
are and how they tie modules together. This can be found in the
|
||||
`src/modules/README.md` documentation.
|
||||
|
||||
## Modules ##
|
||||
- *bootloader* can now be configured to try to generate a unique
|
||||
suffix for the bootloader-id. #1820
|
||||
- *grubcfg* now has a configurable default for kernel parameters,
|
||||
which allows distributions to change the value from `quiet`.
|
||||
The default, if nothing is set, remains `quiet`. Use an explicitly-
|
||||
empty list to specify no-arguments-at-all.
|
||||
- *packagechooser* can now export its choices for use by the *netinstall*
|
||||
module. This makes it possible to use *packagechooser* for large-scale
|
||||
choices, followed by *netinstall* for fine-grained control. (Thanks Evan)
|
||||
- When the *partition* module has a conflicting configuration for the
|
||||
swap choices, it prints a warning and uses the configured choice, rather
|
||||
than always using "suspend". #1881
|
||||
- The *umount* module has been re-written in C++. The copy-a-log-file
|
||||
functionality has been removed. Use the *preservefiles* module for that.
|
||||
|
||||
|
@ -41,7 +41,7 @@
|
||||
# TODO:3.3: Require CMake 3.12
|
||||
cmake_minimum_required( VERSION 3.3 FATAL_ERROR )
|
||||
project( CALAMARES
|
||||
VERSION 3.2.51
|
||||
VERSION 3.2.52
|
||||
LANGUAGES C CXX
|
||||
)
|
||||
|
||||
|
@ -19,12 +19,12 @@ BASEDIR=$(dirname $0)
|
||||
TOPDIR=$( cd $BASEDIR/.. && pwd -P )
|
||||
test -d "$BASEDIR" || { echo "! Could not determine base for $0" ; exit 1 ; }
|
||||
test -d "$TOPDIR" || { echo "! Cound not determine top-level source dir" ; exit 1 ; }
|
||||
test -f "$TOPDIR/.clang-format.base" || { echo "! No .clang-format support files in $TOPDIR" ; exit 1 ; }
|
||||
test -f "$TOPDIR/.clang-format" || { echo "! No .clang-format support files in $TOPDIR" ; exit 1 ; }
|
||||
|
||||
AS=$( which astyle )
|
||||
|
||||
# Allow specifying CF_VERSIONS outside already
|
||||
CF_VERSIONS="$CF_VERSIONS clang-format-8 clang-format80 clang-format90 clang-format-9.0.1 clang-format"
|
||||
CF_VERSIONS="$CF_VERSIONS clang-format13 clang-format12 clang-format"
|
||||
for _cf in $CF_VERSIONS
|
||||
do
|
||||
# Not an error if this particular clang-format isn't found
|
||||
@ -40,31 +40,19 @@ test -x "$CF" || { echo "! $CF is not executable."; exit 1 ; }
|
||||
### CLANG-FORMAT-WRANGLING
|
||||
#
|
||||
# Version 7 and earlier doesn't understand all the options we would like
|
||||
# Version 8 is ok
|
||||
# Version 9 is ok
|
||||
# Later versions change some defaults so need extra wrangling.
|
||||
# .. there are extra files that are appended to the settings, per
|
||||
# .. clang-format version.
|
||||
# Version 12 handles lambdas nicely, so use that.
|
||||
# Version 13 is also ok.
|
||||
|
||||
format_version=`"$CF" --version | tr -dc '[^.0-9]' | cut -d . -f 1`
|
||||
case "$format_version" in
|
||||
[0-7] )
|
||||
echo "! Clang-format version 8+ required"
|
||||
exit 1
|
||||
;;
|
||||
[89] )
|
||||
12|13 )
|
||||
:
|
||||
;;
|
||||
* )
|
||||
echo "! Clang-format version '$format_version' unsupported."
|
||||
echo "! Clang-format version '$format_version' unsupported, version 12 required."
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
_fmt="$TOPDIR/.clang-format"
|
||||
cp "$_fmt.base" "$_fmt"
|
||||
for f in "$extra_settings" ; do
|
||||
test -f "$_fmt.$f" && cat "$_fmt.$f" >> "$_fmt"
|
||||
done
|
||||
|
||||
|
||||
### FILE PROCESSING
|
||||
@ -98,8 +86,3 @@ if test "x$any_dirs" = "xyes" ; then
|
||||
else
|
||||
style_some "$@"
|
||||
fi
|
||||
|
||||
### CLANG-FORMAT-WRANGLING
|
||||
#
|
||||
# Restore the original .clang-format
|
||||
cp "$_fmt.base" "$_fmt"
|
||||
|
File diff suppressed because it is too large
Load Diff
324
lang/python.pot
324
lang/python.pot
@ -2,409 +2,403 @@
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-11-02 15:45+0100\n"
|
||||
"POT-Creation-Date: 2022-02-01 17:27+0100\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"Language: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=CHARSET\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Language: \n"
|
||||
"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
|
||||
|
||||
#: src/modules/initramfscfg/main.py:32
|
||||
msgid "Configuring initramfs."
|
||||
msgstr "Configuring initramfs."
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/initramfscfg/main.py:85 src/modules/initramfscfg/main.py:89
|
||||
#: src/modules/fstab/main.py:355 src/modules/fstab/main.py:361
|
||||
#: src/modules/fstab/main.py:388 src/modules/networkcfg/main.py:105
|
||||
#: src/modules/initcpiocfg/main.py:227 src/modules/initcpiocfg/main.py:231
|
||||
#: src/modules/localecfg/main.py:135 src/modules/mount/main.py:144
|
||||
#: src/modules/fstab/main.py:360 src/modules/fstab/main.py:366
|
||||
#: src/modules/fstab/main.py:393 src/modules/networkcfg/main.py:105
|
||||
#: src/modules/initcpiocfg/main.py:235 src/modules/initcpiocfg/main.py:239
|
||||
#: src/modules/localecfg/main.py:135 src/modules/mount/main.py:229
|
||||
#: src/modules/rawfs/main.py:164 src/modules/openrcdmcryptcfg/main.py:72
|
||||
#: src/modules/openrcdmcryptcfg/main.py:76
|
||||
#: src/modules/luksopenswaphookcfg/main.py:86
|
||||
#: src/modules/luksopenswaphookcfg/main.py:90
|
||||
msgid "Configuration Error"
|
||||
msgstr "Configuration Error"
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/initramfscfg/main.py:86 src/modules/fstab/main.py:356
|
||||
#: src/modules/initcpiocfg/main.py:228 src/modules/mount/main.py:145
|
||||
#: src/modules/initramfscfg/main.py:86 src/modules/fstab/main.py:361
|
||||
#: src/modules/initcpiocfg/main.py:236 src/modules/mount/main.py:230
|
||||
#: src/modules/rawfs/main.py:165 src/modules/openrcdmcryptcfg/main.py:73
|
||||
#: src/modules/luksopenswaphookcfg/main.py:87
|
||||
msgid "No partitions are defined for <pre>{!s}</pre> to use."
|
||||
msgstr "No partitions are defined for <pre>{!s}</pre> to use."
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/initramfscfg/main.py:90 src/modules/fstab/main.py:362
|
||||
#: src/modules/networkcfg/main.py:106 src/modules/initcpiocfg/main.py:232
|
||||
#: src/modules/initramfscfg/main.py:90 src/modules/fstab/main.py:367
|
||||
#: src/modules/networkcfg/main.py:106 src/modules/initcpiocfg/main.py:240
|
||||
#: src/modules/localecfg/main.py:136 src/modules/openrcdmcryptcfg/main.py:77
|
||||
#: src/modules/luksopenswaphookcfg/main.py:91
|
||||
msgid "No root mount point is given for <pre>{!s}</pre> to use."
|
||||
msgstr "No root mount point is given for <pre>{!s}</pre> to use."
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/grubcfg/main.py:28
|
||||
msgid "Configure GRUB."
|
||||
msgstr "Configure GRUB."
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/bootloader/main.py:43
|
||||
msgid "Install bootloader."
|
||||
msgstr "Install bootloader."
|
||||
|
||||
#: src/modules/bootloader/main.py:508
|
||||
msgid "Bootloader installation error"
|
||||
msgstr "Bootloader installation error"
|
||||
|
||||
#: src/modules/bootloader/main.py:509
|
||||
msgid ""
|
||||
"The bootloader could not be installed. The installation command "
|
||||
"<pre>{!s}</pre> returned error code {!s}."
|
||||
msgstr ""
|
||||
"The bootloader could not be installed. The installation command "
|
||||
"<pre>{!s}</pre> returned error code {!s}."
|
||||
|
||||
#: src/modules/bootloader/main.py:612
|
||||
msgid "Failed to install grub, no partitions defined in global storage"
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/bootloader/main.py:780
|
||||
msgid "Bootloader installation error"
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/bootloader/main.py:781
|
||||
msgid ""
|
||||
"The bootloader could not be installed. The installation command <pre>{!s}</"
|
||||
"pre> returned error code {!s}."
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/fstab/main.py:29
|
||||
msgid "Writing fstab."
|
||||
msgstr "Writing fstab."
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/fstab/main.py:389
|
||||
#: src/modules/fstab/main.py:394
|
||||
msgid "No <pre>{!s}</pre> configuration is given for <pre>{!s}</pre> to use."
|
||||
msgstr "No <pre>{!s}</pre> configuration is given for <pre>{!s}</pre> to use."
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/dracut/main.py:27
|
||||
msgid "Creating initramfs with dracut."
|
||||
msgstr "Creating initramfs with dracut."
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/dracut/main.py:49
|
||||
msgid "Failed to run dracut on the target"
|
||||
msgstr "Failed to run dracut on the target"
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/dracut/main.py:50 src/modules/mkinitfs/main.py:50
|
||||
msgid "The exit code was {}"
|
||||
msgstr "The exit code was {}"
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/displaymanager/main.py:526
|
||||
#: src/modules/displaymanager/main.py:524
|
||||
msgid "Cannot write KDM configuration file"
|
||||
msgstr "Cannot write KDM configuration file"
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/displaymanager/main.py:527
|
||||
#: src/modules/displaymanager/main.py:525
|
||||
msgid "KDM config file {!s} does not exist"
|
||||
msgstr "KDM config file {!s} does not exist"
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/displaymanager/main.py:588
|
||||
#: src/modules/displaymanager/main.py:586
|
||||
msgid "Cannot write LXDM configuration file"
|
||||
msgstr "Cannot write LXDM configuration file"
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/displaymanager/main.py:589
|
||||
#: src/modules/displaymanager/main.py:587
|
||||
msgid "LXDM config file {!s} does not exist"
|
||||
msgstr "LXDM config file {!s} does not exist"
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/displaymanager/main.py:672
|
||||
#: src/modules/displaymanager/main.py:670
|
||||
msgid "Cannot write LightDM configuration file"
|
||||
msgstr "Cannot write LightDM configuration file"
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/displaymanager/main.py:673
|
||||
#: src/modules/displaymanager/main.py:671
|
||||
msgid "LightDM config file {!s} does not exist"
|
||||
msgstr "LightDM config file {!s} does not exist"
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/displaymanager/main.py:747
|
||||
#: src/modules/displaymanager/main.py:745
|
||||
msgid "Cannot configure LightDM"
|
||||
msgstr "Cannot configure LightDM"
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/displaymanager/main.py:748
|
||||
#: src/modules/displaymanager/main.py:746
|
||||
msgid "No LightDM greeter installed."
|
||||
msgstr "No LightDM greeter installed."
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/displaymanager/main.py:779
|
||||
#: src/modules/displaymanager/main.py:777
|
||||
msgid "Cannot write SLIM configuration file"
|
||||
msgstr "Cannot write SLIM configuration file"
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/displaymanager/main.py:780
|
||||
#: src/modules/displaymanager/main.py:778
|
||||
msgid "SLIM config file {!s} does not exist"
|
||||
msgstr "SLIM config file {!s} does not exist"
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/displaymanager/main.py:906
|
||||
#: src/modules/displaymanager/main.py:991
|
||||
msgid "No display managers selected for the displaymanager module."
|
||||
msgstr "No display managers selected for the displaymanager module."
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/displaymanager/main.py:907
|
||||
#: src/modules/displaymanager/main.py:992
|
||||
msgid ""
|
||||
"The displaymanagers list is empty or undefined in both globalstorage and "
|
||||
"displaymanager.conf."
|
||||
msgstr ""
|
||||
"The displaymanagers list is empty or undefined in both globalstorage and "
|
||||
"displaymanager.conf."
|
||||
|
||||
#: src/modules/displaymanager/main.py:989
|
||||
#: src/modules/displaymanager/main.py:1074
|
||||
msgid "Display manager configuration was incomplete"
|
||||
msgstr "Display manager configuration was incomplete"
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/services-openrc/main.py:29
|
||||
msgid "Configure OpenRC services"
|
||||
msgstr "Configure OpenRC services"
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/services-openrc/main.py:57
|
||||
msgid "Cannot add service {name!s} to run-level {level!s}."
|
||||
msgstr "Cannot add service {name!s} to run-level {level!s}."
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/services-openrc/main.py:59
|
||||
msgid "Cannot remove service {name!s} from run-level {level!s}."
|
||||
msgstr "Cannot remove service {name!s} from run-level {level!s}."
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/services-openrc/main.py:61
|
||||
msgid ""
|
||||
"Unknown service-action <code>{arg!s}</code> for service {name!s} in run-"
|
||||
"level {level!s}."
|
||||
msgstr ""
|
||||
"Unknown service-action <code>{arg!s}</code> for service {name!s} in run-"
|
||||
"level {level!s}."
|
||||
|
||||
#: src/modules/services-openrc/main.py:93
|
||||
#: src/modules/services-systemd/main.py:59
|
||||
msgid "Cannot modify service"
|
||||
msgstr "Cannot modify service"
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/services-openrc/main.py:94
|
||||
msgid ""
|
||||
"<code>rc-update {arg!s}</code> call in chroot returned error code {num!s}."
|
||||
msgstr ""
|
||||
"<code>rc-update {arg!s}</code> call in chroot returned error code {num!s}."
|
||||
|
||||
#: src/modules/services-openrc/main.py:101
|
||||
msgid "Target runlevel does not exist"
|
||||
msgstr "Target runlevel does not exist"
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/services-openrc/main.py:102
|
||||
msgid ""
|
||||
"The path for runlevel {level!s} is <code>{path!s}</code>, which does not "
|
||||
"exist."
|
||||
msgstr ""
|
||||
"The path for runlevel {level!s} is <code>{path!s}</code>, which does not "
|
||||
"exist."
|
||||
|
||||
#: src/modules/services-openrc/main.py:110
|
||||
msgid "Target service does not exist"
|
||||
msgstr "Target service does not exist"
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/services-openrc/main.py:111
|
||||
msgid ""
|
||||
"The path for service {name!s} is <code>{path!s}</code>, which does not "
|
||||
"exist."
|
||||
"The path for service {name!s} is <code>{path!s}</code>, which does not exist."
|
||||
msgstr ""
|
||||
"The path for service {name!s} is <code>{path!s}</code>, which does not "
|
||||
"exist."
|
||||
|
||||
#: src/modules/networkcfg/main.py:29
|
||||
msgid "Saving network configuration."
|
||||
msgstr "Saving network configuration."
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/packages/main.py:50 src/modules/packages/main.py:59
|
||||
#: src/modules/packages/main.py:69
|
||||
#: src/modules/packages/main.py:54 src/modules/packages/main.py:65
|
||||
#: src/modules/packages/main.py:75
|
||||
msgid "Install packages."
|
||||
msgstr "Install packages."
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/packages/main.py:57
|
||||
#: src/modules/packages/main.py:63
|
||||
#, python-format
|
||||
msgid "Processing packages (%(count)d / %(total)d)"
|
||||
msgstr "Processing packages (%(count)d / %(total)d)"
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/packages/main.py:62
|
||||
#: src/modules/packages/main.py:68
|
||||
#, python-format
|
||||
msgid "Installing one package."
|
||||
msgid_plural "Installing %(num)d packages."
|
||||
msgstr[0] "Installing one package."
|
||||
msgstr[1] "Installing %(num)d packages."
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
|
||||
#: src/modules/packages/main.py:65
|
||||
#: src/modules/packages/main.py:71
|
||||
#, python-format
|
||||
msgid "Removing one package."
|
||||
msgid_plural "Removing %(num)d packages."
|
||||
msgstr[0] "Removing one package."
|
||||
msgstr[1] "Removing %(num)d packages."
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
|
||||
#: src/modules/packages/main.py:638 src/modules/packages/main.py:650
|
||||
#: src/modules/packages/main.py:678
|
||||
#: src/modules/packages/main.py:725 src/modules/packages/main.py:737
|
||||
#: src/modules/packages/main.py:765
|
||||
msgid "Package Manager error"
|
||||
msgstr "Package Manager error"
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/packages/main.py:639
|
||||
#: src/modules/packages/main.py:726
|
||||
msgid ""
|
||||
"The package manager could not prepare updates. The command <pre>{!s}</pre> "
|
||||
"returned error code {!s}."
|
||||
msgstr ""
|
||||
"The package manager could not prepare updates. The command <pre>{!s}</pre> "
|
||||
|
||||
#: src/modules/packages/main.py:738
|
||||
msgid ""
|
||||
"The package manager could not update the system. The command <pre>{!s}</pre> "
|
||||
"returned error code {!s}."
|
||||
|
||||
#: src/modules/packages/main.py:651
|
||||
msgid ""
|
||||
"The package manager could not update the system. The command <pre>{!s}</pre>"
|
||||
" returned error code {!s}."
|
||||
msgstr ""
|
||||
"The package manager could not update the system. The command <pre>{!s}</pre>"
|
||||
" returned error code {!s}."
|
||||
|
||||
#: src/modules/packages/main.py:679
|
||||
#: src/modules/packages/main.py:766
|
||||
msgid ""
|
||||
"The package manager could not make changes to the installed system. The "
|
||||
"command <pre>{!s}</pre> returned error code {!s}."
|
||||
msgstr ""
|
||||
"The package manager could not make changes to the installed system. The "
|
||||
"command <pre>{!s}</pre> returned error code {!s}."
|
||||
|
||||
#: src/modules/plymouthcfg/main.py:27
|
||||
msgid "Configure Plymouth theme"
|
||||
msgstr "Configure Plymouth theme"
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/initcpiocfg/main.py:28
|
||||
msgid "Configuring mkinitcpio."
|
||||
msgstr "Configuring mkinitcpio."
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/localecfg/main.py:30
|
||||
msgid "Configuring locales."
|
||||
msgstr "Configuring locales."
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/mount/main.py:30
|
||||
#: src/modules/mount/main.py:42
|
||||
msgid "Mounting partitions."
|
||||
msgstr "Mounting partitions."
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/mount/main.py:88 src/modules/mount/main.py:124
|
||||
msgid "Internal error mounting zfs datasets"
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/mount/main.py:100
|
||||
msgid "Failed to import zpool"
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/mount/main.py:116
|
||||
msgid "Failed to unlock zpool"
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/mount/main.py:133 src/modules/mount/main.py:138
|
||||
msgid "Failed to set zfs mountpoint"
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/mount/main.py:253
|
||||
msgid "zfs mounting error"
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/rawfs/main.py:26
|
||||
msgid "Installing data."
|
||||
msgstr "Installing data."
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/dummypython/main.py:35
|
||||
msgid "Dummy python job."
|
||||
msgstr "Dummy python job."
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/dummypython/main.py:37 src/modules/dummypython/main.py:93
|
||||
#: src/modules/dummypython/main.py:94
|
||||
msgid "Dummy python step {}"
|
||||
msgstr "Dummy python step {}"
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/hwclock/main.py:26
|
||||
msgid "Setting hardware clock."
|
||||
msgstr "Setting hardware clock."
|
||||
|
||||
#: src/modules/umount/main.py:31
|
||||
msgid "Unmount file systems."
|
||||
msgstr "Unmount file systems."
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/openrcdmcryptcfg/main.py:26
|
||||
msgid "Configuring OpenRC dmcrypt service."
|
||||
msgstr "Configuring OpenRC dmcrypt service."
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/services-systemd/main.py:26
|
||||
msgid "Configure systemd services"
|
||||
msgstr "Configure systemd services"
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/services-systemd/main.py:60
|
||||
msgid ""
|
||||
"<code>systemctl {arg!s}</code> call in chroot returned error code {num!s}."
|
||||
msgstr ""
|
||||
"<code>systemctl {arg!s}</code> call in chroot returned error code {num!s}."
|
||||
|
||||
#: src/modules/services-systemd/main.py:63
|
||||
#: src/modules/services-systemd/main.py:69
|
||||
msgid "Cannot enable systemd service <code>{name!s}</code>."
|
||||
msgstr "Cannot enable systemd service <code>{name!s}</code>."
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/services-systemd/main.py:65
|
||||
msgid "Cannot enable systemd target <code>{name!s}</code>."
|
||||
msgstr "Cannot enable systemd target <code>{name!s}</code>."
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/services-systemd/main.py:67
|
||||
msgid "Cannot enable systemd timer <code>{name!s}</code>."
|
||||
msgstr "Cannot enable systemd timer <code>{name!s}</code>."
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/services-systemd/main.py:71
|
||||
msgid "Cannot disable systemd target <code>{name!s}</code>."
|
||||
msgstr "Cannot disable systemd target <code>{name!s}</code>."
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/services-systemd/main.py:73
|
||||
msgid "Cannot mask systemd unit <code>{name!s}</code>."
|
||||
msgstr "Cannot mask systemd unit <code>{name!s}</code>."
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/services-systemd/main.py:75
|
||||
msgid ""
|
||||
"Unknown systemd commands <code>{command!s}</code> and "
|
||||
"<code>{suffix!s}</code> for unit {name!s}."
|
||||
"Unknown systemd commands <code>{command!s}</code> and <code>{suffix!s}</"
|
||||
"code> for unit {name!s}."
|
||||
msgstr ""
|
||||
"Unknown systemd commands <code>{command!s}</code> and "
|
||||
"<code>{suffix!s}</code> for unit {name!s}."
|
||||
|
||||
#: src/modules/mkinitfs/main.py:27
|
||||
msgid "Creating initramfs with mkinitfs."
|
||||
msgstr "Creating initramfs with mkinitfs."
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/mkinitfs/main.py:49
|
||||
msgid "Failed to run mkinitfs on the target"
|
||||
msgstr "Failed to run mkinitfs on the target"
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/unpackfs/main.py:34
|
||||
msgid "Filling up filesystems."
|
||||
msgstr "Filling up filesystems."
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/unpackfs/main.py:254
|
||||
msgid "rsync failed with error code {}."
|
||||
msgstr "rsync failed with error code {}."
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/unpackfs/main.py:299
|
||||
msgid "Unpacking image {}/{}, file {}/{}"
|
||||
msgstr "Unpacking image {}/{}, file {}/{}"
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/unpackfs/main.py:314
|
||||
msgid "Starting to unpack {}"
|
||||
msgstr "Starting to unpack {}"
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/unpackfs/main.py:323 src/modules/unpackfs/main.py:465
|
||||
#: src/modules/unpackfs/main.py:323 src/modules/unpackfs/main.py:467
|
||||
msgid "Failed to unpack image \"{}\""
|
||||
msgstr "Failed to unpack image \"{}\""
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/unpackfs/main.py:430
|
||||
msgid "No mount point for root partition"
|
||||
msgstr "No mount point for root partition"
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/unpackfs/main.py:431
|
||||
msgid "globalstorage does not contain a \"rootMountPoint\" key, doing nothing"
|
||||
msgstr "globalstorage does not contain a \"rootMountPoint\" key, doing nothing"
|
||||
msgid "globalstorage does not contain a \"rootMountPoint\" key."
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/unpackfs/main.py:436
|
||||
#: src/modules/unpackfs/main.py:434
|
||||
msgid "Bad mount point for root partition"
|
||||
msgstr "Bad mount point for root partition"
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/unpackfs/main.py:437
|
||||
msgid "rootMountPoint is \"{}\", which does not exist, doing nothing"
|
||||
msgstr "rootMountPoint is \"{}\", which does not exist, doing nothing"
|
||||
#: src/modules/unpackfs/main.py:435
|
||||
msgid "rootMountPoint is \"{}\", which does not exist."
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/unpackfs/main.py:453 src/modules/unpackfs/main.py:457
|
||||
#: src/modules/unpackfs/main.py:463 src/modules/unpackfs/main.py:478
|
||||
msgid "Bad unsquash configuration"
|
||||
msgstr "Bad unsquash configuration"
|
||||
#: src/modules/unpackfs/main.py:439 src/modules/unpackfs/main.py:455
|
||||
#: src/modules/unpackfs/main.py:459 src/modules/unpackfs/main.py:465
|
||||
#: src/modules/unpackfs/main.py:480
|
||||
msgid "Bad unpackfs configuration"
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/unpackfs/main.py:454
|
||||
#: src/modules/unpackfs/main.py:440
|
||||
msgid "There is no configuration information."
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/unpackfs/main.py:456
|
||||
msgid "The filesystem for \"{}\" ({}) is not supported by your current kernel"
|
||||
msgstr "The filesystem for \"{}\" ({}) is not supported by your current kernel"
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/unpackfs/main.py:458
|
||||
#: src/modules/unpackfs/main.py:460
|
||||
msgid "The source filesystem \"{}\" does not exist"
|
||||
msgstr "The source filesystem \"{}\" does not exist"
|
||||
msgstr ""
|
||||
|
||||
#: src/modules/unpackfs/main.py:464
|
||||
#: src/modules/unpackfs/main.py:466
|
||||
msgid ""
|
||||
"Failed to find unsquashfs, make sure you have the squashfs-tools package "
|
||||
"installed."
|
||||
msgstr ""
|
||||
"Failed to find unsquashfs, make sure you have the squashfs-tools package "
|
||||
"installed."
|
||||
|
||||
#: src/modules/unpackfs/main.py:479
|
||||
#: src/modules/unpackfs/main.py:481
|
||||
msgid "The destination \"{}\" in the target system is not a directory"
|
||||
msgstr "The destination \"{}\" in the target system is not a directory"
|
||||
|
||||
#: src/modules/luksopenswaphookcfg/main.py:26
|
||||
msgid "Configuring encrypted swap."
|
||||
msgstr "Configuring encrypted swap."
|
||||
msgstr ""
|
||||
|
@ -485,7 +485,7 @@ main( int argc, char* argv[] )
|
||||
return 1;
|
||||
}
|
||||
|
||||
cDebug() << Logger::SubEntry << " .. got" << m->name() << m->typeString() << m->interfaceString();
|
||||
cDebug() << Logger::SubEntry << "got" << m->name() << m->typeString() << m->interfaceString();
|
||||
if ( m->type() == Calamares::Module::Type::View )
|
||||
{
|
||||
// If we forgot the --ui, any ViewModule will core dump as it
|
||||
@ -535,7 +535,7 @@ main( int argc, char* argv[] )
|
||||
|
||||
using TR = Logger::DebugRow< const char*, const QString >;
|
||||
|
||||
cDebug() << "Module metadata" << TR( "name", m->name() ) << TR( "type", m->typeString() )
|
||||
cDebug() << Logger::SubEntry << "Module metadata" << TR( "name", m->name() ) << TR( "type", m->typeString() )
|
||||
<< TR( "interface", m->interfaceString() );
|
||||
|
||||
Calamares::JobList jobList = m->jobs();
|
||||
@ -543,6 +543,8 @@ main( int argc, char* argv[] )
|
||||
unsigned int count = 1;
|
||||
for ( const auto& p : jobList )
|
||||
{
|
||||
// This doesn't get a SubEntry because the jobs may log a bunch of
|
||||
// things; print the function-header to make clear that we're back in main.
|
||||
cDebug() << "Job #" << count << "name" << p->prettyName();
|
||||
Calamares::JobResult r = p->exec();
|
||||
if ( !r )
|
||||
|
@ -122,8 +122,9 @@ public:
|
||||
}
|
||||
else
|
||||
{
|
||||
cDebug() << o << "Starting" << ( failureEncountered ? "EMERGENCY JOB" : "job" ) << jobitem.job->prettyName()
|
||||
<< '(' << ( m_jobIndex + 1 ) << '/' << m_runningJobs->count() << ')';
|
||||
cDebug() << o << "Starting" << ( failureEncountered ? "EMERGENCY JOB" : "job" )
|
||||
<< jobitem.job->prettyName() << '(' << ( m_jobIndex + 1 ) << '/' << m_runningJobs->count()
|
||||
<< ')';
|
||||
o.refresh(); // So next time it shows the function header again
|
||||
emitProgress( 0.0 ); // 0% for *this job*
|
||||
connect( jobitem.job.data(), &Job::progress, this, &JobThread::emitProgress );
|
||||
|
@ -259,21 +259,22 @@ operator<<( QDebug& s, const RedactedCommand& l )
|
||||
* Identical strings with the same context will be hashed the same,
|
||||
* so that they can be logged and still recognized as the-same.
|
||||
*/
|
||||
static uint insertRedactedName( const QString& context, const QString& s )
|
||||
static uint
|
||||
insertRedactedName( const QString& context, const QString& s )
|
||||
{
|
||||
static uint salt = QRandomGenerator::global()->generate(); // Just once
|
||||
|
||||
uint val = qHash(context, salt);
|
||||
return qHash(s, val);
|
||||
uint val = qHash( context, salt );
|
||||
return qHash( s, val );
|
||||
}
|
||||
|
||||
RedactedName::RedactedName( const QString& context, const QString& s )
|
||||
: m_id( insertRedactedName(context, s) ),
|
||||
m_context(context)
|
||||
: m_id( insertRedactedName( context, s ) )
|
||||
, m_context( context )
|
||||
{
|
||||
}
|
||||
|
||||
RedactedName::RedactedName(const char *context, const QString& s )
|
||||
RedactedName::RedactedName( const char* context, const QString& s )
|
||||
: RedactedName( QString::fromLatin1( context ), s )
|
||||
{
|
||||
}
|
||||
|
@ -71,8 +71,11 @@ private:
|
||||
inline CDebug&
|
||||
operator<<( CDebug&& s, const FuncSuppressor& f )
|
||||
{
|
||||
s.m_funcinfo = nullptr;
|
||||
s << f.m_s;
|
||||
if ( s.m_funcinfo )
|
||||
{
|
||||
s.m_funcinfo = nullptr;
|
||||
s.m_msg = QString( f.m_s );
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
@ -244,7 +247,8 @@ private:
|
||||
const QString m_context;
|
||||
};
|
||||
|
||||
inline QDebug& operator<<( QDebug& s, const RedactedName& n )
|
||||
inline QDebug&
|
||||
operator<<( QDebug& s, const RedactedName& n )
|
||||
{
|
||||
return s << NoQuote << QString( n ) << Quote;
|
||||
}
|
||||
|
@ -29,7 +29,8 @@ namespace CalamaresUtils
|
||||
* @param locale the new locale (names as defined by Calamares).
|
||||
* @param brandingTranslationsPrefix the branding path prefix, from Calamares::Branding.
|
||||
*/
|
||||
DLLEXPORT void installTranslator( const CalamaresUtils::Locale::Translation::Id& locale, const QString& brandingTranslationsPrefix );
|
||||
DLLEXPORT void installTranslator( const CalamaresUtils::Locale::Translation::Id& locale,
|
||||
const QString& brandingTranslationsPrefix );
|
||||
|
||||
/** @brief Initializes the translations with the current system settings
|
||||
*/
|
||||
@ -56,7 +57,8 @@ DLLEXPORT CalamaresUtils::Locale::Translation::Id translatorLocaleName();
|
||||
*
|
||||
* @returns @c true on success
|
||||
*/
|
||||
DLLEXPORT bool loadTranslator( const CalamaresUtils::Locale::Translation::Id& locale, const QString& prefix, QTranslator* translator );
|
||||
DLLEXPORT bool
|
||||
loadTranslator( const CalamaresUtils::Locale::Translation::Id& locale, const QString& prefix, QTranslator* translator );
|
||||
|
||||
/** @brief Set @p allow to true to load translations from current dir.
|
||||
*
|
||||
@ -88,7 +90,7 @@ public:
|
||||
static Retranslator* instance();
|
||||
|
||||
/// @brief Helper function for attaching lambdas
|
||||
static void attach( QObject* o, std::function< void( void ) > f);
|
||||
static void attach( QObject* o, std::function< void( void ) > f );
|
||||
|
||||
signals:
|
||||
void languageChanged();
|
||||
@ -138,8 +140,11 @@ private:
|
||||
#define CALAMARES_RETRANSLATE_SLOT( slotfunc ) \
|
||||
do \
|
||||
{ \
|
||||
connect( CalamaresUtils::Retranslator::instance(), &CalamaresUtils::Retranslator::languageChanged, this, slotfunc ); \
|
||||
(this->*slotfunc)(); \
|
||||
connect( CalamaresUtils::Retranslator::instance(), \
|
||||
&CalamaresUtils::Retranslator::languageChanged, \
|
||||
this, \
|
||||
slotfunc ); \
|
||||
( this->*slotfunc )(); \
|
||||
} while ( false )
|
||||
|
||||
#endif
|
||||
|
@ -179,6 +179,26 @@ it is possible to take the whole installation-process into account
|
||||
for determining the relative weights there.
|
||||
|
||||
|
||||
## Global storage keys
|
||||
Some modules place values in global storage so that they can be referenced later by other modules or even other parts of the same module. The following table represents a partial list of the values available as well as where they originate from and which module consume them.
|
||||
|
||||
Key|Source|Consumers|Description
|
||||
---|---|---|---
|
||||
btrfsSubvolumes|mount|fstab|List of maps containing the mountpoint and btrtfs subvolume
|
||||
btrfsRootSubvolume|mount|bootloader, luksopenswaphook|String containing the subvolume mounted at root
|
||||
efiSystemPartition|partition|bootloader, fstab|String containing the path to the ESP relative to the installed system
|
||||
extraMounts|mount|unpackfs|List of maps holding metadata for the temporary mountpoints used by the installer
|
||||
hostname|users||A string containing the hostname of the new system
|
||||
netinstallAdd|packagechooser|netinstall|Data to add to netinstall tree. Same format as netinstall.yaml
|
||||
netinstallSelect|packagechooser|netinstall|List of group names to select in the netinstall tree
|
||||
partitions|partition, rawfs|numerous modules|List of maps of metadata about each partition
|
||||
rootMountPoint|mount|numerous modules|A string with the absolute path to the root mountpoint
|
||||
username|users|networkcfg, plasmainf, preservefiles|A string containing the username of the new user
|
||||
zfsDatasets|zfs|bootloader, grubcfg, mount|List of maps of zfs datasets including the name and mount information
|
||||
zfsInfo|partition|mount, zfs|List of encrypted zfs partitions and the encription info
|
||||
zfsPoolInfo|zfs|mount, umount|List of maps of zfs pool info including the name and mountpoint
|
||||
|
||||
|
||||
## C++ modules
|
||||
|
||||
> Type: viewmodule, jobmodule
|
||||
|
@ -427,7 +427,7 @@ def efi_label(efi_directory):
|
||||
used within @p efi_directory.
|
||||
"""
|
||||
if "efiBootloaderId" in libcalamares.job.configuration:
|
||||
efi_bootloader_id = change_efi_suffix( efi_directory, calamares.job.configuration["efiBootloaderId"] )
|
||||
efi_bootloader_id = change_efi_suffix( efi_directory, libcalamares.job.configuration["efiBootloaderId"] )
|
||||
else:
|
||||
branding = libcalamares.globalstorage.value("branding")
|
||||
efi_bootloader_id = branding["bootloaderEntryName"]
|
||||
@ -563,6 +563,7 @@ def run_grub_install(fw_type, partitions, efi_directory):
|
||||
check_target_env_call(["sh", "-c", "echo ZPOOL_VDEV_NAME_PATH=1 >> /etc/environment"])
|
||||
|
||||
if fw_type == "efi":
|
||||
assert efi_directory is not None
|
||||
efi_bootloader_id = efi_label(efi_directory)
|
||||
efi_target, efi_grub_file, efi_boot_file = get_grub_efi_parameters()
|
||||
|
||||
@ -577,6 +578,7 @@ def run_grub_install(fw_type, partitions, efi_directory):
|
||||
"--bootloader-id=" + efi_bootloader_id,
|
||||
"--force"])
|
||||
else:
|
||||
assert efi_directory is None
|
||||
if libcalamares.globalstorage.value("bootLoader") is None:
|
||||
return
|
||||
|
||||
@ -653,7 +655,7 @@ def install_grub(efi_directory, fw_type):
|
||||
shutil.copy2(efi_file_source, efi_file_target)
|
||||
else:
|
||||
libcalamares.utils.debug("Bootloader: grub (bios)")
|
||||
run_grub_install(fw_type, partitions)
|
||||
run_grub_install(fw_type, partitions, None)
|
||||
|
||||
run_grub_mkconfig(partitions, libcalamares.job.configuration["grubCfg"])
|
||||
|
||||
|
25
src/modules/fstab/test2.yaml
Normal file
25
src/modules/fstab/test2.yaml
Normal file
@ -0,0 +1,25 @@
|
||||
# SPDX-FileCopyrightText: no
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
#
|
||||
# This test shows how btrfs root would work
|
||||
rootMountPoint: /tmp/mount
|
||||
partitions:
|
||||
- device: /dev/sda1
|
||||
fs: btrfs
|
||||
mountPoint: /
|
||||
uuid: 2a00f1d5-1217-49a7-bedd-b55c85764732
|
||||
- device: /dev/sda2
|
||||
fs: swap
|
||||
uuid: 59406569-446f-4730-a874-9f6b4b44fee3
|
||||
mountPoint:
|
||||
- device: /dev/sdb1
|
||||
fs: btrfs
|
||||
mountPoint: /home
|
||||
uuid: 59406569-abcd-1234-a874-9f6b4b44fee3
|
||||
btrfsSubvolumes:
|
||||
- mountPoint: /
|
||||
subvolume: "@ROOT"
|
||||
- mountPoint: /var
|
||||
subvolume: "@var"
|
||||
- mountPoint: /usr/local
|
||||
subvolume: "@local"
|
@ -29,8 +29,16 @@ prefer_grub_d: false
|
||||
# kept, not updated to the *bootloaderEntryName* from the branding file.
|
||||
# Use this if the GRUB_DISTRIBUTOR setting in the file is "smart" in
|
||||
# some way (e.g. uses shell-command substitution).
|
||||
#
|
||||
# TODO:3.3:snake-case this key
|
||||
keepDistributor: false
|
||||
|
||||
# The default kernel params that should always be applied.
|
||||
# This is an array of strings. If it is unset, the default is
|
||||
# `["quiet"]`. To avoid the default, explicitly set this key
|
||||
# to an empty list, `[]`.
|
||||
kernel_params: [ "quiet" ]
|
||||
|
||||
# Default entries to write to /etc/default/grub if it does not exist yet or if
|
||||
# we are overwriting it.
|
||||
#
|
||||
|
@ -7,8 +7,10 @@ additionalProperties: false
|
||||
type: object
|
||||
properties:
|
||||
overwrite: { type: boolean, default: false }
|
||||
# TODO:3.3:snake-case this key
|
||||
keepDistributor: { type: boolean, default: false }
|
||||
prefer_grub_d: { type: boolean, default: false }
|
||||
kernel_params: { type: array, items: { type: string } }
|
||||
defaults:
|
||||
type: object
|
||||
additionalProperties: true # Other fields are acceptable
|
||||
|
@ -174,7 +174,7 @@ def modify_grub_default(partitions, root_mount_point, distributor):
|
||||
if partition["fs"] == "zfs" and partition["mountPoint"] == "/":
|
||||
zfs_root_path = get_zfs_root()
|
||||
|
||||
kernel_params = ["quiet"]
|
||||
kernel_params = libcalamares.job.configuration.get("kernel_params", ["quiet"])
|
||||
|
||||
# Currently, grub doesn't detect this properly so it must be set manually
|
||||
if zfs_root_path:
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "PackageModel.h"
|
||||
#include "ui_page_netinst.h"
|
||||
|
||||
#include "GlobalStorage.h"
|
||||
#include "JobQueue.h"
|
||||
|
||||
#include "network/Manager.h"
|
||||
@ -62,4 +63,19 @@ void
|
||||
NetInstallPage::onActivate()
|
||||
{
|
||||
ui->groupswidget->setFocus();
|
||||
|
||||
// The netinstallSelect global storage value can be used to make additional items selected by default
|
||||
Calamares::GlobalStorage* gs = Calamares::JobQueue::instance()->globalStorage();
|
||||
const QStringList selectNames = gs->value( "netinstallSelect" ).toStringList();
|
||||
if ( !selectNames.isEmpty() )
|
||||
{
|
||||
m_config->model()->setSelections( selectNames );
|
||||
}
|
||||
|
||||
// If NetInstallAdd is found in global storage, add those items to the tree
|
||||
const QVariantList groups = gs->value( "netinstallAdd" ).toList();
|
||||
if ( !groups.isEmpty() )
|
||||
{
|
||||
m_config->model()->appendModelData( groups );
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,43 @@
|
||||
#include "utils/Variant.h"
|
||||
#include "utils/Yaml.h"
|
||||
|
||||
/// Recursive helper for setSelections()
|
||||
static void
|
||||
setSelections( const QStringList& selectNames, PackageTreeItem* item )
|
||||
{
|
||||
for ( int i = 0; i < item->childCount(); i++ )
|
||||
{
|
||||
auto* child = item->child( i );
|
||||
setSelections( selectNames, child );
|
||||
}
|
||||
if ( item->isGroup() && selectNames.contains( item->name() ) )
|
||||
{
|
||||
item->setSelected( Qt::CheckState::Checked );
|
||||
}
|
||||
}
|
||||
|
||||
/** @brief Collects all the "source" values from @p groupList
|
||||
*
|
||||
* Iterates over @p groupList and returns all nonempty "source"
|
||||
* values from the maps.
|
||||
*
|
||||
*/
|
||||
static QStringList
|
||||
collectSources( const QVariantList& groupList )
|
||||
{
|
||||
QStringList sources;
|
||||
for ( const QVariant& group : groupList )
|
||||
{
|
||||
QVariantMap groupMap = group.toMap();
|
||||
if ( !groupMap[ "source" ].toString().isEmpty() )
|
||||
{
|
||||
sources.append( groupMap[ "source" ].toString() );
|
||||
}
|
||||
}
|
||||
|
||||
return sources;
|
||||
}
|
||||
|
||||
PackageModel::PackageModel( QObject* parent )
|
||||
: QAbstractItemModel( parent )
|
||||
{
|
||||
@ -170,6 +207,15 @@ PackageModel::headerData( int section, Qt::Orientation orientation, int role ) c
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
void
|
||||
PackageModel::setSelections( const QStringList& selectNames )
|
||||
{
|
||||
if ( m_rootItem )
|
||||
{
|
||||
::setSelections( selectNames, m_rootItem );
|
||||
}
|
||||
}
|
||||
|
||||
PackageTreeItem::List
|
||||
PackageModel::getPackages() const
|
||||
{
|
||||
@ -303,9 +349,43 @@ PackageModel::setupModelData( const QVariantList& groupList, PackageTreeItem* pa
|
||||
void
|
||||
PackageModel::setupModelData( const QVariantList& l )
|
||||
{
|
||||
emit beginResetModel();
|
||||
Q_EMIT beginResetModel();
|
||||
delete m_rootItem;
|
||||
m_rootItem = new PackageTreeItem();
|
||||
setupModelData( l, m_rootItem );
|
||||
emit endResetModel();
|
||||
Q_EMIT endResetModel();
|
||||
}
|
||||
|
||||
void
|
||||
PackageModel::appendModelData( const QVariantList& groupList )
|
||||
{
|
||||
if ( m_rootItem )
|
||||
{
|
||||
Q_EMIT beginResetModel();
|
||||
|
||||
const QStringList sources = collectSources( groupList );
|
||||
|
||||
if ( !sources.isEmpty() )
|
||||
{
|
||||
// Prune any existing data from the same source
|
||||
QList< int > removeList;
|
||||
for ( int i = 0; i < m_rootItem->childCount(); i++ )
|
||||
{
|
||||
PackageTreeItem* child = m_rootItem->child( i );
|
||||
if ( sources.contains( child->source() ) )
|
||||
{
|
||||
removeList.insert( 0, i );
|
||||
}
|
||||
}
|
||||
for ( const int& item : qAsConst( removeList ) )
|
||||
{
|
||||
m_rootItem->removeChild( item );
|
||||
}
|
||||
}
|
||||
|
||||
// Add the new data to the model
|
||||
setupModelData( groupList, m_rootItem );
|
||||
|
||||
Q_EMIT endResetModel();
|
||||
}
|
||||
}
|
||||
|
@ -54,9 +54,33 @@ public:
|
||||
int rowCount( const QModelIndex& parent = QModelIndex() ) const override;
|
||||
int columnCount( const QModelIndex& parent = QModelIndex() ) const override;
|
||||
|
||||
/** @brief Sets the checked flag on matching groups in the tree
|
||||
*
|
||||
* Recursively traverses the tree pointed to by m_rootItem and
|
||||
* checks if a group name matches any of the items in @p selectNames.
|
||||
* If a match is found, set check the box for that group and it's children.
|
||||
*
|
||||
* Individual packages will not be matched.
|
||||
*
|
||||
*/
|
||||
void setSelections( const QStringList& selectNames );
|
||||
|
||||
PackageTreeItem::List getPackages() const;
|
||||
PackageTreeItem::List getItemPackages( PackageTreeItem* item ) const;
|
||||
|
||||
/** @brief Appends groups to the tree
|
||||
*
|
||||
* Uses the data from @p groupList to add elements to the
|
||||
* existing tree that m_rootItem points to. If m_rootItem
|
||||
* is not valid, it does nothing
|
||||
*
|
||||
* Before adding anything to the model, it ensures that there
|
||||
* is no existing data from the same source. If there is, that
|
||||
* data is pruned first
|
||||
*
|
||||
*/
|
||||
void appendModelData( const QVariantList& groupList );
|
||||
|
||||
private:
|
||||
friend class ItemTests;
|
||||
|
||||
|
@ -70,6 +70,7 @@ PackageTreeItem::PackageTreeItem( const QVariantMap& groupData, GroupTag&& paren
|
||||
, m_description( CalamaresUtils::getString( groupData, "description" ) )
|
||||
, m_preScript( CalamaresUtils::getString( groupData, "pre-install" ) )
|
||||
, m_postScript( CalamaresUtils::getString( groupData, "post-install" ) )
|
||||
, m_source( CalamaresUtils::getString( groupData, "source" ) )
|
||||
, m_isGroup( true )
|
||||
, m_isCritical( parentCriticality( groupData, parent.parent ) )
|
||||
, m_isHidden( CalamaresUtils::getBool( groupData, "hidden", false ) )
|
||||
@ -248,6 +249,19 @@ PackageTreeItem::setChildrenSelected( Qt::CheckState isSelected )
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PackageTreeItem::removeChild( int row )
|
||||
{
|
||||
if ( 0 <= row && row < m_childItems.count() )
|
||||
{
|
||||
m_childItems.removeAt( row );
|
||||
}
|
||||
else
|
||||
{
|
||||
cWarning() << "Attempt to remove invalid child in removeChild() at row " << row;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
PackageTreeItem::type() const
|
||||
{
|
||||
|
@ -56,6 +56,7 @@ public:
|
||||
QString description() const { return m_description; }
|
||||
QString preScript() const { return m_preScript; }
|
||||
QString postScript() const { return m_postScript; }
|
||||
QString source() const { return m_source; }
|
||||
|
||||
/** @brief Is this item a group-item?
|
||||
*
|
||||
@ -124,6 +125,8 @@ public:
|
||||
void setSelected( Qt::CheckState isSelected );
|
||||
void setChildrenSelected( Qt::CheckState isSelected );
|
||||
|
||||
void removeChild( int row );
|
||||
|
||||
/** @brief Update selectedness based on the children's states
|
||||
*
|
||||
* This only makes sense for groups, which might have packages
|
||||
@ -157,6 +160,7 @@ private:
|
||||
QString m_description;
|
||||
QString m_preScript;
|
||||
QString m_postScript;
|
||||
QString m_source;
|
||||
bool m_isGroup = false;
|
||||
bool m_isCritical = false;
|
||||
bool m_isHidden = false;
|
||||
|
@ -410,7 +410,7 @@ ItemTests::testUrlFallback()
|
||||
QEventLoop loop;
|
||||
connect( &c, &Config::statusReady, &loop, &QEventLoop::quit );
|
||||
QSignalSpy spy( &c, &Config::statusReady );
|
||||
QTimer::singleShot( std::chrono::seconds(1), &loop, &QEventLoop::quit );
|
||||
QTimer::singleShot( std::chrono::seconds( 1 ), &loop, &QEventLoop::quit );
|
||||
loop.exec();
|
||||
|
||||
// Check it didn't time out
|
||||
|
@ -27,6 +27,29 @@
|
||||
#include "utils/Logger.h"
|
||||
#include "utils/Variant.h"
|
||||
|
||||
/** @brief This removes any values from @p groups that match @p source
|
||||
*
|
||||
* This is used to remove duplicates from the netinstallAdd structure
|
||||
* It iterates over @p groups and for each map in the list, if the
|
||||
* "source" element matches @p source, it is removed from the returned
|
||||
* list.
|
||||
*/
|
||||
static QVariantList
|
||||
pruneNetinstallAdd( const QString& source, const QVariant& groups )
|
||||
{
|
||||
QVariantList newGroupList;
|
||||
const QVariantList groupList = groups.toList();
|
||||
for ( const QVariant& group : groupList )
|
||||
{
|
||||
QVariantMap groupMap = group.toMap();
|
||||
if ( groupMap.value( "source", "" ).toString() != source )
|
||||
{
|
||||
newGroupList.append( groupMap );
|
||||
}
|
||||
}
|
||||
return newGroupList;
|
||||
}
|
||||
|
||||
const NamedEnumTable< PackageChooserMode >&
|
||||
packageChooserModeNames()
|
||||
{
|
||||
@ -55,6 +78,8 @@ PackageChooserMethodNames()
|
||||
{ "custom", PackageChooserMethod::Legacy },
|
||||
{ "contextualprocess", PackageChooserMethod::Legacy },
|
||||
{ "packages", PackageChooserMethod::Packages },
|
||||
{ "netinstall-add", PackageChooserMethod::NetAdd },
|
||||
{ "netinstall-select", PackageChooserMethod::NetSelect },
|
||||
};
|
||||
return names;
|
||||
}
|
||||
@ -121,6 +146,47 @@ Config::updateGlobalStorage( const QStringList& selected ) const
|
||||
CalamaresUtils::Packages::setGSPackageAdditions(
|
||||
Calamares::JobQueue::instance()->globalStorage(), m_defaultId, packageNames );
|
||||
}
|
||||
else if ( m_method == PackageChooserMethod::NetAdd )
|
||||
{
|
||||
QVariantList netinstallDataList = m_model->getNetinstallDataForNames( selected );
|
||||
if ( netinstallDataList.isEmpty() )
|
||||
{
|
||||
cWarning() << "No netinstall information found for " << selected;
|
||||
}
|
||||
else
|
||||
{
|
||||
// If an earlier packagechooser instance added this data to global storage, combine them
|
||||
auto* gs = Calamares::JobQueue::instance()->globalStorage();
|
||||
if ( gs->contains( "netinstallAdd" ) )
|
||||
{
|
||||
netinstallDataList
|
||||
+= pruneNetinstallAdd( QStringLiteral( "packageChooser" ), gs->value( "netinstallAdd" ) );
|
||||
}
|
||||
gs->insert( "netinstallAdd", netinstallDataList );
|
||||
}
|
||||
}
|
||||
else if ( m_method == PackageChooserMethod::NetSelect )
|
||||
{
|
||||
cDebug() << m_defaultId << "groups to select in netinstall" << selected;
|
||||
QStringList newSelected = selected;
|
||||
auto* gs = Calamares::JobQueue::instance()->globalStorage();
|
||||
|
||||
// If an earlier packagechooser instance added this data to global storage, combine them
|
||||
if ( gs->contains( "netinstallSelect" ) )
|
||||
{
|
||||
auto selectedOrig = gs->value( "netinstallSelect" );
|
||||
if ( selectedOrig.canConvert( QVariant::StringList ) )
|
||||
{
|
||||
newSelected += selectedOrig.toStringList();
|
||||
}
|
||||
else
|
||||
{
|
||||
cWarning() << "Invalid NetinstallSelect data in global storage. Earlier selections purged";
|
||||
}
|
||||
gs->remove( "netinstallSelect" );
|
||||
}
|
||||
gs->insert( "netinstallSelect", newSelected );
|
||||
}
|
||||
else
|
||||
{
|
||||
cWarning() << "Unknown packagechooser method" << smash( m_method );
|
||||
|
@ -33,6 +33,8 @@ enum class PackageChooserMethod
|
||||
{
|
||||
Legacy, // use contextualprocess or other custom
|
||||
Packages, // use the packages module
|
||||
NetAdd, // adds packages to the netinstall module
|
||||
NetSelect, // makes selections in the netinstall module
|
||||
};
|
||||
|
||||
const NamedEnumTable< PackageChooserMethod >& PackageChooserMethodNames();
|
||||
|
@ -15,6 +15,16 @@
|
||||
|
||||
#include <QFileInfo>
|
||||
|
||||
/** @brief A wrapper for CalamaresUtils::getSubMap that excludes the success param
|
||||
*/
|
||||
static QVariantMap
|
||||
getSubMap( const QVariantMap& map, const QString& key )
|
||||
{
|
||||
bool success;
|
||||
|
||||
return CalamaresUtils::getSubMap( map, key, success );
|
||||
}
|
||||
|
||||
static QPixmap
|
||||
loadScreenshot( const QString& path )
|
||||
{
|
||||
@ -51,12 +61,13 @@ PackageItem::PackageItem( const QString& a_id,
|
||||
{
|
||||
}
|
||||
|
||||
PackageItem::PackageItem::PackageItem( const QVariantMap& item_map )
|
||||
PackageItem::PackageItem( const QVariantMap& item_map )
|
||||
: id( CalamaresUtils::getString( item_map, "id" ) )
|
||||
, name( CalamaresUtils::Locale::TranslatedString( item_map, "name" ) )
|
||||
, description( CalamaresUtils::Locale::TranslatedString( item_map, "description" ) )
|
||||
, screenshot( loadScreenshot( CalamaresUtils::getString( item_map, "screenshot" ) ) )
|
||||
, packageNames( CalamaresUtils::getStringList( item_map, "packages" ) )
|
||||
, netinstallData( getSubMap( item_map, "netinstall" ) )
|
||||
{
|
||||
if ( name.isEmpty() && id.isEmpty() )
|
||||
{
|
||||
@ -125,6 +136,25 @@ PackageListModel::getInstallPackagesForNames( const QStringList& ids ) const
|
||||
return l;
|
||||
}
|
||||
|
||||
QVariantList
|
||||
PackageListModel::getNetinstallDataForNames( const QStringList& ids ) const
|
||||
{
|
||||
QVariantList l;
|
||||
for ( auto& p : m_packages )
|
||||
{
|
||||
if ( ids.contains( p.id ) )
|
||||
{
|
||||
if ( !p.netinstallData.isEmpty() )
|
||||
{
|
||||
QVariantMap newData = p.netinstallData;
|
||||
newData[ "source" ] = QStringLiteral( "packageChooser" );
|
||||
l.append( newData );
|
||||
}
|
||||
}
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
int
|
||||
PackageListModel::rowCount( const QModelIndex& index ) const
|
||||
{
|
||||
|
@ -26,6 +26,7 @@ struct PackageItem
|
||||
CalamaresUtils::Locale::TranslatedString description;
|
||||
QPixmap screenshot;
|
||||
QStringList packageNames;
|
||||
QVariantMap netinstallData;
|
||||
|
||||
/// @brief Create blank PackageItem
|
||||
PackageItem();
|
||||
@ -111,6 +112,14 @@ public:
|
||||
*/
|
||||
QStringList getInstallPackagesForNames( const QStringList& ids ) const;
|
||||
|
||||
/** @brief Does a name lookup (based on id) and returns the netinstall data
|
||||
*
|
||||
* If there is a package with an id in @p ids, returns their netinstall data
|
||||
*
|
||||
* returns a list of netinstall data or an emply list if none is found
|
||||
*/
|
||||
QVariantList getNetinstallDataForNames( const QStringList& ids ) const;
|
||||
|
||||
enum Roles : int
|
||||
{
|
||||
NameRole = Qt::DisplayRole,
|
||||
|
@ -33,6 +33,15 @@ mode: required
|
||||
# in the `exec` section. These package settings will then be handed
|
||||
# off to whatever package manager is configured there.
|
||||
#
|
||||
# - "netinstall-select"
|
||||
# When this is set, the id(s) selected are passed to the netinstall module.
|
||||
# Any id that matches a group name in that module is set to checked
|
||||
#
|
||||
# - "netinstall-add"
|
||||
# With this method, the packagechooser module is used to add groups to the
|
||||
# netinstall module. For this to hav=e any effect. You must set netinstall,
|
||||
# which is described below.
|
||||
#
|
||||
# There is no need to put this module in the `exec` section. There
|
||||
# are no jobs that this module provides. You should put **other**
|
||||
# modules, either *contextualprocess* or *packages* or some custom
|
||||
@ -101,13 +110,19 @@ labels:
|
||||
# an additional attempt is made to load the image from the **branding**
|
||||
# directory.
|
||||
#
|
||||
# The following field is **optional** for an item:
|
||||
# The following fields are **optional** for an item:
|
||||
#
|
||||
# - *packages* :
|
||||
# List of package names for the product. If using the *method*
|
||||
# "packages", consider this item mandatory (because otherwise
|
||||
# selecting the item would install no packages).
|
||||
#
|
||||
# - *netinstall* :
|
||||
# The data in this field should follow the format of a group
|
||||
# from the netinstall module documented in
|
||||
# src/modules/netinstall/netinstall.conf. This is only used
|
||||
# when method is set to "netinstall-add"
|
||||
#
|
||||
# # AppData Items #
|
||||
#
|
||||
# For data provided by AppData XML: the item has an *appdata*
|
||||
|
@ -345,6 +345,11 @@ Config::setConfigurationMap( const QVariantMap& configurationMap )
|
||||
if ( !m_swapChoices.contains( m_initialSwapChoice ) )
|
||||
{
|
||||
cWarning() << "Configuration for *initialSwapChoice* is not one of the *userSwapChoices*";
|
||||
if ( nameFound )
|
||||
{
|
||||
cWarning() << Logger::SubEntry << "Choice" << swapChoiceNames().find( m_initialSwapChoice ) << "added.";
|
||||
m_swapChoices.insert( m_initialSwapChoice );
|
||||
}
|
||||
m_initialSwapChoice = pickOne( m_swapChoices );
|
||||
}
|
||||
setSwapChoice( m_initialSwapChoice );
|
||||
|
@ -675,11 +675,15 @@ PartitionViewStep::setConfigurationMap( const QVariantMap& configurationMap )
|
||||
// because it could take a while. Then when it's done, we can set up the widgets
|
||||
// and remove the spinner.
|
||||
m_future = new QFutureWatcher< void >();
|
||||
connect( m_future, &QFutureWatcher< void >::finished, this, [this] {
|
||||
continueLoading();
|
||||
this->m_future->deleteLater();
|
||||
this->m_future = nullptr;
|
||||
} );
|
||||
connect( m_future,
|
||||
&QFutureWatcher< void >::finished,
|
||||
this,
|
||||
[ this ]
|
||||
{
|
||||
continueLoading();
|
||||
this->m_future->deleteLater();
|
||||
this->m_future = nullptr;
|
||||
} );
|
||||
|
||||
QFuture< void > future = QtConcurrent::run( this, &PartitionViewStep::initPartitionCoreModule );
|
||||
m_future->setFuture( future );
|
||||
|
@ -28,9 +28,9 @@
|
||||
static void
|
||||
sortDevices( DeviceModel::DeviceList& l )
|
||||
{
|
||||
std::sort( l.begin(), l.end(), []( const Device* dev1, const Device* dev2 ) {
|
||||
return dev1->deviceNode() < dev2->deviceNode();
|
||||
} );
|
||||
std::sort( l.begin(),
|
||||
l.end(),
|
||||
[]( const Device* dev1, const Device* dev2 ) { return dev1->deviceNode() < dev2->deviceNode(); } );
|
||||
}
|
||||
|
||||
DeviceModel::DeviceModel( QObject* parent )
|
||||
|
@ -262,11 +262,9 @@ PartitionCoreModule::doInit()
|
||||
// Gives ownership of the Device* to the DeviceInfo object
|
||||
auto deviceInfo = new DeviceInfo( device );
|
||||
m_deviceInfos << deviceInfo;
|
||||
cDebug() << Logger::SubEntry
|
||||
<< device->deviceNode()
|
||||
<< device->capacity()
|
||||
<< Logger::RedactedName( "DevName", device->name() )
|
||||
<< Logger::RedactedName( "DevNamePretty", device->prettyName() );
|
||||
cDebug() << Logger::SubEntry << device->deviceNode() << device->capacity()
|
||||
<< Logger::RedactedName( "DevName", device->name() )
|
||||
<< Logger::RedactedName( "DevNamePretty", device->prettyName() );
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -685,9 +683,8 @@ PartitionCoreModule::lvmPVs() const
|
||||
bool
|
||||
PartitionCoreModule::hasVGwithThisName( const QString& name ) const
|
||||
{
|
||||
auto condition = [name]( DeviceInfo* d ) {
|
||||
return dynamic_cast< LvmDevice* >( d->device.data() ) && d->device.data()->name() == name;
|
||||
};
|
||||
auto condition = [ name ]( DeviceInfo* d )
|
||||
{ return dynamic_cast< LvmDevice* >( d->device.data() ) && d->device.data()->name() == name; };
|
||||
|
||||
return std::find_if( m_deviceInfos.begin(), m_deviceInfos.end(), condition ) != m_deviceInfos.end();
|
||||
}
|
||||
@ -695,7 +692,8 @@ PartitionCoreModule::hasVGwithThisName( const QString& name ) const
|
||||
bool
|
||||
PartitionCoreModule::isInVG( const Partition* partition ) const
|
||||
{
|
||||
auto condition = [partition]( DeviceInfo* d ) {
|
||||
auto condition = [ partition ]( DeviceInfo* d )
|
||||
{
|
||||
LvmDevice* vg = dynamic_cast< LvmDevice* >( d->device.data() );
|
||||
return vg && vg->physicalVolumes().contains( partition );
|
||||
};
|
||||
@ -964,9 +962,9 @@ PartitionCoreModule::layoutApply( Device* dev,
|
||||
const QString boot = QStringLiteral( "/boot" );
|
||||
const QString root = QStringLiteral( "/" );
|
||||
const auto is_boot
|
||||
= [&]( Partition* p ) -> bool { return PartitionInfo::mountPoint( p ) == boot || p->mountPoint() == boot; };
|
||||
= [ & ]( Partition* p ) -> bool { return PartitionInfo::mountPoint( p ) == boot || p->mountPoint() == boot; };
|
||||
const auto is_root
|
||||
= [&]( Partition* p ) -> bool { return PartitionInfo::mountPoint( p ) == root || p->mountPoint() == root; };
|
||||
= [ & ]( Partition* p ) -> bool { return PartitionInfo::mountPoint( p ) == root || p->mountPoint() == root; };
|
||||
|
||||
const bool separate_boot_partition
|
||||
= std::find_if( partList.constBegin(), partList.constEnd(), is_boot ) != partList.constEnd();
|
||||
@ -1089,10 +1087,14 @@ void
|
||||
PartitionCoreModule::asyncRevertDevice( Device* dev, std::function< void() > callback )
|
||||
{
|
||||
QFutureWatcher< void >* watcher = new QFutureWatcher< void >();
|
||||
connect( watcher, &QFutureWatcher< void >::finished, this, [watcher, callback] {
|
||||
callback();
|
||||
watcher->deleteLater();
|
||||
} );
|
||||
connect( watcher,
|
||||
&QFutureWatcher< void >::finished,
|
||||
this,
|
||||
[ watcher, callback ]
|
||||
{
|
||||
callback();
|
||||
watcher->deleteLater();
|
||||
} );
|
||||
|
||||
QFuture< void > future = QtConcurrent::run( this, &PartitionCoreModule::revertDevice, dev, true );
|
||||
watcher->setFuture( future );
|
||||
|
@ -283,7 +283,7 @@ PartitionLayout::createPartitions( Device* dev,
|
||||
}
|
||||
}
|
||||
|
||||
auto correctFS = [d = m_defaultFsType]( FileSystem::Type t ) { return t == FileSystem::Type::Unknown ? d : t; };
|
||||
auto correctFS = [ d = m_defaultFsType ]( FileSystem::Type t ) { return t == FileSystem::Type::Unknown ? d : t; };
|
||||
|
||||
// Create the partitions.
|
||||
currentSector = firstSector;
|
||||
|
@ -19,7 +19,8 @@
|
||||
* to bother with one-byte accuracy (and anyway, a double has at least 50 bits
|
||||
* at which point we're printing giga (or gibi) bytes).
|
||||
*/
|
||||
static inline QString formatByteSize( qint64 sizeValue )
|
||||
static inline QString
|
||||
formatByteSize( qint64 sizeValue )
|
||||
{
|
||||
return Capacity::formatByteSize( static_cast< double >( sizeValue ) );
|
||||
}
|
||||
|
@ -176,10 +176,14 @@ ChoicePage::init( PartitionCoreModule* core )
|
||||
|
||||
|
||||
// We need to do this because a PCM revert invalidates the deviceModel.
|
||||
connect( core, &PartitionCoreModule::reverted, this, [=] {
|
||||
setModelToComboBox( m_drivesCombo, core->deviceModel() );
|
||||
m_drivesCombo->setCurrentIndex( m_lastSelectedDeviceIndex );
|
||||
} );
|
||||
connect( core,
|
||||
&PartitionCoreModule::reverted,
|
||||
this,
|
||||
[ = ]
|
||||
{
|
||||
setModelToComboBox( m_drivesCombo, core->deviceModel() );
|
||||
m_drivesCombo->setCurrentIndex( m_lastSelectedDeviceIndex );
|
||||
} );
|
||||
setModelToComboBox( m_drivesCombo, core->deviceModel() );
|
||||
|
||||
connect( m_drivesCombo, qOverload< int >( &QComboBox::currentIndexChanged ), this, &ChoicePage::applyDeviceChoice );
|
||||
@ -303,26 +307,30 @@ ChoicePage::setupChoices()
|
||||
#else
|
||||
auto buttonSignal = &QButtonGroup::idToggled;
|
||||
#endif
|
||||
connect( m_grp, buttonSignal, this, [this]( int id, bool checked ) {
|
||||
if ( checked ) // An action was picked.
|
||||
{
|
||||
m_config->setInstallChoice( id );
|
||||
updateNextEnabled();
|
||||
connect( m_grp,
|
||||
buttonSignal,
|
||||
this,
|
||||
[ this ]( int id, bool checked )
|
||||
{
|
||||
if ( checked ) // An action was picked.
|
||||
{
|
||||
m_config->setInstallChoice( id );
|
||||
updateNextEnabled();
|
||||
|
||||
Q_EMIT actionChosen();
|
||||
}
|
||||
else // An action was unpicked, either on its own or because of another selection.
|
||||
{
|
||||
if ( m_grp->checkedButton() == nullptr ) // If no other action is chosen, we must
|
||||
{
|
||||
// set m_choice to NoChoice and reset previews.
|
||||
m_config->setInstallChoice( InstallChoice::NoChoice );
|
||||
updateNextEnabled();
|
||||
Q_EMIT actionChosen();
|
||||
}
|
||||
else // An action was unpicked, either on its own or because of another selection.
|
||||
{
|
||||
if ( m_grp->checkedButton() == nullptr ) // If no other action is chosen, we must
|
||||
{
|
||||
// set m_choice to NoChoice and reset previews.
|
||||
m_config->setInstallChoice( InstallChoice::NoChoice );
|
||||
updateNextEnabled();
|
||||
|
||||
Q_EMIT actionChosen();
|
||||
}
|
||||
}
|
||||
} );
|
||||
Q_EMIT actionChosen();
|
||||
}
|
||||
}
|
||||
} );
|
||||
|
||||
m_rightLayout->setStretchFactor( m_itemsLayout, 1 );
|
||||
m_rightLayout->setStretchFactor( m_previewBeforeFrame, 0 );
|
||||
@ -401,11 +409,13 @@ ChoicePage::applyDeviceChoice()
|
||||
if ( m_core->isDirty() )
|
||||
{
|
||||
ScanningDialog::run(
|
||||
QtConcurrent::run( [=] {
|
||||
QMutexLocker locker( &m_coreMutex );
|
||||
m_core->revertAllDevices();
|
||||
} ),
|
||||
[this] { continueApplyDeviceChoice(); },
|
||||
QtConcurrent::run(
|
||||
[ = ]
|
||||
{
|
||||
QMutexLocker locker( &m_coreMutex );
|
||||
m_core->revertAllDevices();
|
||||
} ),
|
||||
[ this ] { continueApplyDeviceChoice(); },
|
||||
this );
|
||||
}
|
||||
else
|
||||
@ -493,11 +503,14 @@ ChoicePage::applyActionChoice( InstallChoice choice )
|
||||
if ( m_core->isDirty() )
|
||||
{
|
||||
ScanningDialog::run(
|
||||
QtConcurrent::run( [=] {
|
||||
QMutexLocker locker( &m_coreMutex );
|
||||
m_core->revertDevice( selectedDevice() );
|
||||
} ),
|
||||
[=] {
|
||||
QtConcurrent::run(
|
||||
[ = ]
|
||||
{
|
||||
QMutexLocker locker( &m_coreMutex );
|
||||
m_core->revertDevice( selectedDevice() );
|
||||
} ),
|
||||
[ = ]
|
||||
{
|
||||
PartitionActions::doAutopartition( m_core, selectedDevice(), options );
|
||||
Q_EMIT deviceChosen();
|
||||
},
|
||||
@ -514,10 +527,12 @@ ChoicePage::applyActionChoice( InstallChoice choice )
|
||||
if ( m_core->isDirty() )
|
||||
{
|
||||
ScanningDialog::run(
|
||||
QtConcurrent::run( [=] {
|
||||
QMutexLocker locker( &m_coreMutex );
|
||||
m_core->revertDevice( selectedDevice() );
|
||||
} ),
|
||||
QtConcurrent::run(
|
||||
[ = ]
|
||||
{
|
||||
QMutexLocker locker( &m_coreMutex );
|
||||
m_core->revertDevice( selectedDevice() );
|
||||
} ),
|
||||
[] {},
|
||||
this );
|
||||
}
|
||||
@ -532,11 +547,14 @@ ChoicePage::applyActionChoice( InstallChoice choice )
|
||||
if ( m_core->isDirty() )
|
||||
{
|
||||
ScanningDialog::run(
|
||||
QtConcurrent::run( [=] {
|
||||
QMutexLocker locker( &m_coreMutex );
|
||||
m_core->revertDevice( selectedDevice() );
|
||||
} ),
|
||||
[this] {
|
||||
QtConcurrent::run(
|
||||
[ = ]
|
||||
{
|
||||
QMutexLocker locker( &m_coreMutex );
|
||||
m_core->revertDevice( selectedDevice() );
|
||||
} ),
|
||||
[ this ]
|
||||
{
|
||||
// We need to reupdate after reverting because the splitter widget is
|
||||
// not a true view.
|
||||
updateActionChoicePreview( m_config->installChoice() );
|
||||
@ -772,7 +790,8 @@ ChoicePage::doReplaceSelectedPartition( const QModelIndex& current )
|
||||
|
||||
ScanningDialog::run(
|
||||
QtConcurrent::run(
|
||||
[this, current, homePartitionPath]( bool doReuseHomePartition ) {
|
||||
[ this, current, homePartitionPath ]( bool doReuseHomePartition )
|
||||
{
|
||||
QMutexLocker locker( &m_coreMutex );
|
||||
|
||||
if ( m_core->isDirty() )
|
||||
@ -853,7 +872,8 @@ ChoicePage::doReplaceSelectedPartition( const QModelIndex& current )
|
||||
}
|
||||
},
|
||||
m_reuseHomeCheckBox->isChecked() ),
|
||||
[this, homePartitionPath] {
|
||||
[ this, homePartitionPath ]
|
||||
{
|
||||
m_reuseHomeCheckBox->setVisible( !homePartitionPath->isEmpty() );
|
||||
if ( !homePartitionPath->isEmpty() )
|
||||
m_reuseHomeCheckBox->setText( tr( "Reuse %1 as home partition for %2." )
|
||||
@ -1006,7 +1026,8 @@ ChoicePage::updateActionChoicePreview( InstallChoice choice )
|
||||
connect( m_afterPartitionSplitterWidget,
|
||||
&PartitionSplitterWidget::partitionResized,
|
||||
this,
|
||||
[this, sizeLabel]( const QString& path, qint64 size, qint64 sizeNext ) {
|
||||
[ this, sizeLabel ]( const QString& path, qint64 size, qint64 sizeNext )
|
||||
{
|
||||
Q_UNUSED( path )
|
||||
sizeLabel->setText(
|
||||
tr( "%1 will be shrunk to %2MiB and a new "
|
||||
@ -1020,7 +1041,8 @@ ChoicePage::updateActionChoicePreview( InstallChoice choice )
|
||||
m_previewAfterFrame->show();
|
||||
m_previewAfterLabel->show();
|
||||
|
||||
SelectionFilter filter = []( const QModelIndex& index ) {
|
||||
SelectionFilter filter = []( const QModelIndex& index )
|
||||
{
|
||||
return PartUtils::canBeResized(
|
||||
static_cast< Partition* >( index.data( PartitionModel::PartitionPtrRole ).value< void* >() ),
|
||||
Logger::Once() );
|
||||
@ -1069,17 +1091,22 @@ ChoicePage::updateActionChoicePreview( InstallChoice choice )
|
||||
eraseBootloaderLabel->setText( tr( "Boot loader location:" ) );
|
||||
|
||||
m_bootloaderComboBox = createBootloaderComboBox( eraseWidget );
|
||||
connect( m_core->bootLoaderModel(), &QAbstractItemModel::modelReset, [this]() {
|
||||
if ( !m_bootloaderComboBox.isNull() )
|
||||
{
|
||||
Calamares::restoreSelectedBootLoader( *m_bootloaderComboBox, m_core->bootLoaderInstallPath() );
|
||||
}
|
||||
} );
|
||||
connect( m_core->bootLoaderModel(),
|
||||
&QAbstractItemModel::modelReset,
|
||||
[ this ]()
|
||||
{
|
||||
if ( !m_bootloaderComboBox.isNull() )
|
||||
{
|
||||
Calamares::restoreSelectedBootLoader( *m_bootloaderComboBox,
|
||||
m_core->bootLoaderInstallPath() );
|
||||
}
|
||||
} );
|
||||
connect(
|
||||
m_core,
|
||||
&PartitionCoreModule::deviceReverted,
|
||||
this,
|
||||
[this]( Device* dev ) {
|
||||
[ this ]( Device* dev )
|
||||
{
|
||||
Q_UNUSED( dev )
|
||||
if ( !m_bootloaderComboBox.isNull() )
|
||||
{
|
||||
@ -1110,7 +1137,8 @@ ChoicePage::updateActionChoicePreview( InstallChoice choice )
|
||||
}
|
||||
else
|
||||
{
|
||||
SelectionFilter filter = []( const QModelIndex& index ) {
|
||||
SelectionFilter filter = []( const QModelIndex& index )
|
||||
{
|
||||
return PartUtils::canBeReplaced(
|
||||
static_cast< Partition* >( index.data( PartitionModel::PartitionPtrRole ).value< void* >() ),
|
||||
Logger::Once() );
|
||||
@ -1217,18 +1245,22 @@ ChoicePage::createBootloaderComboBox( QWidget* parent )
|
||||
comboForBootloader->setModel( m_core->bootLoaderModel() );
|
||||
|
||||
// When the chosen bootloader device changes, we update the choice in the PCM
|
||||
connect( comboForBootloader, QOverload< int >::of( &QComboBox::currentIndexChanged ), this, [this]( int newIndex ) {
|
||||
QComboBox* bootloaderCombo = qobject_cast< QComboBox* >( sender() );
|
||||
if ( bootloaderCombo )
|
||||
{
|
||||
QVariant var = bootloaderCombo->itemData( newIndex, BootLoaderModel::BootLoaderPathRole );
|
||||
if ( !var.isValid() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
m_core->setBootLoaderInstallPath( var.toString() );
|
||||
}
|
||||
} );
|
||||
connect( comboForBootloader,
|
||||
QOverload< int >::of( &QComboBox::currentIndexChanged ),
|
||||
this,
|
||||
[ this ]( int newIndex )
|
||||
{
|
||||
QComboBox* bootloaderCombo = qobject_cast< QComboBox* >( sender() );
|
||||
if ( bootloaderCombo )
|
||||
{
|
||||
QVariant var = bootloaderCombo->itemData( newIndex, BootLoaderModel::BootLoaderPathRole );
|
||||
if ( !var.isValid() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
m_core->setBootLoaderInstallPath( var.toString() );
|
||||
}
|
||||
} );
|
||||
|
||||
return comboForBootloader;
|
||||
}
|
||||
|
@ -325,16 +325,10 @@ CreatePartitionDialog::updateMountPointUi()
|
||||
void
|
||||
CreatePartitionDialog::checkMountPointSelection()
|
||||
{
|
||||
if ( m_usedMountPoints.contains( selectedMountPoint( m_ui->mountPointComboBox ) ) )
|
||||
{
|
||||
m_ui->labelMountPoint->setText( tr( "Mountpoint already in use. Please select another one." ) );
|
||||
m_ui->buttonBox->button( QDialogButtonBox::Ok )->setEnabled( false );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ui->labelMountPoint->setText( QString() );
|
||||
m_ui->buttonBox->button( QDialogButtonBox::Ok )->setEnabled( true );
|
||||
}
|
||||
validateMountPoint( selectedMountPoint( m_ui->mountPointComboBox ),
|
||||
m_usedMountPoints,
|
||||
m_ui->mountPointExplanation,
|
||||
m_ui->buttonBox->button( QDialogButtonBox::Ok ) );
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -68,7 +68,7 @@ SPDX-License-Identifier: GPL-3.0-or-later
|
||||
<item>
|
||||
<widget class="QRadioButton" name="primaryRadioButton">
|
||||
<property name="text">
|
||||
<string>&Primary</string>
|
||||
<string>Primar&y</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
@ -171,6 +171,12 @@ SPDX-License-Identifier: GPL-3.0-or-later
|
||||
</item>
|
||||
<item row="8" column="1">
|
||||
<widget class="QComboBox" name="mountPointComboBox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="editable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
@ -179,21 +185,14 @@ SPDX-License-Identifier: GPL-3.0-or-later
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="1">
|
||||
<widget class="QLabel" name="labelMountPoint">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="0">
|
||||
<item row="12" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Flags:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="1">
|
||||
<item row="12" column="1">
|
||||
<widget class="QListWidget" name="m_listFlags">
|
||||
<property name="alternatingRowColors">
|
||||
<bool>true</bool>
|
||||
@ -206,7 +205,7 @@ SPDX-License-Identifier: GPL-3.0-or-later
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="12" column="0">
|
||||
<item row="13" column="0">
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
@ -219,14 +218,8 @@ SPDX-License-Identifier: GPL-3.0-or-later
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="9" column="1">
|
||||
<item row="10" column="1">
|
||||
<widget class="QLineEdit" name="filesystemLabelEdit">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>150</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Label for the filesystem</string>
|
||||
</property>
|
||||
@ -235,13 +228,20 @@ SPDX-License-Identifier: GPL-3.0-or-later
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="0">
|
||||
<item row="10" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>FS Label:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="1">
|
||||
<widget class="QLabel" name="mountPointExplanation">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
|
@ -69,22 +69,25 @@ EditExistingPartitionDialog::EditExistingPartitionDialog( Device* device,
|
||||
|
||||
replacePartResizerWidget();
|
||||
|
||||
connect( m_ui->formatRadioButton, &QAbstractButton::toggled, [this]( bool doFormat ) {
|
||||
replacePartResizerWidget();
|
||||
connect( m_ui->formatRadioButton,
|
||||
&QAbstractButton::toggled,
|
||||
[ this ]( bool doFormat )
|
||||
{
|
||||
replacePartResizerWidget();
|
||||
|
||||
m_ui->fileSystemLabel->setEnabled( doFormat );
|
||||
m_ui->fileSystemComboBox->setEnabled( doFormat );
|
||||
m_ui->fileSystemLabel->setEnabled( doFormat );
|
||||
m_ui->fileSystemComboBox->setEnabled( doFormat );
|
||||
|
||||
if ( !doFormat )
|
||||
{
|
||||
m_ui->fileSystemComboBox->setCurrentText( userVisibleFS( m_partition->fileSystem() ) );
|
||||
}
|
||||
if ( !doFormat )
|
||||
{
|
||||
m_ui->fileSystemComboBox->setCurrentText( userVisibleFS( m_partition->fileSystem() ) );
|
||||
}
|
||||
|
||||
updateMountPointPicker();
|
||||
} );
|
||||
updateMountPointPicker();
|
||||
} );
|
||||
|
||||
connect(
|
||||
m_ui->fileSystemComboBox, &QComboBox::currentTextChanged, [this]( QString ) { updateMountPointPicker(); } );
|
||||
m_ui->fileSystemComboBox, &QComboBox::currentTextChanged, [ this ]( QString ) { updateMountPointPicker(); } );
|
||||
|
||||
// File system
|
||||
QStringList fsNames;
|
||||
@ -295,14 +298,8 @@ EditExistingPartitionDialog::updateMountPointPicker()
|
||||
void
|
||||
EditExistingPartitionDialog::checkMountPointSelection()
|
||||
{
|
||||
if ( m_usedMountPoints.contains( selectedMountPoint( m_ui->mountPointComboBox ) ) )
|
||||
{
|
||||
m_ui->labelMountPoint->setText( tr( "Mountpoint already in use. Please select another one." ) );
|
||||
m_ui->buttonBox->button( QDialogButtonBox::Ok )->setEnabled( false );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ui->labelMountPoint->setText( QString() );
|
||||
m_ui->buttonBox->button( QDialogButtonBox::Ok )->setEnabled( true );
|
||||
}
|
||||
validateMountPoint( selectedMountPoint( m_ui->mountPointComboBox ),
|
||||
m_usedMountPoints,
|
||||
m_ui->mountPointExplanation,
|
||||
m_ui->buttonBox->button( QDialogButtonBox::Ok ) );
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ SPDX-License-Identifier: GPL-3.0-or-later
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Content:</string>
|
||||
<string>Con&tent:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>keepRadioButton</cstring>
|
||||
@ -109,6 +109,12 @@ SPDX-License-Identifier: GPL-3.0-or-later
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QComboBox" name="mountPointComboBox">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="editable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
@ -147,14 +153,14 @@ SPDX-License-Identifier: GPL-3.0-or-later
|
||||
<item row="5" column="1">
|
||||
<widget class="QComboBox" name="fileSystemComboBox"/>
|
||||
</item>
|
||||
<item row="9" column="0">
|
||||
<item row="10" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Flags:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="1">
|
||||
<item row="10" column="1">
|
||||
<widget class="QListWidget" name="m_listFlags">
|
||||
<property name="alternatingRowColors">
|
||||
<bool>true</bool>
|
||||
@ -168,20 +174,7 @@ SPDX-License-Identifier: GPL-3.0-or-later
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="1">
|
||||
<widget class="QLabel" name="labelMountPoint">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1">
|
||||
<widget class="QLineEdit" name="fileSystemLabelEdit">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>150</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Label for the filesystem</string>
|
||||
</property>
|
||||
@ -190,13 +183,20 @@ SPDX-License-Identifier: GPL-3.0-or-later
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<item row="8" column="0">
|
||||
<widget class="QLabel" name="fileSystemLabelLabel">
|
||||
<property name="text">
|
||||
<string>FS Label:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1">
|
||||
<widget class="QLabel" name="mountPointExplanation">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
|
@ -13,9 +13,27 @@
|
||||
|
||||
#include "ui_EncryptWidget.h"
|
||||
|
||||
#include "Branding.h"
|
||||
#include "utils/CalamaresUtilsGui.h"
|
||||
#include "utils/Retranslator.h"
|
||||
|
||||
/** @brief Does this system support whole-disk encryption?
|
||||
*
|
||||
* Returns @c true if the system is likely to support encryption
|
||||
* with sufficient performance to be usable. A machine that can't
|
||||
* doe hardware-assisted AES is **probably** too slow, so we could
|
||||
* warn the user that ticking the "encrypt system" box is a bad
|
||||
* idea.
|
||||
*
|
||||
* Since we don't have an oracle that can answer that question,
|
||||
* just pretend every system can do it.
|
||||
*/
|
||||
static inline bool
|
||||
systemSupportsEncryptionAcceptably()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
EncryptWidget::EncryptWidget( QWidget* parent )
|
||||
: QWidget( parent )
|
||||
, m_ui( new Ui::EncryptWidget )
|
||||
@ -27,6 +45,18 @@ EncryptWidget::EncryptWidget( QWidget* parent )
|
||||
m_ui->m_passphraseLineEdit->hide();
|
||||
m_ui->m_confirmLineEdit->hide();
|
||||
m_ui->m_iconLabel->hide();
|
||||
// TODO: this deserves better rendering, an icon or something, but that will
|
||||
// depend on having a non-bogus implementation of systemSupportsEncryptionAcceptably
|
||||
if ( systemSupportsEncryptionAcceptably() )
|
||||
{
|
||||
m_ui->m_encryptionUnsupportedLabel->hide();
|
||||
}
|
||||
else
|
||||
{
|
||||
// This is really ugly, but the character is unicode "unlocked"
|
||||
m_ui->m_encryptionUnsupportedLabel->setText( QStringLiteral( "🔓" ) );
|
||||
m_ui->m_encryptionUnsupportedLabel->show();
|
||||
}
|
||||
|
||||
connect( m_ui->m_encryptCheckBox, &QCheckBox::stateChanged, this, &EncryptWidget::onCheckBoxStateChanged );
|
||||
connect( m_ui->m_passphraseLineEdit, &QLineEdit::textEdited, this, &EncryptWidget::onPassphraseEdited );
|
||||
|
@ -37,6 +37,19 @@ SPDX-License-Identifier: GPL-3.0-or-later
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="m_encryptionUnsupportedLabel">
|
||||
<property name="toolTip">
|
||||
<string>Your system does not seem to support encryption well enough to encrypt the entire system. You may enable encryption, but performance may suffer.</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string notr="true">🔓</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="m_passphraseLineEdit">
|
||||
<property name="echoMode">
|
||||
@ -57,6 +70,19 @@ SPDX-License-Identifier: GPL-3.0-or-later
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="m_iconLabel">
|
||||
<property name="text">
|
||||
|
@ -54,9 +54,10 @@ PartitionBarsView::PartitionBarsView( QWidget* parent )
|
||||
setSelectionMode( QAbstractItemView::SingleSelection );
|
||||
|
||||
// Debug
|
||||
connect( this, &PartitionBarsView::clicked, this, [=]( const QModelIndex& index ) {
|
||||
cDebug() << "Clicked row" << index.row();
|
||||
} );
|
||||
connect( this,
|
||||
&PartitionBarsView::clicked,
|
||||
this,
|
||||
[ = ]( const QModelIndex& index ) { cDebug() << "Clicked row" << index.row(); } );
|
||||
setMouseTracking( true );
|
||||
}
|
||||
|
||||
@ -399,7 +400,7 @@ void
|
||||
PartitionBarsView::setSelectionModel( QItemSelectionModel* selectionModel )
|
||||
{
|
||||
QAbstractItemView::setSelectionModel( selectionModel );
|
||||
connect( selectionModel, &QItemSelectionModel::selectionChanged, this, [=] { viewport()->repaint(); } );
|
||||
connect( selectionModel, &QItemSelectionModel::selectionChanged, this, [ = ] { viewport()->repaint(); } );
|
||||
}
|
||||
|
||||
|
||||
@ -410,7 +411,8 @@ PartitionBarsView::setSelectionFilter( std::function< bool( const QModelIndex& )
|
||||
}
|
||||
|
||||
|
||||
QModelIndex PartitionBarsView::moveCursor( CursorAction, Qt::KeyboardModifiers )
|
||||
QModelIndex
|
||||
PartitionBarsView::moveCursor( CursorAction, Qt::KeyboardModifiers )
|
||||
{
|
||||
return QModelIndex();
|
||||
}
|
||||
|
@ -12,13 +12,17 @@
|
||||
#include "PartitionDialogHelpers.h"
|
||||
|
||||
#include "core/PartUtils.h"
|
||||
#include "gui/CreatePartitionDialog.h"
|
||||
|
||||
#include "GlobalStorage.h"
|
||||
#include "JobQueue.h"
|
||||
#include "utils/Logger.h"
|
||||
|
||||
#include <QComboBox>
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include <QListWidget>
|
||||
#include <QPushButton>
|
||||
|
||||
QStringList
|
||||
standardMountPoints()
|
||||
@ -37,7 +41,7 @@ void
|
||||
standardMountPoints( QComboBox& combo )
|
||||
{
|
||||
combo.clear();
|
||||
combo.addItem( QObject::tr( "(no mount point)" ) );
|
||||
combo.lineEdit()->setPlaceholderText( QObject::tr( "(no mount point)" ) );
|
||||
combo.addItems( standardMountPoints() );
|
||||
}
|
||||
|
||||
@ -51,10 +55,6 @@ standardMountPoints( QComboBox& combo, const QString& selected )
|
||||
QString
|
||||
selectedMountPoint( QComboBox& combo )
|
||||
{
|
||||
if ( combo.currentIndex() == 0 )
|
||||
{
|
||||
return QString();
|
||||
}
|
||||
return combo.currentText();
|
||||
}
|
||||
|
||||
@ -63,7 +63,7 @@ setSelectedMountPoint( QComboBox& combo, const QString& selected )
|
||||
{
|
||||
if ( selected.isEmpty() )
|
||||
{
|
||||
combo.setCurrentIndex( 0 ); // (no mount point)
|
||||
combo.setCurrentIndex( -1 ); // (no mount point)
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -80,6 +80,34 @@ setSelectedMountPoint( QComboBox& combo, const QString& selected )
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
validateMountPoint( const QString& mountPoint, const QStringList& inUse, QLabel* label, QPushButton* button )
|
||||
{
|
||||
QString msg;
|
||||
bool ok = true;
|
||||
|
||||
if ( inUse.contains( mountPoint ) )
|
||||
{
|
||||
msg = CreatePartitionDialog::tr( "Mountpoint already in use. Please select another one." );
|
||||
ok = false;
|
||||
}
|
||||
else if ( !mountPoint.isEmpty() && !mountPoint.startsWith( '/' ) )
|
||||
{
|
||||
msg = CreatePartitionDialog::tr( "Mountpoint must start with a <tt>/</tt>." );
|
||||
ok = false;
|
||||
}
|
||||
|
||||
if ( label )
|
||||
{
|
||||
label->setText( msg );
|
||||
}
|
||||
if ( button )
|
||||
{
|
||||
button->setEnabled( ok );
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
||||
PartitionTable::Flags
|
||||
flagsFromList( const QListWidget& list )
|
||||
|
@ -16,7 +16,9 @@
|
||||
|
||||
#include <QStringList>
|
||||
|
||||
class QPushButton;
|
||||
class QComboBox;
|
||||
class QLabel;
|
||||
class QListWidget;
|
||||
|
||||
/**
|
||||
@ -58,6 +60,16 @@ setSelectedMountPoint( QComboBox* combo, const QString& selected )
|
||||
setSelectedMountPoint( *combo, selected );
|
||||
}
|
||||
|
||||
/** @brief Validate a @p mountPoint and adjust the UI
|
||||
*
|
||||
* If @p mountPoint is valid -- unused and starts with a /, for instance --
|
||||
* then the button is enabled, label is cleared, and returns @c true.
|
||||
*
|
||||
* If it is not valid, returns @c false and sets the UI
|
||||
* to explain why.
|
||||
*/
|
||||
bool validateMountPoint( const QString& mountPoint, const QStringList& inUse, QLabel* label, QPushButton* button );
|
||||
|
||||
/**
|
||||
* Get the flags that have been checked in the list widget.
|
||||
*/
|
||||
|
@ -519,7 +519,7 @@ void
|
||||
PartitionLabelsView::setSelectionModel( QItemSelectionModel* selectionModel )
|
||||
{
|
||||
QAbstractItemView::setSelectionModel( selectionModel );
|
||||
connect( selectionModel, &QItemSelectionModel::selectionChanged, this, [=] { viewport()->repaint(); } );
|
||||
connect( selectionModel, &QItemSelectionModel::selectionChanged, this, [ = ] { viewport()->repaint(); } );
|
||||
}
|
||||
|
||||
|
||||
|
@ -451,15 +451,18 @@ void
|
||||
PartitionPage::onRevertClicked()
|
||||
{
|
||||
ScanningDialog::run(
|
||||
QtConcurrent::run( [this] {
|
||||
QMutexLocker locker( &m_revertMutex );
|
||||
QtConcurrent::run(
|
||||
[ this ]
|
||||
{
|
||||
QMutexLocker locker( &m_revertMutex );
|
||||
|
||||
int oldIndex = m_ui->deviceComboBox->currentIndex();
|
||||
m_core->revertAllDevices();
|
||||
m_ui->deviceComboBox->setCurrentIndex( ( oldIndex < 0 ) ? 0 : oldIndex );
|
||||
updateFromCurrentDevice();
|
||||
} ),
|
||||
[this] {
|
||||
int oldIndex = m_ui->deviceComboBox->currentIndex();
|
||||
m_core->revertAllDevices();
|
||||
m_ui->deviceComboBox->setCurrentIndex( ( oldIndex < 0 ) ? 0 : oldIndex );
|
||||
updateFromCurrentDevice();
|
||||
} ),
|
||||
[ this ]
|
||||
{
|
||||
m_lastSelectedBootLoaderIndex = -1;
|
||||
if ( m_ui->bootLoaderComboBox->currentIndex() < 0 )
|
||||
{
|
||||
@ -606,7 +609,8 @@ PartitionPage::updateFromCurrentDevice()
|
||||
m_ui->partitionBarsView->selectionModel(),
|
||||
&QItemSelectionModel::currentChanged,
|
||||
this,
|
||||
[=] {
|
||||
[ = ]
|
||||
{
|
||||
QModelIndex selectedIndex = m_ui->partitionBarsView->selectionModel()->currentIndex();
|
||||
selectedIndex = selectedIndex.sibling( selectedIndex.row(), 0 );
|
||||
m_ui->partitionBarsView->setCurrentIndex( selectedIndex );
|
||||
@ -625,7 +629,7 @@ PartitionPage::updateFromCurrentDevice()
|
||||
// model changes
|
||||
connect( m_ui->partitionTreeView->selectionModel(),
|
||||
&QItemSelectionModel::currentChanged,
|
||||
[this]( const QModelIndex&, const QModelIndex& ) { updateButtons(); } );
|
||||
[ this ]( const QModelIndex&, const QModelIndex& ) { updateButtons(); } );
|
||||
connect( model, &QAbstractItemModel::modelReset, this, &PartitionPage::onPartitionModelReset );
|
||||
}
|
||||
|
||||
|
@ -159,14 +159,16 @@ PartitionSplitterWidget::setSplitPartition( const QString& path, qint64 minSize,
|
||||
m_itemToResizePath.clear();
|
||||
}
|
||||
|
||||
PartitionSplitterItem itemToResize = _findItem( m_items, [path]( PartitionSplitterItem& item ) -> bool {
|
||||
if ( path == item.itemPath )
|
||||
{
|
||||
item.status = PartitionSplitterItem::Resizing;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
} );
|
||||
PartitionSplitterItem itemToResize = _findItem( m_items,
|
||||
[ path ]( PartitionSplitterItem& item ) -> bool
|
||||
{
|
||||
if ( path == item.itemPath )
|
||||
{
|
||||
item.status = PartitionSplitterItem::Resizing;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
} );
|
||||
|
||||
if ( itemToResize.isNull() )
|
||||
{
|
||||
@ -184,14 +186,16 @@ PartitionSplitterWidget::setSplitPartition( const QString& path, qint64 minSize,
|
||||
|
||||
qint64 newSize = m_itemToResize.size - preferredSize;
|
||||
m_itemToResize.size = preferredSize;
|
||||
int opCount = _eachItem( m_items, [preferredSize]( PartitionSplitterItem& item ) -> bool {
|
||||
if ( item.status == PartitionSplitterItem::Resizing )
|
||||
{
|
||||
item.size = preferredSize;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
} );
|
||||
int opCount = _eachItem( m_items,
|
||||
[ preferredSize ]( PartitionSplitterItem& item ) -> bool
|
||||
{
|
||||
if ( item.status == PartitionSplitterItem::Resizing )
|
||||
{
|
||||
item.size = preferredSize;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
} );
|
||||
cDebug() << "each splitter item opcount:" << opCount;
|
||||
m_itemMinSize = minSize;
|
||||
m_itemMaxSize = maxSize;
|
||||
@ -358,19 +362,21 @@ PartitionSplitterWidget::mouseMoveEvent( QMouseEvent* event )
|
||||
|
||||
m_itemToResize.size = qRound64( span * percent );
|
||||
m_itemToResizeNext.size -= m_itemToResize.size - oldsize;
|
||||
_eachItem( m_items, [this]( PartitionSplitterItem& item ) -> bool {
|
||||
if ( item.status == PartitionSplitterItem::Resizing )
|
||||
{
|
||||
item.size = m_itemToResize.size;
|
||||
return true;
|
||||
}
|
||||
else if ( item.status == PartitionSplitterItem::ResizingNext )
|
||||
{
|
||||
item.size = m_itemToResizeNext.size;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
} );
|
||||
_eachItem( m_items,
|
||||
[ this ]( PartitionSplitterItem& item ) -> bool
|
||||
{
|
||||
if ( item.status == PartitionSplitterItem::Resizing )
|
||||
{
|
||||
item.size = m_itemToResize.size;
|
||||
return true;
|
||||
}
|
||||
else if ( item.status == PartitionSplitterItem::ResizingNext )
|
||||
{
|
||||
item.size = m_itemToResizeNext.size;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
} );
|
||||
|
||||
repaint();
|
||||
|
||||
|
@ -46,9 +46,10 @@ ReplaceWidget::ReplaceWidget( PartitionCoreModule* core, QComboBox* devicesCombo
|
||||
m_ui->bootStatusLabel->clear();
|
||||
|
||||
updateFromCurrentDevice( devicesComboBox );
|
||||
connect( devicesComboBox, &QComboBox::currentTextChanged, this, [=]( const QString& /* text */ ) {
|
||||
updateFromCurrentDevice( devicesComboBox );
|
||||
} );
|
||||
connect( devicesComboBox,
|
||||
&QComboBox::currentTextChanged,
|
||||
this,
|
||||
[ = ]( const QString& /* text */ ) { updateFromCurrentDevice( devicesComboBox ); } );
|
||||
|
||||
CALAMARES_RETRANSLATE( onPartitionSelected(); );
|
||||
}
|
||||
|
@ -47,12 +47,16 @@ ScanningDialog::run( const QFuture< void >& future,
|
||||
theDialog->show();
|
||||
|
||||
QFutureWatcher< void >* watcher = new QFutureWatcher< void >();
|
||||
connect( watcher, &QFutureWatcher< void >::finished, theDialog, [watcher, theDialog, callback] {
|
||||
watcher->deleteLater();
|
||||
theDialog->hide();
|
||||
theDialog->deleteLater();
|
||||
callback();
|
||||
} );
|
||||
connect( watcher,
|
||||
&QFutureWatcher< void >::finished,
|
||||
theDialog,
|
||||
[ watcher, theDialog, callback ]
|
||||
{
|
||||
watcher->deleteLater();
|
||||
theDialog->hide();
|
||||
theDialog->deleteLater();
|
||||
callback();
|
||||
} );
|
||||
|
||||
watcher->setFuture( future );
|
||||
}
|
||||
|
@ -45,17 +45,25 @@ VolumeGroupBaseDialog::VolumeGroupBaseDialog( QString& vgName, QVector< const Pa
|
||||
updateOkButton();
|
||||
updateTotalSize();
|
||||
|
||||
connect( ui->pvList, &QListWidget::itemChanged, this, [&]( QListWidgetItem* ) {
|
||||
updateTotalSize();
|
||||
updateOkButton();
|
||||
} );
|
||||
connect( ui->pvList,
|
||||
&QListWidget::itemChanged,
|
||||
this,
|
||||
[ & ]( QListWidgetItem* )
|
||||
{
|
||||
updateTotalSize();
|
||||
updateOkButton();
|
||||
} );
|
||||
|
||||
connect( ui->peSize, qOverload< int >( &QSpinBox::valueChanged ), this, [&]( int ) {
|
||||
updateTotalSectors();
|
||||
updateOkButton();
|
||||
} );
|
||||
connect( ui->peSize,
|
||||
qOverload< int >( &QSpinBox::valueChanged ),
|
||||
this,
|
||||
[ & ]( int )
|
||||
{
|
||||
updateTotalSectors();
|
||||
updateOkButton();
|
||||
} );
|
||||
|
||||
connect( ui->vgName, &QLineEdit::textChanged, this, [&]( const QString& ) { updateOkButton(); } );
|
||||
connect( ui->vgName, &QLineEdit::textChanged, this, [ & ]( const QString& ) { updateOkButton(); } );
|
||||
}
|
||||
|
||||
VolumeGroupBaseDialog::~VolumeGroupBaseDialog()
|
||||
|
@ -26,7 +26,9 @@ Calamares::JobResult
|
||||
AutoMountManagementJob::exec()
|
||||
{
|
||||
cVerbose() << "this" << Logger::Pointer( this ) << "value" << Logger::Pointer( m_stored )
|
||||
<< ( m_stored ? "restore" : m_disable ? "disable" : "enable" );
|
||||
<< ( m_stored ? "restore"
|
||||
: m_disable ? "disable"
|
||||
: "enable" );
|
||||
if ( m_stored )
|
||||
{
|
||||
CalamaresUtils::Partition::automountRestore( m_stored );
|
||||
|
@ -157,9 +157,11 @@ getLVMVolumes()
|
||||
QStringList lvscanLines = QString::fromLocal8Bit( process.readAllStandardOutput() ).split( '\n' );
|
||||
// Get the second column (`value(1)`) sinec that is the device name,
|
||||
// remove quoting.
|
||||
std::transform( lvscanLines.begin(), lvscanLines.end(), lvscanLines.begin(), []( const QString& lvscanLine ) {
|
||||
return lvscanLine.simplified().split( ' ' ).value( 1 ).replace( '\'', "" );
|
||||
} );
|
||||
std::transform( lvscanLines.begin(),
|
||||
lvscanLines.end(),
|
||||
lvscanLines.begin(),
|
||||
[]( const QString& lvscanLine )
|
||||
{ return lvscanLine.simplified().split( ' ' ).value( 1 ).replace( '\'', "" ); } );
|
||||
return lvscanLines;
|
||||
}
|
||||
else
|
||||
|
@ -69,8 +69,8 @@ AutoMountJobTests::testRunQueue()
|
||||
QVERIFY( !q.isRunning() );
|
||||
|
||||
QEventLoop loop;
|
||||
QTimer::singleShot( std::chrono::milliseconds( 100 ), [&q]() { q.start(); } );
|
||||
QTimer::singleShot( std::chrono::milliseconds( 5000 ), [&loop]() { loop.quit(); } );
|
||||
QTimer::singleShot( std::chrono::milliseconds( 100 ), [ &q ]() { q.start(); } );
|
||||
QTimer::singleShot( std::chrono::milliseconds( 5000 ), [ &loop ]() { loop.quit(); } );
|
||||
connect( &q, &Calamares::JobQueue::finished, &loop, &QEventLoop::quit );
|
||||
loop.exec();
|
||||
|
||||
|
@ -32,10 +32,10 @@ getPartitionsForDevice_other( const QString& deviceName )
|
||||
{
|
||||
QProcess process;
|
||||
process.setProgram( "sh" );
|
||||
process.setArguments(
|
||||
{ "-c",
|
||||
QString( "echo $(awk '{print \"/dev/\"$4}' /proc/partitions | sed -e '/name/d' -e '/^$/d' -e '/[1-9]/!d' | grep %1)" )
|
||||
.arg( deviceName ) } );
|
||||
process.setArguments( { "-c",
|
||||
QString( "echo $(awk '{print \"/dev/\"$4}' /proc/partitions | sed -e '/name/d' -e '/^$/d' "
|
||||
"-e '/[1-9]/!d' | grep %1)" )
|
||||
.arg( deviceName ) } );
|
||||
process.start();
|
||||
process.waitForFinished();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user