Compare commits
75 Commits
v3.3.0-alp
...
v3.3.0-alp
Author | SHA1 | Date | |
---|---|---|---|
![]() |
0e9cf861f4 | ||
![]() |
065647154e | ||
![]() |
6558cd5150 | ||
![]() |
c939fbce96 | ||
![]() |
c34ee74d08 | ||
![]() |
66cc1a74ec | ||
![]() |
8de565f269 | ||
![]() |
c3f366ce9e | ||
![]() |
7a262362df | ||
![]() |
9a4d992778 | ||
![]() |
fb3112b75d | ||
![]() |
3540121449 | ||
![]() |
a422fd80d9 | ||
![]() |
6cbf2d7e32 | ||
![]() |
40527ffd4e | ||
![]() |
eb242168bf | ||
![]() |
cfb8ef9f65 | ||
![]() |
a988298a65 | ||
![]() |
78e216fedb | ||
![]() |
115f493676 | ||
![]() |
e9f011b686 | ||
![]() |
8c873e0f49 | ||
![]() |
af045ab8b2 | ||
![]() |
42386c520d | ||
![]() |
fd56b5bdc4 | ||
![]() |
be54cd24de | ||
![]() |
ba96f7ddc2 | ||
![]() |
8a43ed99ed | ||
![]() |
84c0da2186 | ||
![]() |
d52d1bfeee | ||
![]() |
73628b13ea | ||
![]() |
8cefb59efb | ||
![]() |
908928b41c | ||
![]() |
97cbebc0f7 | ||
![]() |
04e93f513c | ||
![]() |
eef3bb19d3 | ||
![]() |
64eed3a40c | ||
![]() |
10da2c257d | ||
![]() |
c49d520d3d | ||
![]() |
650bddae63 | ||
![]() |
250678627a | ||
![]() |
56e37d0abb | ||
![]() |
bb0a2d3bd4 | ||
![]() |
eccfdbd986 | ||
![]() |
3360ad612e | ||
![]() |
fb620464d7 | ||
![]() |
ab813b607f | ||
![]() |
0e6d70c395 | ||
![]() |
27c187084b | ||
![]() |
781ced1a59 | ||
![]() |
8f3ac6e00b | ||
![]() |
24652abe8a | ||
![]() |
6e950cf49c | ||
![]() |
4935da8fe4 | ||
![]() |
170a5a8697 | ||
![]() |
18a3092aa1 | ||
![]() |
d7e35d2ad2 | ||
![]() |
f53f83be56 | ||
![]() |
42f4cdd40c | ||
![]() |
f5891e1c8c | ||
![]() |
2322f12b59 | ||
![]() |
c03850a302 | ||
![]() |
66002f375c | ||
![]() |
3d901637d1 | ||
![]() |
a7b3ccf198 | ||
![]() |
f8a845d996 | ||
![]() |
273941f451 | ||
![]() |
010ab08384 | ||
![]() |
2d9d65f33c | ||
![]() |
b4c23b8b70 | ||
![]() |
6a9d9700d4 | ||
![]() |
0688c7f4e7 | ||
![]() |
f42f2514cb | ||
![]() |
09ed07b0c8 | ||
![]() |
f30d568f10 |
2
.github/workflows/nightly-debian.yml
vendored
2
.github/workflows/nightly-debian.yml
vendored
@@ -9,9 +9,7 @@ env:
|
||||
BUILDDIR: /build
|
||||
SRCDIR: ${{ github.workspace }}
|
||||
CMAKE_ARGS: |
|
||||
-DWEBVIEW_FORCE_WEBKIT=1
|
||||
-DKDE_INSTALL_USE_QT_SYS_PATHS=ON
|
||||
-DWITH_PYTHONQT=OFF"
|
||||
-DCMAKE_BUILD_TYPE=Debug
|
||||
|
||||
jobs:
|
||||
|
2
.github/workflows/nightly-neon.yml
vendored
2
.github/workflows/nightly-neon.yml
vendored
@@ -9,9 +9,7 @@ env:
|
||||
BUILDDIR: /build
|
||||
SRCDIR: ${{ github.workspace }}
|
||||
CMAKE_ARGS: |
|
||||
-DWEBVIEW_FORCE_WEBKIT=1
|
||||
-DKDE_INSTALL_USE_QT_SYS_PATHS=ON
|
||||
-DWITH_PYTHONQT=OFF"
|
||||
-DCMAKE_BUILD_TYPE=Debug
|
||||
|
||||
jobs:
|
||||
|
2
.github/workflows/nightly-opensuse.yml
vendored
2
.github/workflows/nightly-opensuse.yml
vendored
@@ -9,9 +9,7 @@ env:
|
||||
BUILDDIR: /build
|
||||
SRCDIR: ${{ github.workspace }}
|
||||
CMAKE_ARGS: |
|
||||
-DWEBVIEW_FORCE_WEBKIT=1
|
||||
-DKDE_INSTALL_USE_QT_SYS_PATHS=ON
|
||||
-DWITH_PYTHONQT=OFF"
|
||||
-DCMAKE_BUILD_TYPE=Debug
|
||||
|
||||
jobs:
|
||||
|
27
.github/workflows/pullrequest.yml
vendored
Normal file
27
.github/workflows/pullrequest.yml
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
name: pullrequest
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, closed]
|
||||
|
||||
jobs:
|
||||
notify:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: "notify: new"
|
||||
if: github.event.action == 'opened'
|
||||
uses: calamares/actions/matrix-notify@v4
|
||||
with:
|
||||
token: ${{ secrets.MATRIX_TOKEN }}
|
||||
room: ${{ secrets.MATRIX_ROOM }}
|
||||
message: |
|
||||
PR OPENED ${{ github.event.pull_request.html_url }} by ${{ github.actor }}
|
||||
.. ${{ github.event.pull_request.title }}"
|
||||
- name: "notify: closed"
|
||||
if: github.event.action == 'closed'
|
||||
uses: calamares/actions/matrix-notify@v4
|
||||
with:
|
||||
token: ${{ secrets.MATRIX_TOKEN }}
|
||||
room: ${{ secrets.MATRIX_ROOM }}
|
||||
message: |
|
||||
PR CLOSED ${{ github.event.pull_request.html_url }} by ${{ github.actor }}
|
@@ -22,7 +22,7 @@ This release contains contributions from (alphabetically by first name):
|
||||
- No module changes yet
|
||||
|
||||
|
||||
# 3.2.60 (2022-06-19) #
|
||||
# 3.2.60 (2022-06-19) #
|
||||
|
||||
This is the first community-maintainence release of Calamares 3.2.
|
||||
Somewhat ironically, all the commits in the branch come from
|
||||
|
49
CHANGES-3.3
49
CHANGES-3.3
@@ -7,7 +7,45 @@ contributors are listed. Note that Calamares does not have a historical
|
||||
changelog -- this log starts with version 3.3.0. See CHANGES-3.2 for
|
||||
the history of the 3.2 series (2018-05 - 2021-12).
|
||||
|
||||
# 3.3.0 (unreleased) #
|
||||
# 3.3.0-alpha2 (2022-08-23)
|
||||
|
||||
Second alpha release, with updated ABI compatibility checking,
|
||||
some 3.3.0 release goals, new features in modules and important bugfixes.
|
||||
|
||||
This release contains contributions from (alphabetically by first name):
|
||||
- Adriaan de Groot
|
||||
- Anke Boersma
|
||||
- Evan James
|
||||
- Shivanand
|
||||
- Vitor Lopes
|
||||
|
||||
## Core ##
|
||||
|
||||
A core **TODO** is moving all library code into the `Calamares` namespace,
|
||||
dropping the `CalamaresUtils` namespace. Modern C++ supports nested namespaces,
|
||||
so in some cases we can use those. This has a drastic effect on ABI compatibility,
|
||||
though, as functions move from one namespace to another. This needs to be
|
||||
completed before a 3.3.0 with ABI stability is released.
|
||||
|
||||
## Modules ##
|
||||
|
||||
Module schemas have been updated to reflect all the incompatible changes.
|
||||
|
||||
|
||||
# 3.3.0-alpha1 (2022-06-27)
|
||||
|
||||
Initial 3.3.0 alpha release to check the release scripts &c.
|
||||
|
||||
This release contains contributions from (alphabetically by first name):
|
||||
- Adriaan de Groot
|
||||
- Aleksey Samoilov
|
||||
- Anke Boersma
|
||||
- Dan Simmons
|
||||
- Evan James
|
||||
- Peter Jung
|
||||
|
||||
|
||||
# 3.3.0-pre-alpha (unreleased) #
|
||||
|
||||
This release contains contributions from (alphabetically by first name):
|
||||
- Anubhav Choudhary
|
||||
@@ -23,8 +61,8 @@ Users (distributions) are **strongly** advised to use the tools
|
||||
for configuration validation (`ci/configvalidator.py`) to check
|
||||
that the distribution configuration files follow the current schema.
|
||||
|
||||
Pre-release versions:
|
||||
- 3.3.0-alpha1 (2022-06-27)
|
||||
- 3.3.0-alpha2 (unreleased)
|
||||
Incompatible module-configuration changes, see #1438.
|
||||
|
||||
## Project ##
|
||||
- The C++ code in the project is now formatted with clang-format 12 or 13,
|
||||
@@ -49,6 +87,8 @@ Pre-release versions:
|
||||
## Modules ##
|
||||
- *bootloader* now supports more options when building the kernel
|
||||
command-line. (Thanks Evan)
|
||||
- *bootloader* no longer supports `@@`-style suffixes for unique-EFI-id
|
||||
generation. Use `${}` instead.
|
||||
- *displaymanager* no longer supports the discontinued *kdm* display manager.
|
||||
- *fstab* configuration has been completely re-done. Many configuration
|
||||
options have moved to the *mount* module. See #1993
|
||||
@@ -56,7 +96,10 @@ Pre-release versions:
|
||||
Please update configurations.
|
||||
- *mount* now does most of the mounting; options that were in *fstab*
|
||||
have moved here. See #1993
|
||||
- *oemid* now uses consistent variable replacement (e.g. KMacroExpander)
|
||||
and does not support `@@DATE@@` anymore (use `${DATE}`).
|
||||
- *partition* requires KPMCore 21.12 (e.g. KPMCore 4.2 API, or later).
|
||||
- *partition* can now skip installing the bootloader in more scenarios.
|
||||
#1632 (Thanks Anubhav)
|
||||
- *preservefiles* follows `${}` variable syntax instead of `@@`.
|
||||
|
||||
|
@@ -43,7 +43,7 @@
|
||||
|
||||
cmake_minimum_required(VERSION 3.16 FATAL_ERROR)
|
||||
|
||||
set(CALAMARES_VERSION 3.3.0-alpha1)
|
||||
set(CALAMARES_VERSION 3.3.0-alpha2)
|
||||
set(CALAMARES_RELEASE_MODE ON) # Set to ON during a release
|
||||
|
||||
if(CMAKE_SCRIPT_MODE_FILE)
|
||||
@@ -65,6 +65,11 @@ project(CALAMARES VERSION ${CALAMARES_VERSION_SHORT} LANGUAGES C CXX HOMEPAGE_UR
|
||||
if(NOT CALAMARES_RELEASE_MODE AND CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR)
|
||||
message(FATAL_ERROR "Do not build development versions in the source-directory.")
|
||||
endif()
|
||||
# Calamares in the 3.3 series promises ABI compatbility, so it sets a
|
||||
# .so-version equal to the series number. We use ci/abicheck.sh to
|
||||
# keep track of this. Note that the **alpha** releases also have
|
||||
# such an .so-version, but are not ABI-stable yet.
|
||||
set(CALAMARES_SOVERSION "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}")
|
||||
|
||||
### OPTIONS
|
||||
#
|
||||
@@ -139,8 +144,6 @@ set(CALAMARES_DESCRIPTION_SUMMARY "The distribution-independent installer framew
|
||||
# (sr@latin in particular) or location (ca@valencia) need special
|
||||
# handling in libcalamares/locale/Translation.h .
|
||||
#
|
||||
# NOTE: move eo (Esperanto) to _ok once Qt can actually create a
|
||||
# locale for it. (Qt 5.12.2 can, see Translation Status section).
|
||||
# NOTE: move ie (Interlingue) to _ok once Qt supports it.
|
||||
# NOTE: update these lines by running `txstats.py`, or for full automation
|
||||
# `txstats.py -e`. See also
|
||||
@@ -411,19 +414,10 @@ set(Calamares_WITH_QML ${WITH_QML})
|
||||
|
||||
### Transifex Translation status
|
||||
#
|
||||
# Construct language lists for use. This massages the language lists
|
||||
# for use with older Qt (which does not support Esperanto) and checks
|
||||
# for some obvious error. The actual work of compiling translations
|
||||
# is done in the lang/ directory.
|
||||
# Construct language lists for use. This massages the language lists if
|
||||
# needed and checks for some obvious errors. The actual work of
|
||||
# compiling translations is done in the lang/ directory.
|
||||
#
|
||||
if(Qt5_VERSION VERSION_GREATER 5.12.1)
|
||||
# At least Qt 5.12.2 seems to support Esperanto in QLocale
|
||||
if("eo" IN_LIST _tx_incomplete)
|
||||
message(STATUS "Esperanto support since Qt 5.12.2, enabling Esperanto locale")
|
||||
list(REMOVE_ITEM _tx_incomplete "eo")
|
||||
list(APPEND _tx_ok "eo")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(curr_tx ${_tx_complete} ${_tx_good} ${_tx_ok} ${_tx_incomplete})
|
||||
set(tx_errors OFF)
|
||||
|
@@ -57,11 +57,6 @@ function( extend_version version short_only short_var long_var )
|
||||
set( ${short_var} "${version}" PARENT_SCOPE )
|
||||
set( _v "${version}" )
|
||||
if ( NOT short_only )
|
||||
# Additional info for non-release builds which want "long" version info
|
||||
# with date and git information (commit, dirty status). That is used only
|
||||
# by CalamaresVersionX.h, which is included by consumers that need a full
|
||||
# version number with all that information; normal consumers can include
|
||||
# CalamaresVersion.h with more stable numbers.
|
||||
string( TIMESTAMP CALAMARES_VERSION_DATE "%Y%m%d" )
|
||||
if( CALAMARES_VERSION_DATE GREATER 0 )
|
||||
set( _v ${_v}.${CALAMARES_VERSION_DATE} )
|
||||
|
@@ -7,21 +7,49 @@
|
||||
#
|
||||
# Finds KPMcore and consistently sets API flags based on the version.
|
||||
#
|
||||
if ( NOT KPMcore_searched_for )
|
||||
set( KPMcore_searched_for TRUE )
|
||||
|
||||
find_package( KPMcore 21.12.0 )
|
||||
# If KPMcore is not found, still create calamares::kpmcore interface
|
||||
# library, which will add definition WITHOUT_KPMcore.
|
||||
#
|
||||
if(NOT TARGET calapmcore)
|
||||
find_package(KPMcore 20.04.0)
|
||||
set_package_properties(
|
||||
KPMcore PROPERTIES
|
||||
KPMcore
|
||||
PROPERTIES
|
||||
URL "https://invent.kde.org/kde/kpmcore"
|
||||
DESCRIPTION "KDE Partitioning library"
|
||||
TYPE RECOMMENDED
|
||||
PURPOSE "For disk partitioning support"
|
||||
)
|
||||
|
||||
if( KPMcore_FOUND )
|
||||
set( KPMcore_API_DEFINITIONS "" )
|
||||
# Create an internal Calamares interface to KPMcore
|
||||
# and give it a nice alias name. If kpmcore is not found,
|
||||
# then make a "no KPMcore" library.
|
||||
add_library(calapmcore INTERFACE)
|
||||
|
||||
if(KPMcore_FOUND)
|
||||
find_package(Qt5 REQUIRED DBus) # Needed for KPMCore
|
||||
find_package(KF5 REQUIRED I18n WidgetsAddons) # Needed for KPMCore
|
||||
|
||||
target_link_libraries(calapmcore INTERFACE kpmcore Qt5::DBus KF5::I18n KF5::WidgetsAddons)
|
||||
target_include_directories(calapmcore INTERFACE ${KPMCORE_INCLUDE_DIR})
|
||||
# If there were KPMcore API variations, figure them out here
|
||||
# target_compile_definitions(calapmcore INTERFACE WITH_KPMcore)
|
||||
|
||||
# Flag that this library has KPMcore support. A variable
|
||||
# set here has the wrong scope. ENV{} would be visible
|
||||
# everywhere but seems the wrong thing to do. Setting
|
||||
# properties on calapmcore requires a newer CMake than
|
||||
# Debian 11 has, so runs into support issues.
|
||||
add_library(calamares::kpmcore ALIAS calapmcore)
|
||||
else()
|
||||
set( KPMcore_API_DEFINITIONS WITHOUT_KPMcore )
|
||||
target_compile_definitions(calapmcore INTERFACE WITHOUT_KPMcore)
|
||||
endif()
|
||||
else()
|
||||
if(TARGET calamares::kpmcore)
|
||||
message(STATUS "KPMcore has already been found")
|
||||
set(KPMcore_FOUND TRUE)
|
||||
else()
|
||||
message(STATUS "KPMcore has been searched-for and not found")
|
||||
set(KPMcore_FOUND FALSE)
|
||||
endif()
|
||||
endif()
|
||||
|
@@ -86,6 +86,16 @@ KEY_ID="328D742D8807A435"
|
||||
rm -f CMakeLists.txt.gpg
|
||||
gpg -s -u $KEY_ID CMakeLists.txt
|
||||
|
||||
### Get version number for this release
|
||||
#
|
||||
# Do this early, in a clean build-dir, since it doesn't cost much.
|
||||
# Redirect stderr from CMake script mode, because the message()
|
||||
# in CMakeLists.txt that prints the version, goes to stderr.
|
||||
rm -rf "$BUILDDIR"
|
||||
mkdir "$BUILDDIR" || { echo "Could not create build directory." ; exit 1 ; }
|
||||
V=$( cd "$BUILDDIR" && cmake -P ../CMakeLists.txt 2>&1 )
|
||||
test -n "$V" || { echo "Could not obtain version in $BUILDDIR ." ; exit 1 ; }
|
||||
|
||||
### Build with default compiler
|
||||
#
|
||||
#
|
||||
@@ -124,12 +134,6 @@ else
|
||||
( cd "$BUILDDIR" && cmake .. ) || { echo "Could not run cmake in $BUILDDIR ." ; exit 1 ; }
|
||||
fi
|
||||
|
||||
### Get version number for this release
|
||||
#
|
||||
#
|
||||
V=$( cd "$BUILDDIR" && cmake -P ../CMakeLists.txt | grep ^CALAMARES_VERSION | sed s/^[A-Z_]*=// )
|
||||
test -n "$V" || { echo "Could not obtain version in $BUILDDIR ." ; exit 1 ; }
|
||||
|
||||
### Create signed tag
|
||||
#
|
||||
# This is the signing key ID associated with the GitHub account adriaandegroot,
|
||||
|
@@ -13,9 +13,10 @@
|
||||
# The base version can be a tag or git-hash; it will be checked-out
|
||||
# in a worktree.
|
||||
#
|
||||
# Note that the hash here now is the very start of 3.3, when ABI
|
||||
# compatibility was not expected yet at **all**.
|
||||
BASE_VERSION=419be4df25bc6fcc1958cb6e44afc1b9e64fce71
|
||||
# Note that the hash here now is 3.3-alpha1, when ABI
|
||||
# compatibility was not expected much. From 3.3-beta,
|
||||
# whenever that is, ABI compatibility should be more of a concern.
|
||||
BASE_VERSION=0c794183936b6d916a109784829e605cc4582e9f
|
||||
|
||||
### Build a tree and cache the ABI info into ci/
|
||||
#
|
||||
|
@@ -120,7 +120,7 @@ tx_sum()
|
||||
WORKTREE_NAME="$1"
|
||||
WORKTREE_TAG="$2"
|
||||
|
||||
git worktree add $WORKTREE_NAME $WORKTREE_TAG > /dev/null 2>&1 || { echo "! Could not create worktree." ; exit 1 ; }
|
||||
git worktree add -d $WORKTREE_NAME $WORKTREE_TAG > /dev/null 2>&1 || { echo "! Could not create worktree." ; exit 1 ; }
|
||||
( cd $WORKTREE_NAME && sh "$CURDIR"/ci/txpush.sh --no-tx ) > /dev/null 2>&1 || { echo "! Could not re-create translations." ; exit 1 ; }
|
||||
|
||||
# Remove linenumbers from .ts (XML) and .pot
|
||||
|
@@ -124,8 +124,8 @@ tx push --source --no-interactive -r calamares.fdo
|
||||
PYGETTEXT="xgettext --keyword=_n:1,2 -L python"
|
||||
|
||||
SHARED_PYTHON=""
|
||||
for MODULE_DIR in $(find src/modules -maxdepth 1 -mindepth 1 -type d) ; do
|
||||
FILES=$(find "$MODULE_DIR" -name "*.py" -a -type f)
|
||||
for MODULE_DIR in $(find src/modules -maxdepth 1 -mindepth 1 -type d | sort) ; do
|
||||
FILES=$(find "$MODULE_DIR" -name "*.py" -a -type f | sort)
|
||||
if test -n "$FILES" ; then
|
||||
MODULE_NAME=$(basename ${MODULE_DIR})
|
||||
if [ -d ${MODULE_DIR}/lang ]; then
|
||||
|
@@ -177,11 +177,9 @@ def get_tx_stats(languages, outputter, verbose):
|
||||
# Some languages go into the "incomplete" list by definition,
|
||||
# regardless of their completion status: this can have various reasons.
|
||||
#
|
||||
# Note that Esperanto (eo) is special-cased in CMakeLists.txt
|
||||
# during the build; recent Qt releases *do* support the language,
|
||||
# and it's at-the-least ok.
|
||||
# - (Esperanto wasn't supported until Qt 5.12.2)
|
||||
# - Interlingue still is not supported by the minimum Qt version
|
||||
incomplete_languages = (
|
||||
"eo", # Not supported by QLocale < 5.12.1
|
||||
"ie", # Not supported by Qt at least through 5.15.0
|
||||
)
|
||||
|
||||
|
@@ -60,8 +60,8 @@ modules-search: [ local ]
|
||||
# the instances section can safely be left empty.
|
||||
#
|
||||
# Module name plus instance name makes an instance key, e.g.
|
||||
# "webview@owncloud", where "webview" is the module name (for the webview
|
||||
# viewmodule) and "owncloud" is the instance name. In the *sequence*
|
||||
# "packagechooserq@licenseq", where "packagechooserq" is the module name (for the packagechooserq
|
||||
# viewmodule) and "licenseq" is the instance name. In the *sequence*
|
||||
# section below, use instance-keys to name instances (instead of just
|
||||
# a module name, for modules which have only a single instance).
|
||||
#
|
||||
@@ -86,9 +86,9 @@ modules-search: [ local ]
|
||||
#
|
||||
# YAML: list of maps of string:string key-value pairs.
|
||||
#instances:
|
||||
#- id: owncloud
|
||||
# module: webview
|
||||
# config: owncloud.conf
|
||||
#- id: licenseq
|
||||
# module: packagechooserq
|
||||
# config: licenseq.conf
|
||||
|
||||
# Sequence section. This section describes the sequence of modules, both
|
||||
# viewmodules and jobmodules, as they should appear and/or run.
|
||||
@@ -116,6 +116,7 @@ sequence:
|
||||
- show:
|
||||
- welcome
|
||||
# - notesqml
|
||||
# - packagechooserq@licenseq
|
||||
- locale
|
||||
- keyboard
|
||||
- partition
|
||||
@@ -152,7 +153,6 @@ sequence:
|
||||
- bootloader
|
||||
- umount
|
||||
- show:
|
||||
# - webview@owncloud
|
||||
- finished
|
||||
|
||||
# A branding component is a directory, either in SHARE/calamares/branding or
|
||||
|
@@ -18,6 +18,7 @@
|
||||
#include "JobQueue.h"
|
||||
#include "Settings.h"
|
||||
#include "ViewManager.h"
|
||||
#include "locale/TranslationsModel.h"
|
||||
#include "modulesystem/ModuleManager.h"
|
||||
#include "utils/CalamaresUtilsGui.h"
|
||||
#include "utils/CalamaresUtilsSystem.h"
|
||||
@@ -67,7 +68,7 @@ CalamaresApplication::init()
|
||||
{
|
||||
Logger::setupLogfile();
|
||||
cDebug() << "Calamares version:" << CALAMARES_VERSION;
|
||||
cDebug() << Logger::SubEntry << "languages:" << QString( CALAMARES_TRANSLATION_LANGUAGES ).replace( ";", ", " );
|
||||
cDebug() << Logger::SubEntry << "languages:" << Calamares::Locale::availableLanguages();
|
||||
|
||||
if ( !Calamares::Settings::instance() )
|
||||
{
|
||||
|
@@ -145,8 +145,8 @@ getWidgetSidebar( Calamares::DebugWindowManager* debug,
|
||||
CALAMARES_RETRANSLATE_FOR(
|
||||
aboutDialog,
|
||||
aboutDialog->setText(
|
||||
QCoreApplication::translate( CalamaresWindow::staticMetaObject.className(), "About" ) );
|
||||
aboutDialog->setToolTip( QCoreApplication::translate( CalamaresWindow::staticMetaObject.className(),
|
||||
QCoreApplication::translate( "calamares-sidebar", "About" ) );
|
||||
aboutDialog->setToolTip( QCoreApplication::translate( "calamares-sidebar",
|
||||
"Show information about Calamares" ) ); );
|
||||
extraButtons->addWidget( aboutDialog );
|
||||
aboutDialog->setFlat( true );
|
||||
@@ -161,9 +161,9 @@ getWidgetSidebar( Calamares::DebugWindowManager* debug,
|
||||
CalamaresUtils::Bugs, CalamaresUtils::Original, 2 * QSize( defaultFontHeight, defaultFontHeight ) ) );
|
||||
CALAMARES_RETRANSLATE_FOR( debugWindowBtn,
|
||||
debugWindowBtn->setText( QCoreApplication::translate(
|
||||
CalamaresWindow::staticMetaObject.className(), "Debug" ) );
|
||||
"calamares-sidebar", "Debug" ) );
|
||||
debugWindowBtn->setToolTip( QCoreApplication::translate(
|
||||
CalamaresWindow::staticMetaObject.className(), "Show debug information" ) ); );
|
||||
"calamares-sidebar", "Show debug information" ) ); );
|
||||
extraButtons->addWidget( debugWindowBtn );
|
||||
debugWindowBtn->setFlat( true );
|
||||
debugWindowBtn->setCheckable( true );
|
||||
|
@@ -107,6 +107,7 @@ handle_args( CalamaresApplication& a )
|
||||
int
|
||||
main( int argc, char* argv[] )
|
||||
{
|
||||
QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
|
||||
CalamaresApplication a( argc, argv );
|
||||
|
||||
KAboutData aboutData( "calamares",
|
||||
|
@@ -17,6 +17,24 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/CalamaresConfig.h.in ${CMAKE_CURRENT_
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/CalamaresVersion.h.in ${CMAKE_CURRENT_BINARY_DIR}/CalamaresVersion.h)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/CalamaresVersionX.h.in ${CMAKE_CURRENT_BINARY_DIR}/CalamaresVersionX.h)
|
||||
|
||||
# Map the available translations names into a suitable constexpr list
|
||||
# of names in C++. This gets us Calamares::Locale::availableLanguages,
|
||||
# a QStringList of names.
|
||||
set(_names_tu
|
||||
"
|
||||
#ifndef CALAMARES_TRANSLATIONS_H
|
||||
#define CALAMARES_TRANSLATIONS_H
|
||||
#include <QStringList>
|
||||
namespace {
|
||||
static const QStringList availableLanguageList{
|
||||
"
|
||||
)
|
||||
foreach(l ${CALAMARES_TRANSLATION_LANGUAGES})
|
||||
string(APPEND _names_tu "\"${l}\",\n")
|
||||
endforeach()
|
||||
string(APPEND _names_tu "};\n} // namespace\n#endif\n\n")
|
||||
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/CalamaresTranslations.cc "${_names_tu}")
|
||||
|
||||
add_library(
|
||||
calamares
|
||||
SHARED
|
||||
@@ -79,7 +97,7 @@ set_target_properties(
|
||||
calamares
|
||||
PROPERTIES
|
||||
VERSION ${CALAMARES_VERSION_SHORT}
|
||||
SOVERSION ${CALAMARES_VERSION_SHORT}
|
||||
SOVERSION ${CALAMARES_SOVERSION}
|
||||
INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_INSTALL_FULL_INCLUDEDIR}/libcalamares
|
||||
)
|
||||
target_link_libraries(calamares LINK_PUBLIC yamlcpp::yamlcpp Qt5::Core KF5::CoreAddons)
|
||||
@@ -115,13 +133,6 @@ endif()
|
||||
include(KPMcoreHelper)
|
||||
|
||||
if(KPMcore_FOUND)
|
||||
find_package(Qt5 REQUIRED DBus) # Needed for KPMCore
|
||||
find_package(KF5 REQUIRED I18n WidgetsAddons) # Needed for KPMCore
|
||||
|
||||
foreach(d ${KPMcore_API_DEFINITIONS})
|
||||
add_definitions(-D${d})
|
||||
endforeach()
|
||||
include_directories(${KPMCORE_INCLUDE_DIR})
|
||||
target_sources(
|
||||
calamares
|
||||
PRIVATE
|
||||
@@ -130,8 +141,11 @@ if(KPMcore_FOUND)
|
||||
partition/PartitionIterator.cpp
|
||||
partition/PartitionQuery.cpp
|
||||
)
|
||||
target_link_libraries(calamares PRIVATE kpmcore)
|
||||
endif()
|
||||
# Always, since this also handles the no-KPMcore case; we don't
|
||||
# call it calamares::kpmcore because that name exists only
|
||||
# when KPMcore is actually found.
|
||||
target_link_libraries(calamares PRIVATE calapmcore)
|
||||
|
||||
### LIBRARY
|
||||
#
|
||||
@@ -245,8 +259,12 @@ calamares_add_test(libcalamaresnetworktest SOURCES network/Tests.cpp)
|
||||
calamares_add_test(libcalamarespackagestest SOURCES packages/Tests.cpp)
|
||||
|
||||
if(KPMcore_FOUND)
|
||||
calamares_add_test(libcalamarespartitiontest SOURCES partition/Global.cpp partition/Tests.cpp LIBRARIES kpmcore)
|
||||
calamares_add_test(libcalamarespartitionkpmtest SOURCES partition/KPMTests.cpp LIBRARIES kpmcore)
|
||||
calamares_add_test(
|
||||
libcalamarespartitiontest
|
||||
SOURCES partition/Global.cpp partition/Tests.cpp
|
||||
LIBRARIES calamares::kpmcore
|
||||
)
|
||||
calamares_add_test(libcalamarespartitionkpmtest SOURCES partition/KPMTests.cpp LIBRARIES calamares::kpmcore)
|
||||
endif()
|
||||
|
||||
calamares_add_test(libcalamaresutilstest SOURCES utils/Tests.cpp utils/Runner.cpp)
|
||||
|
@@ -14,6 +14,4 @@
|
||||
#cmakedefine CALAMARES_VERSION_PATCH "${CALAMARES_VERSION_PATCH}"
|
||||
#cmakedefine CALAMARES_VERSION_RC "${CALAMARES_VERSION_RC}"
|
||||
|
||||
#cmakedefine CALAMARES_TRANSLATION_LANGUAGES "${CALAMARES_TRANSLATION_LANGUAGES}"
|
||||
|
||||
#endif // CALAMARES_VERSION_H
|
||||
|
@@ -12,7 +12,7 @@
|
||||
|
||||
#include "CountryData_p.cpp"
|
||||
|
||||
namespace CalamaresUtils
|
||||
namespace Calamares
|
||||
{
|
||||
namespace Locale
|
||||
{
|
||||
@@ -95,4 +95,4 @@ languageForCountry( QLocale::Country country )
|
||||
}
|
||||
|
||||
} // namespace Locale
|
||||
} // namespace CalamaresUtils
|
||||
} // namespace Calamares
|
||||
|
@@ -16,7 +16,7 @@
|
||||
#include <QLocale>
|
||||
#include <QPair>
|
||||
|
||||
namespace CalamaresUtils
|
||||
namespace Calamares
|
||||
{
|
||||
namespace Locale
|
||||
{
|
||||
@@ -42,6 +42,6 @@ DLLEXPORT QPair< QLocale::Country, QLocale::Language > countryData( const QStrin
|
||||
/// @brief Get a likely locale for a 2-letter country code
|
||||
DLLEXPORT QLocale countryLocale( const QString& code );
|
||||
} // namespace Locale
|
||||
} // namespace CalamaresUtils
|
||||
} // namespace Calamares
|
||||
|
||||
#endif
|
||||
|
@@ -71,7 +71,7 @@ LocaleTests::initTestCase()
|
||||
void
|
||||
LocaleTests::testLanguageModelCount()
|
||||
{
|
||||
const auto* m = CalamaresUtils::Locale::availableTranslations();
|
||||
const auto* m = Calamares::Locale::availableTranslations();
|
||||
|
||||
QVERIFY( m );
|
||||
QVERIFY( m->rowCount( QModelIndex() ) > 1 );
|
||||
@@ -90,7 +90,7 @@ LocaleTests::testLanguageModelCount()
|
||||
void
|
||||
LocaleTests::testLanguageScripts()
|
||||
{
|
||||
const auto* m = CalamaresUtils::Locale::availableTranslations();
|
||||
const auto* m = Calamares::Locale::availableTranslations();
|
||||
|
||||
QVERIFY( m );
|
||||
|
||||
@@ -153,12 +153,11 @@ someLanguages()
|
||||
void
|
||||
LocaleTests::testTranslatableLanguages()
|
||||
{
|
||||
QStringList availableLanguages = QString( CALAMARES_TRANSLATION_LANGUAGES ).split( ';' );
|
||||
cDebug() << "Translation languages:" << availableLanguages;
|
||||
cDebug() << "Translation languages:" << Calamares::Locale::availableLanguages();
|
||||
for ( const auto& language : someLanguages() )
|
||||
{
|
||||
// Could be QVERIFY, but then we don't see what language code fails
|
||||
QCOMPARE( availableLanguages.contains( language ) ? language : QString(), language );
|
||||
QCOMPARE( Calamares::Locale::availableLanguages().contains( language ) ? language : QString(), language );
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -128,7 +128,7 @@ specialCaseSystemLanguage()
|
||||
return ( it != std::cend( special_cases ) ) ? QString::fromLatin1( it->id ) : QString();
|
||||
}
|
||||
|
||||
namespace CalamaresUtils
|
||||
namespace Calamares
|
||||
{
|
||||
namespace Locale
|
||||
{
|
||||
@@ -187,4 +187,4 @@ Translation::getLocale( const Id& localeId )
|
||||
}
|
||||
|
||||
} // namespace Locale
|
||||
} // namespace CalamaresUtils
|
||||
} // namespace Calamares
|
||||
|
@@ -18,7 +18,7 @@
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
|
||||
namespace CalamaresUtils
|
||||
namespace Calamares
|
||||
{
|
||||
namespace Locale
|
||||
{
|
||||
@@ -124,6 +124,6 @@ operator==( const Translation::Id& lhs, const Translation::Id& rhs )
|
||||
}
|
||||
|
||||
} // namespace Locale
|
||||
} // namespace CalamaresUtils
|
||||
} // namespace Calamares
|
||||
|
||||
#endif
|
||||
|
@@ -13,9 +13,9 @@
|
||||
|
||||
#include "Lookup.h"
|
||||
|
||||
#include "CalamaresVersion.h" // For the list of translations
|
||||
#include "CalamaresTranslations.cc" // For the list of translations, generated at build time
|
||||
|
||||
namespace CalamaresUtils
|
||||
namespace Calamares
|
||||
{
|
||||
namespace Locale
|
||||
{
|
||||
@@ -139,10 +139,15 @@ TranslationsModel::find( const Translation::Id& id ) const
|
||||
TranslationsModel*
|
||||
availableTranslations()
|
||||
{
|
||||
static TranslationsModel* model
|
||||
= new TranslationsModel( QStringLiteral( CALAMARES_TRANSLATION_LANGUAGES ).split( ';' ) );
|
||||
static TranslationsModel* model = new TranslationsModel( availableLanguageList );
|
||||
return model;
|
||||
}
|
||||
|
||||
const QStringList&
|
||||
availableLanguages()
|
||||
{
|
||||
return availableLanguageList;
|
||||
}
|
||||
|
||||
} // namespace Locale
|
||||
} // namespace CalamaresUtils
|
||||
} // namespace Calamares
|
||||
|
@@ -19,7 +19,7 @@
|
||||
#include <QVector>
|
||||
|
||||
|
||||
namespace CalamaresUtils
|
||||
namespace Calamares
|
||||
{
|
||||
namespace Locale
|
||||
{
|
||||
@@ -74,14 +74,22 @@ private:
|
||||
/** @brief Returns a model with all available translations.
|
||||
*
|
||||
* The translations are set when Calamares is compiled; the list
|
||||
* is provided by CMake via the CALAMARES_TRANSLATION_LANGUAGES
|
||||
* #define.
|
||||
* of names used can be queried with avalableLanguages().
|
||||
*
|
||||
* This model is a singleton and can be shared.
|
||||
*
|
||||
* NOTE: While the model is not typed const, it should be. Do not modify.
|
||||
*/
|
||||
DLLEXPORT TranslationsModel* availableTranslations();
|
||||
|
||||
/** @brief The list of names (e.g. en, pt_BR) of available translations.
|
||||
*
|
||||
* The translations are set when Calamares is compiled.
|
||||
* At CMake-time, the list CALAMARES_TRANSLATION_LANGUAGES
|
||||
* is used to create the table.
|
||||
*/
|
||||
DLLEXPORT const QStringList& availableLanguages();
|
||||
|
||||
} // namespace Locale
|
||||
} // namespace CalamaresUtils
|
||||
} // namespace Calamares
|
||||
#endif
|
||||
|
@@ -19,6 +19,7 @@
|
||||
#define PARTITION_FILESYSTEM_H
|
||||
|
||||
#include "DllMacro.h"
|
||||
#include "partition/Global.h"
|
||||
|
||||
#include <kpmcore/fs/filesystem.h>
|
||||
|
||||
@@ -70,6 +71,28 @@ userVisibleFS( FileSystem* fs )
|
||||
return fs ? userVisibleFS( *fs ) : QString();
|
||||
}
|
||||
|
||||
/** @brief Mark a particular filesystem type as used (or not)
|
||||
*
|
||||
* See useFilesystemGS(const QString&, bool); this method uses the filesystem type
|
||||
* enumeration to pick the name. (The other implementation is in `Global.h`
|
||||
* because it touches Global Storage, but this one needs KPMcore)
|
||||
*/
|
||||
inline void
|
||||
useFilesystemGS( FileSystem::Type filesystem, bool used )
|
||||
{
|
||||
useFilesystemGS( untranslatedFS( filesystem ), used );
|
||||
}
|
||||
|
||||
/* @brief Reads from global storage whether the typesystem type is used
|
||||
*
|
||||
* See isFilesystemUsedGS(const QString&). (The other implementation is in `Global.h`
|
||||
* because it touches Global Storage, but this one needs KPMcore)
|
||||
*/
|
||||
inline bool
|
||||
isFilesystemUsedGS( FileSystem::Type filesystem )
|
||||
{
|
||||
return isFilesystemUsedGS( untranslatedFS( filesystem ) );
|
||||
}
|
||||
|
||||
} // namespace Partition
|
||||
} // namespace CalamaresUtils
|
||||
|
@@ -10,18 +10,15 @@
|
||||
|
||||
/*
|
||||
* This is the API for manipulating Global Storage keys related to
|
||||
* filesystems and partitions.
|
||||
* filesystems and partitions. This does **not** depend on KPMcore.
|
||||
*/
|
||||
|
||||
#ifndef PARTITION_GLOBAL_H
|
||||
#define PARTITION_GLOBAL_H
|
||||
|
||||
#include "DllMacro.h"
|
||||
#include "FileSystem.h"
|
||||
#include "JobQueue.h"
|
||||
|
||||
#include <kpmcore/fs/filesystem.h>
|
||||
|
||||
namespace CalamaresUtils
|
||||
{
|
||||
namespace Partition
|
||||
@@ -75,27 +72,6 @@ isFilesystemUsedGS( const QString& filesystemType )
|
||||
return isFilesystemUsedGS( Calamares::JobQueue::instanceGlobalStorage(), filesystemType );
|
||||
}
|
||||
|
||||
/** @brief Mark a particular filesystem type as used (or not)
|
||||
*
|
||||
* See useFilesystemGS(const QString&, bool); this method uses the filesystem type
|
||||
* enumeration to pick the name.
|
||||
*/
|
||||
inline void
|
||||
useFilesystemGS( FileSystem::Type filesystem, bool used )
|
||||
{
|
||||
useFilesystemGS( untranslatedFS( filesystem ), used );
|
||||
}
|
||||
|
||||
/* @brief Reads from global storage whether the typesystem type is used
|
||||
*
|
||||
* See isFilesystemUsedGS(const QString&).
|
||||
*/
|
||||
inline bool
|
||||
isFilesystemUsedGS( FileSystem::Type filesystem )
|
||||
{
|
||||
return isFilesystemUsedGS( untranslatedFS( filesystem ) );
|
||||
}
|
||||
|
||||
} // namespace Partition
|
||||
} // namespace CalamaresUtils
|
||||
|
||||
|
@@ -178,7 +178,7 @@ static QTranslator* s_tztranslator = nullptr;
|
||||
static QString s_translatorLocaleName;
|
||||
|
||||
void
|
||||
installTranslator( const CalamaresUtils::Locale::Translation::Id& locale, const QString& brandingTranslationsPrefix )
|
||||
installTranslator( const Calamares::Locale::Translation::Id& locale, const QString& brandingTranslationsPrefix )
|
||||
{
|
||||
s_translatorLocaleName = locale.name;
|
||||
|
||||
@@ -190,17 +190,17 @@ installTranslator( const CalamaresUtils::Locale::Translation::Id& locale, const
|
||||
void
|
||||
installTranslator()
|
||||
{
|
||||
installTranslator( CalamaresUtils::Locale::Translation().id(), QString() );
|
||||
installTranslator( Calamares::Locale::Translation().id(), QString() );
|
||||
}
|
||||
|
||||
CalamaresUtils::Locale::Translation::Id
|
||||
Calamares::Locale::Translation::Id
|
||||
translatorLocaleName()
|
||||
{
|
||||
return { s_translatorLocaleName };
|
||||
}
|
||||
|
||||
bool
|
||||
loadTranslator( const CalamaresUtils::Locale::Translation::Id& locale, const QString& prefix, QTranslator* translator )
|
||||
loadTranslator( const Calamares::Locale::Translation::Id& locale, const QString& prefix, QTranslator* translator )
|
||||
{
|
||||
return ::tryLoad( translator, prefix, locale.name );
|
||||
}
|
||||
|
@@ -29,7 +29,7 @@ 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,
|
||||
DLLEXPORT void installTranslator( const Calamares::Locale::Translation::Id& locale,
|
||||
const QString& brandingTranslationsPrefix );
|
||||
|
||||
/** @brief Initializes the translations with the current system settings
|
||||
@@ -42,7 +42,7 @@ DLLEXPORT void installTranslator();
|
||||
* QLocale passed in, because Calamares will munge some names and
|
||||
* may remap translations.
|
||||
*/
|
||||
DLLEXPORT CalamaresUtils::Locale::Translation::Id translatorLocaleName();
|
||||
DLLEXPORT Calamares::Locale::Translation::Id translatorLocaleName();
|
||||
|
||||
/** @brief Loads <prefix><locale> translations into the given @p translator
|
||||
*
|
||||
@@ -58,7 +58,7 @@ 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 );
|
||||
loadTranslator( const Calamares::Locale::Translation::Id& locale, const QString& prefix, QTranslator* translator );
|
||||
|
||||
/** @brief Set @p allow to true to load translations from current dir.
|
||||
*
|
||||
|
@@ -48,6 +48,14 @@ public:
|
||||
virtual ~DictionaryExpander() override;
|
||||
|
||||
void insert( const QString& key, const QString& value );
|
||||
/** @brief As insert(), but supports method-chaining.
|
||||
*
|
||||
*/
|
||||
DictionaryExpander& add( const QString& key, const QString& value )
|
||||
{
|
||||
insert( key, value );
|
||||
return *this;
|
||||
}
|
||||
|
||||
void clearErrors();
|
||||
bool hasErrors() const;
|
||||
|
@@ -53,6 +53,7 @@ calamares_add_library(calamaresui
|
||||
UI
|
||||
utils/ErrorDialog/ErrorDialog.ui
|
||||
VERSION ${CALAMARES_VERSION_SHORT}
|
||||
SOVERSION ${CALAMARES_SOVERSION}
|
||||
)
|
||||
target_link_libraries(calamaresui PRIVATE yamlcpp::yamlcpp)
|
||||
if(KF5CoreAddons_FOUND AND KF5CoreAddons_VERSION VERSION_GREATER_EQUAL 5.58)
|
||||
|
@@ -53,10 +53,10 @@ efiBootMgr: "efibootmgr"
|
||||
# (problematic characters, see above, are replaced).
|
||||
#
|
||||
# There are some special words possible at the end of *efiBootloaderId*:
|
||||
# @@SERIAL@@ can be used to obtain a uniquely-numbered suffix
|
||||
# ${SERIAL} can be used to obtain a uniquely-numbered suffix
|
||||
# that is added to the Id (yielding, e.g., `dirname1` or `dirname72`)
|
||||
# @@RANDOM@@ can be used to obtain a unique 4-digit hex suffix
|
||||
# @@PHRASE@@ can be used to obtain a unique 1-to-3-word suffix
|
||||
# ${RANDOM} can be used to obtain a unique 4-digit hex suffix
|
||||
# ${PHRASE} can be used to obtain a unique 1-to-3-word suffix
|
||||
# from a dictionary of space-themed words
|
||||
# These words must be at the **end** of the *efiBootloaderId* value.
|
||||
# There must also be at most one of them. If there is none, no suffix-
|
||||
|
@@ -393,28 +393,28 @@ class phraseEfi(object):
|
||||
|
||||
def get_efi_suffix_generator(name):
|
||||
"""
|
||||
Handle EFI bootloader Ids with @@<something>@@ for suffix-processing.
|
||||
Handle EFI bootloader Ids with ${<something>} for suffix-processing.
|
||||
"""
|
||||
if "@@" not in name:
|
||||
raise ValueError("Misplaced call to get_efi_suffix_generator, no @@")
|
||||
parts = name.split("@@")
|
||||
if len(parts) != 3:
|
||||
raise ValueError("EFI Id {!r} is malformed".format(name))
|
||||
if parts[2]:
|
||||
# Supposed to be empty because the string ends with "@@"
|
||||
raise ValueError("EFI Id {!r} is malformed".format(name))
|
||||
if parts[1] not in ("SERIAL", "RANDOM", "PHRASE"):
|
||||
raise ValueError("EFI suffix {!r} is unknown".format(parts[1]))
|
||||
if "${" not in name:
|
||||
raise ValueError("Misplaced call to get_efi_suffix_generator, no ${}")
|
||||
if not name.endswith("}"):
|
||||
raise ValueError("Misplaced call to get_efi_suffix_generator, no trailing ${}")
|
||||
if name.count("${") > 1:
|
||||
raise ValueError("EFI ID {!r} contains multiple generators".format(name))
|
||||
import re
|
||||
prefix, generator_name = re.match("(.*)\${([^}]*)}$", name).groups()
|
||||
if generator_name not in ("SERIAL", "RANDOM", "PHRASE"):
|
||||
raise ValueError("EFI suffix {!r} is unknown".format(generator_name))
|
||||
|
||||
generator = None
|
||||
if parts[1] == "SERIAL":
|
||||
generator = serialEfi(parts[0])
|
||||
elif parts[1] == "RANDOM":
|
||||
generator = randomEfi(parts[0])
|
||||
elif parts[1] == "PHRASE":
|
||||
generator = phraseEfi(parts[0])
|
||||
if generator_name == "SERIAL":
|
||||
generator = serialEfi(prefix)
|
||||
elif generator_name == "RANDOM":
|
||||
generator = randomEfi(prefix)
|
||||
elif generator_name == "PHRASE":
|
||||
generator = phraseEfi(prefix)
|
||||
if generator is None:
|
||||
raise ValueError("EFI suffix {!r} is unsupported".format(parts[1]))
|
||||
raise ValueError("EFI suffix {!r} is unsupported".format(generator_name))
|
||||
|
||||
return generator
|
||||
|
||||
@@ -422,10 +422,10 @@ def get_efi_suffix_generator(name):
|
||||
def change_efi_suffix(efi_directory, bootloader_id):
|
||||
"""
|
||||
Returns a label based on @p bootloader_id that is usable within
|
||||
@p efi_directory. If there is a @@<something>@@ suffix marker
|
||||
@p efi_directory. If there is a ${<something>} suffix marker
|
||||
in the given id, tries to generate a unique label.
|
||||
"""
|
||||
if bootloader_id.endswith("@@"):
|
||||
if bootloader_id.endswith("}") and "${" in bootloader_id:
|
||||
# Do 10 attempts with any suffix generator
|
||||
g = suffix_iterator(10, get_efi_suffix_generator(bootloader_id))
|
||||
else:
|
||||
@@ -471,7 +471,7 @@ def efi_boot_next():
|
||||
"""
|
||||
boot_mgr = libcalamares.job.configuration["efiBootMgr"]
|
||||
boot_entry = None
|
||||
efi_bootvars = subprocess.check_output([boot_mgr], text=True)
|
||||
efi_bootvars = subprocess.check_output([boot_mgr], universal_newlines=True)
|
||||
for line in efi_bootvars.split('\n'):
|
||||
if not line:
|
||||
continue
|
||||
|
@@ -10,7 +10,7 @@ libcalamares.globalstorage.insert("testing", True)
|
||||
from src.modules.bootloader import main
|
||||
|
||||
# Specific Bootloader test
|
||||
g = main.get_efi_suffix_generator("derp@@SERIAL@@")
|
||||
g = main.get_efi_suffix_generator("derp${SERIAL}")
|
||||
assert g is not None
|
||||
assert g.next() == "derp" # First time, no suffix
|
||||
for n in range(9):
|
||||
@@ -18,13 +18,13 @@ for n in range(9):
|
||||
# We called next() 10 times in total, starting from 0
|
||||
assert g.next() == "derp10"
|
||||
|
||||
g = main.get_efi_suffix_generator("derp@@RANDOM@@")
|
||||
g = main.get_efi_suffix_generator("derp${RANDOM}")
|
||||
assert g is not None
|
||||
for n in range(10):
|
||||
print(g.next())
|
||||
# it's random, nothing to assert
|
||||
|
||||
g = main.get_efi_suffix_generator("derp@@PHRASE@@")
|
||||
g = main.get_efi_suffix_generator("derp${PHRASE}")
|
||||
assert g is not None
|
||||
for n in range(10):
|
||||
print(g.next())
|
||||
@@ -38,19 +38,19 @@ except ValueError as e:
|
||||
pass
|
||||
|
||||
try:
|
||||
g = main.get_efi_suffix_generator("derp@@HEX@@")
|
||||
g = main.get_efi_suffix_generator("derp${HEX}")
|
||||
raise TypeError("Shouldn't get generator (unknown indicator)")
|
||||
except ValueError as e:
|
||||
pass
|
||||
|
||||
try:
|
||||
g = main.get_efi_suffix_generator("derp@@SERIAL@@x")
|
||||
g = main.get_efi_suffix_generator("derp${SERIAL}x")
|
||||
raise TypeError("Shouldn't get generator (trailing garbage)")
|
||||
except ValueError as e:
|
||||
pass
|
||||
|
||||
try:
|
||||
g = main.get_efi_suffix_generator("derp@@SERIAL@@@@RANDOM@@")
|
||||
g = main.get_efi_suffix_generator("derp${SERIAL}${RANDOM}")
|
||||
raise TypeError("Shouldn't get generator (multiple indicators)")
|
||||
except ValueError as e:
|
||||
pass
|
||||
@@ -59,9 +59,9 @@ except ValueError as e:
|
||||
# Try the generator (assuming no calamares- test files exist in /tmp)
|
||||
import os
|
||||
assert "calamares-single" == main.change_efi_suffix("/tmp", "calamares-single")
|
||||
assert "calamares-serial" == main.change_efi_suffix("/tmp", "calamares-serial@@SERIAL@@")
|
||||
assert "calamares-serial" == main.change_efi_suffix("/tmp", "calamares-serial${SERIAL}")
|
||||
try:
|
||||
os.makedirs("/tmp/calamares-serial", exist_ok=True)
|
||||
assert "calamares-serial1" == main.change_efi_suffix("/tmp", "calamares-serial@@SERIAL@@")
|
||||
assert "calamares-serial1" == main.change_efi_suffix("/tmp", "calamares-serial${SERIAL}")
|
||||
finally:
|
||||
os.rmdir("/tmp/calamares-serial")
|
||||
|
@@ -17,6 +17,14 @@ try:
|
||||
except FileNotFoundError as e:
|
||||
pass
|
||||
|
||||
try:
|
||||
import toml
|
||||
except ImportError:
|
||||
# This is a failure of the test-environment.
|
||||
import sys
|
||||
print("Can't find module toml.", file=sys.stderr)
|
||||
sys.exit(0)
|
||||
|
||||
# Specific DM test
|
||||
d = main.DMgreetd("/tmp")
|
||||
d.set_autologin("d", True, default_desktop_environment)
|
||||
|
@@ -9,7 +9,7 @@ find_package(KF5WidgetsAddons CONFIG)
|
||||
|
||||
include(KPMcoreHelper)
|
||||
|
||||
if(KPMcore_FOUND AND Qt5DBus_FOUND AND KF5CoreAddons_FOUND AND KF5Config_FOUND)
|
||||
if(KPMcore_FOUND)
|
||||
include_directories(${KPMCORE_INCLUDE_DIR} ${CMAKE_SOURCE_DIR}/src/modules/partition)
|
||||
|
||||
# The PartitionIterator is a small class, and it's easiest -- but also a
|
||||
@@ -20,7 +20,7 @@ if(KPMcore_FOUND AND Qt5DBus_FOUND AND KF5CoreAddons_FOUND AND KF5Config_FOUND)
|
||||
SOURCES
|
||||
ResizeFSJob.cpp
|
||||
LINK_PRIVATE_LIBRARIES
|
||||
kpmcore
|
||||
calamares::kpmcore
|
||||
COMPILE_DEFINITIONS ${KPMcore_API_DEFINITIONS}
|
||||
SHARED_LIB
|
||||
)
|
||||
|
@@ -281,7 +281,10 @@ def run():
|
||||
partitions = libcalamares.globalstorage.value("partitions")
|
||||
root_mount_point = libcalamares.globalstorage.value("rootMountPoint")
|
||||
branding = libcalamares.globalstorage.value("branding")
|
||||
distributor = branding["bootloaderEntryName"]
|
||||
if branding is None:
|
||||
distributor = None
|
||||
else:
|
||||
distributor = branding["bootloaderEntryName"]
|
||||
|
||||
if libcalamares.globalstorage.value("bootLoader") is None and fw_type != "efi":
|
||||
return None
|
||||
|
@@ -1,4 +1,5 @@
|
||||
# SPDX-FileCopyrightText: no
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
---
|
||||
bogus: true
|
||||
branding:
|
||||
bootloaderEntryName: generic
|
||||
|
@@ -1,7 +1,6 @@
|
||||
# SPDX-FileCopyrightText: no
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
---
|
||||
bogus: true
|
||||
firmwareType: bios
|
||||
bootLoader: grub
|
||||
rootMountPoint: /tmp/calamares/grubcfg-test-2
|
||||
|
@@ -1,7 +1,6 @@
|
||||
# SPDX-FileCopyrightText: no
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
---
|
||||
bogus: true
|
||||
firmwareType: bios
|
||||
bootLoader: grub
|
||||
rootMountPoint: /tmp/calamares/grubcfg-test-3
|
||||
|
@@ -1,7 +1,6 @@
|
||||
# SPDX-FileCopyrightText: no
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
---
|
||||
bogus: true
|
||||
firmwareType: bios
|
||||
bootLoader: grub
|
||||
rootMountPoint: /tmp/calamares/grubcfg-test-4
|
||||
|
@@ -22,6 +22,7 @@ calamares_add_plugin(locale
|
||||
Config.cpp
|
||||
LCLocaleDialog.cpp
|
||||
LocaleConfiguration.cpp
|
||||
LocaleNames.cpp
|
||||
LocalePage.cpp
|
||||
LocaleViewStep.cpp
|
||||
SetTimezoneJob.cpp
|
||||
@@ -39,7 +40,13 @@ calamares_add_plugin(locale
|
||||
|
||||
calamares_add_test(
|
||||
localetest
|
||||
SOURCES Tests.cpp Config.cpp LocaleConfiguration.cpp SetTimezoneJob.cpp timezonewidget/TimeZoneImage.cpp
|
||||
SOURCES
|
||||
Tests.cpp
|
||||
Config.cpp
|
||||
LocaleConfiguration.cpp
|
||||
LocaleNames.cpp
|
||||
SetTimezoneJob.cpp
|
||||
timezonewidget/TimeZoneImage.cpp
|
||||
DEFINITIONS SOURCE_DIR="${CMAKE_CURRENT_LIST_DIR}/images" DEBUG_TIMEZONES=1
|
||||
LIBRARIES Qt5::Gui
|
||||
)
|
||||
|
@@ -399,7 +399,7 @@ Config::currentTimezoneName() const
|
||||
static inline QString
|
||||
localeLabel( const QString& s )
|
||||
{
|
||||
using CalamaresUtils::Locale::Translation;
|
||||
using Calamares::Locale::Translation;
|
||||
|
||||
Translation lang( { s }, Translation::LabelFormat::AlwaysWithCountry );
|
||||
return lang.label();
|
||||
|
@@ -9,11 +9,13 @@
|
||||
*/
|
||||
|
||||
#include "LocaleConfiguration.h"
|
||||
#include "LocaleNames.h"
|
||||
|
||||
#include "utils/Logger.h"
|
||||
|
||||
#include <QLocale>
|
||||
#include <QRegularExpression>
|
||||
#include <QVector>
|
||||
|
||||
LocaleConfiguration::LocaleConfiguration()
|
||||
: explicit_lang( false )
|
||||
@@ -40,6 +42,106 @@ LocaleConfiguration::setLanguage( const QString& localeName )
|
||||
m_lang = localeName;
|
||||
}
|
||||
|
||||
static LocaleNameParts
|
||||
updateCountry( LocaleNameParts p, const QString& country )
|
||||
{
|
||||
p.country = country;
|
||||
return p;
|
||||
}
|
||||
|
||||
static QPair< int, LocaleNameParts >
|
||||
identifyBestLanguageMatch( const LocaleNameParts& referenceLocale, QVector< LocaleNameParts >& others )
|
||||
{
|
||||
std::sort( others.begin(),
|
||||
others.end(),
|
||||
[ & ]( const LocaleNameParts& lhs, const LocaleNameParts& rhs )
|
||||
{ return referenceLocale.similarity( lhs ) < referenceLocale.similarity( rhs ); } );
|
||||
// The best match is at the end
|
||||
LocaleNameParts best_match = others.last();
|
||||
if ( !( referenceLocale.similarity( best_match ) > LocaleNameParts::no_match ) )
|
||||
{
|
||||
cDebug() << Logger::SubEntry << "Got no good match for" << referenceLocale.name();
|
||||
return { LocaleNameParts::no_match, LocaleNameParts {} };
|
||||
}
|
||||
else
|
||||
{
|
||||
cDebug() << Logger::SubEntry << "Got best match for" << referenceLocale.name() << "as" << best_match.name();
|
||||
return { referenceLocale.similarity( best_match ), best_match };
|
||||
}
|
||||
}
|
||||
|
||||
/** @brief Returns the QString from @p availableLocales that best-matches.
|
||||
*/
|
||||
static LocaleNameParts
|
||||
identifyBestLanguageMatch( const QString& languageLocale,
|
||||
const QStringList& availableLocales,
|
||||
const QString& countryCode )
|
||||
{
|
||||
const QString default_lang = QStringLiteral( "en_US.UTF-8" );
|
||||
|
||||
const LocaleNameParts self = LocaleNameParts::fromName( languageLocale );
|
||||
if ( self.isValid() && !availableLocales.isEmpty() )
|
||||
{
|
||||
QVector< LocaleNameParts > others;
|
||||
others.resize( availableLocales.length() ); // Makes default structs
|
||||
std::transform( availableLocales.begin(), availableLocales.end(), others.begin(), LocaleNameParts::fromName );
|
||||
|
||||
// Keep track of the best match in various attempts
|
||||
int best_score = LocaleNameParts::no_match;
|
||||
LocaleNameParts best_match;
|
||||
|
||||
// Check with the unmodified language setting
|
||||
{
|
||||
auto [ score, match ] = identifyBestLanguageMatch( self, others );
|
||||
if ( score >= LocaleNameParts::complete_match )
|
||||
{
|
||||
return match;
|
||||
}
|
||||
else if ( score > best_score )
|
||||
{
|
||||
best_match = match;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// .. but it might match **better** with the chosen location country Code
|
||||
{
|
||||
auto [ score, match ] = identifyBestLanguageMatch( updateCountry( self, countryCode ), others );
|
||||
if ( score >= LocaleNameParts::complete_match )
|
||||
{
|
||||
return match;
|
||||
}
|
||||
else if ( score > best_score )
|
||||
{
|
||||
best_match = match;
|
||||
}
|
||||
}
|
||||
|
||||
// .. or better yet with the QLocale-derived country
|
||||
{
|
||||
const QString localeCountry = LocaleNameParts::fromName( QLocale( languageLocale ).name() ).country;
|
||||
auto [ score, match ] = identifyBestLanguageMatch( updateCountry( self, localeCountry ), others );
|
||||
if ( score >= LocaleNameParts::complete_match )
|
||||
{
|
||||
return match;
|
||||
}
|
||||
else if ( score > best_score )
|
||||
{
|
||||
best_match = match;
|
||||
}
|
||||
}
|
||||
|
||||
if ( best_match.isValid() )
|
||||
{
|
||||
cDebug() << Logger::SubEntry << "Matched best with" << best_match.name();
|
||||
return best_match;
|
||||
}
|
||||
}
|
||||
|
||||
// Else we have an unrecognized or unsupported locale, all we can do is go with
|
||||
// en_US.UTF-8 UTF-8. This completes all default language setting guesswork.
|
||||
return LocaleNameParts::fromName( default_lang );
|
||||
}
|
||||
|
||||
LocaleConfiguration
|
||||
LocaleConfiguration::fromLanguageAndLocation( const QString& languageLocale,
|
||||
@@ -47,100 +149,7 @@ LocaleConfiguration::fromLanguageAndLocation( const QString& languageLocale,
|
||||
const QString& countryCode )
|
||||
{
|
||||
cDebug() << "Mapping" << languageLocale << "in" << countryCode << "to locale.";
|
||||
QString language = languageLocale.split( '_' ).first();
|
||||
QString region;
|
||||
if ( language.contains( '@' ) )
|
||||
{
|
||||
auto r = language.split( '@' );
|
||||
language = r.first();
|
||||
region = r[ 1 ]; // second()
|
||||
}
|
||||
|
||||
// Either an exact match, or the whole language part matches
|
||||
// (followed by .<encoding> or _<country>
|
||||
QStringList linesForLanguage = availableLocales.filter( QRegularExpression( language + "[._]" ) );
|
||||
cDebug() << Logger::SubEntry << "Matching" << linesForLanguage;
|
||||
|
||||
QString lang;
|
||||
if ( linesForLanguage.isEmpty() || languageLocale.isEmpty() )
|
||||
{
|
||||
lang = "en_US.UTF-8";
|
||||
}
|
||||
else if ( linesForLanguage.length() == 1 )
|
||||
{
|
||||
lang = linesForLanguage.first();
|
||||
}
|
||||
|
||||
// lang could still be empty if we found multiple locales that satisfy myLanguage
|
||||
const QString combinedLanguageAndCountry = QString( "%1_%2" ).arg( language ).arg( countryCode );
|
||||
if ( lang.isEmpty() && region.isEmpty() )
|
||||
{
|
||||
auto l = linesForLanguage.filter(
|
||||
QRegularExpression( combinedLanguageAndCountry + "[._]" ) ); // no regional variants
|
||||
if ( l.length() == 1 )
|
||||
{
|
||||
lang = l.first();
|
||||
}
|
||||
}
|
||||
|
||||
// The following block was inspired by Ubiquity, scripts/localechooser-apply.
|
||||
// No copyright statement found in file, assuming GPL v2 or later.
|
||||
/* # In the special cases of Portuguese and Chinese, selecting a
|
||||
# different location may imply a different dialect of the language.
|
||||
# In such cases, make LANG reflect the selected language (for
|
||||
# messages, character types, and collation) and make the other
|
||||
# locale categories reflect the selected location. */
|
||||
if ( language == "pt" || language == "zh" )
|
||||
{
|
||||
cDebug() << Logger::SubEntry << "Special-case Portuguese and Chinese";
|
||||
QString proposedLocale = QString( "%1_%2" ).arg( language ).arg( countryCode );
|
||||
for ( const QString& line : linesForLanguage )
|
||||
{
|
||||
if ( line.contains( proposedLocale ) )
|
||||
{
|
||||
cDebug() << Logger::SubEntry << "Country-variant" << line << "chosen.";
|
||||
lang = line;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( lang.isEmpty() && !region.isEmpty() )
|
||||
{
|
||||
cDebug() << Logger::SubEntry << "Special-case region @" << region;
|
||||
QString proposedRegion = QString( "@%1" ).arg( region );
|
||||
for ( const QString& line : linesForLanguage )
|
||||
{
|
||||
if ( line.startsWith( language ) && line.contains( proposedRegion ) )
|
||||
{
|
||||
cDebug() << Logger::SubEntry << "Region-variant" << line << "chosen.";
|
||||
lang = line;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// If we found no good way to set a default lang, do a search with the whole
|
||||
// language locale and pick the first result, if any.
|
||||
if ( lang.isEmpty() )
|
||||
{
|
||||
for ( const QString& line : availableLocales )
|
||||
{
|
||||
if ( line.startsWith( languageLocale ) )
|
||||
{
|
||||
lang = line;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Else we have an unrecognized or unsupported locale, all we can do is go with
|
||||
// en_US.UTF-8 UTF-8. This completes all default language setting guesswork.
|
||||
if ( lang.isEmpty() )
|
||||
{
|
||||
lang = "en_US.UTF-8";
|
||||
}
|
||||
|
||||
const auto bestLocale = identifyBestLanguageMatch( languageLocale, availableLocales, countryCode );
|
||||
|
||||
// The following block was inspired by Ubiquity, scripts/localechooser-apply.
|
||||
// No copyright statement found in file, assuming GPL v2 or later.
|
||||
@@ -188,34 +197,16 @@ LocaleConfiguration::fromLanguageAndLocation( const QString& languageLocale,
|
||||
// We make a proposed locale based on the UI language and the timezone's country. There is no
|
||||
// guarantee that this will be a valid, supported locale (often it won't).
|
||||
QString lc_formats;
|
||||
const QString combined = QString( "%1_%2" ).arg( language ).arg( countryCode );
|
||||
if ( lang.isEmpty() )
|
||||
const QString combined = QString( "%1_%2" ).arg( bestLocale.language ).arg( countryCode );
|
||||
if ( availableLocales.contains( bestLocale.language ) )
|
||||
{
|
||||
cDebug() << Logger::SubEntry << "Looking up formats for" << combinedLanguageAndCountry;
|
||||
// We look up if it's a supported locale.
|
||||
for ( const QString& line : availableLocales )
|
||||
{
|
||||
if ( line.startsWith( combinedLanguageAndCountry ) )
|
||||
{
|
||||
lang = line;
|
||||
lc_formats = line;
|
||||
break;
|
||||
}
|
||||
}
|
||||
cDebug() << Logger::SubEntry << "Exact formats match for language tag" << bestLocale.language;
|
||||
lc_formats = bestLocale.language;
|
||||
}
|
||||
else
|
||||
else if ( availableLocales.contains( combined ) )
|
||||
{
|
||||
if ( availableLocales.contains( lang ) )
|
||||
{
|
||||
cDebug() << Logger::SubEntry << "Exact formats match for language tag" << lang;
|
||||
lc_formats = lang;
|
||||
}
|
||||
else if ( availableLocales.contains( combinedLanguageAndCountry ) )
|
||||
{
|
||||
cDebug() << Logger::SubEntry << "Exact formats match for combined" << combinedLanguageAndCountry;
|
||||
lang = combinedLanguageAndCountry;
|
||||
lc_formats = combinedLanguageAndCountry;
|
||||
}
|
||||
cDebug() << Logger::SubEntry << "Exact formats match for combined" << combined;
|
||||
lc_formats = combined;
|
||||
}
|
||||
|
||||
if ( lc_formats.isEmpty() )
|
||||
@@ -303,12 +294,7 @@ LocaleConfiguration::fromLanguageAndLocation( const QString& languageLocale,
|
||||
|
||||
// If we cannot make a good choice for a given country we go with the LANG
|
||||
// setting, which defaults to en_US.UTF-8 UTF-8 if all else fails.
|
||||
if ( lc_formats.isEmpty() )
|
||||
{
|
||||
lc_formats = lang;
|
||||
}
|
||||
|
||||
return LocaleConfiguration( lang, lc_formats );
|
||||
return LocaleConfiguration( bestLocale.name(), lc_formats.isEmpty() ? bestLocale.name() : lc_formats );
|
||||
}
|
||||
|
||||
|
||||
|
90
src/modules/locale/LocaleNames.cpp
Normal file
90
src/modules/locale/LocaleNames.cpp
Normal file
@@ -0,0 +1,90 @@
|
||||
/* === This file is part of Calamares - <https://calamares.io> ===
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2022 Adriaan de Groot <groot@kde.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* Calamares is Free Software: see the License-Identifier above.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "LocaleNames.h"
|
||||
|
||||
#include "utils/Logger.h"
|
||||
|
||||
#include <QRegularExpression>
|
||||
|
||||
LocaleNameParts
|
||||
LocaleNameParts::fromName( const QString& name )
|
||||
{
|
||||
auto requireAndRemoveLeadingChar = []( QChar c, QString s )
|
||||
{
|
||||
if ( s.startsWith( c ) )
|
||||
{
|
||||
return s.remove( 0, 1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
return QString();
|
||||
}
|
||||
};
|
||||
|
||||
auto parts = QRegularExpression( "^([a-zA-Z]+)(_[a-zA-Z]+)?(\\.[-a-zA-Z0-9]+)?(@[a-zA-Z]+)?" ).match( name );
|
||||
const QString calamaresLanguage = parts.captured( 1 );
|
||||
const QString calamaresCountry = requireAndRemoveLeadingChar( '_', parts.captured( 2 ) );
|
||||
const QString calamaresEncoding = requireAndRemoveLeadingChar( '.', parts.captured( 3 ) );
|
||||
const QString calamaresRegion = requireAndRemoveLeadingChar( '@', parts.captured( 4 ) );
|
||||
|
||||
if ( calamaresLanguage.isEmpty() )
|
||||
{
|
||||
return LocaleNameParts {};
|
||||
}
|
||||
else
|
||||
{
|
||||
return LocaleNameParts { calamaresLanguage, calamaresCountry, calamaresRegion, calamaresEncoding };
|
||||
}
|
||||
}
|
||||
|
||||
QString
|
||||
LocaleNameParts::name() const
|
||||
{
|
||||
// We don't want QStringView to a temporary; force conversion
|
||||
auto insertLeadingChar = []( QChar c, QString s ) -> QString
|
||||
{
|
||||
if ( s.isEmpty() )
|
||||
{
|
||||
return QString();
|
||||
}
|
||||
else
|
||||
{
|
||||
return c + s;
|
||||
}
|
||||
};
|
||||
|
||||
if ( !isValid() )
|
||||
{
|
||||
return QString();
|
||||
}
|
||||
else
|
||||
{
|
||||
return language + insertLeadingChar( '_', country ) + insertLeadingChar( '.', encoding )
|
||||
+ insertLeadingChar( '@', region );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
LocaleNameParts::similarity( const LocaleNameParts& other ) const
|
||||
{
|
||||
if ( !isValid() || !other.isValid() )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if ( language != other.language )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
const auto matched_region = ( region == other.region ? 30 : 0 );
|
||||
const auto matched_country = ( country == other.country ? ( country.isEmpty() ? 10 : 20 ) : 0 );
|
||||
const auto no_other_country_given = ( ( country != other.country && other.country.isEmpty() ) ? 10 : 0 );
|
||||
return 50 + matched_region + matched_country + no_other_country_given;
|
||||
}
|
46
src/modules/locale/LocaleNames.h
Normal file
46
src/modules/locale/LocaleNames.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/* === This file is part of Calamares - <https://calamares.io> ===
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2022 Adriaan de Groot <groot@kde.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* Calamares is Free Software: see the License-Identifier above.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LOCALENAMES_H
|
||||
#define LOCALENAMES_H
|
||||
|
||||
#include <QString>
|
||||
|
||||
/** @brief parts of a locale-name (e.g. "ar_LY.UTF-8", split apart)
|
||||
*
|
||||
* These are created from lines in `/usr/share/i18n/SUPPORTED`,
|
||||
* which lists all the locales supported by the system (there
|
||||
* are also other sources of the same).
|
||||
*
|
||||
*/
|
||||
struct LocaleNameParts
|
||||
{
|
||||
QString language; // e.g. "ar"
|
||||
QString country; // e.g. "LY" (may be empty)
|
||||
QString region; // e.g. "@valencia" (may be empty)
|
||||
QString encoding; // e.g. "UTF-8" (may be empty)
|
||||
|
||||
bool isValid() const { return !language.isEmpty(); }
|
||||
QString name() const;
|
||||
|
||||
static LocaleNameParts fromName( const QString& name );
|
||||
|
||||
static inline constexpr const int no_match = 0;
|
||||
static inline constexpr const int complete_match = 100;
|
||||
|
||||
/** @brief Compute similarity-score with another locale-name.
|
||||
*
|
||||
* Similarity is driven by language and region, then country.
|
||||
* Returns a number between 0 (no similarity, e.g. the
|
||||
* language is different) and 100 (complete match).
|
||||
*/
|
||||
int similarity( const LocaleNameParts& other ) const;
|
||||
};
|
||||
|
||||
#endif
|
@@ -9,9 +9,12 @@
|
||||
|
||||
#include "Config.h"
|
||||
#include "LocaleConfiguration.h"
|
||||
#include "LocaleNames.h"
|
||||
#include "timezonewidget/TimeZoneImage.h"
|
||||
|
||||
#include "Settings.h"
|
||||
#include "locale/TimeZone.h"
|
||||
#include "locale/TranslationsModel.h"
|
||||
#include "utils/Logger.h"
|
||||
|
||||
#include <QtTest/QtTest>
|
||||
@@ -25,6 +28,9 @@ public:
|
||||
LocaleTests();
|
||||
~LocaleTests() override;
|
||||
|
||||
// Implementation of data for MappingNeon and MappingFreeBSD
|
||||
void MappingData();
|
||||
|
||||
private Q_SLOTS:
|
||||
void initTestCase();
|
||||
// Check the sample config file is processed correctly
|
||||
@@ -43,6 +49,21 @@ private Q_SLOTS:
|
||||
void testLanguageDetection_data();
|
||||
void testLanguageDetection();
|
||||
void testLanguageDetectionValencia();
|
||||
|
||||
// Check that the test-data is available and ok
|
||||
void testKDENeonLanguageData();
|
||||
void testLocaleNameParts();
|
||||
|
||||
// Check realistic language mapping for issue 2008
|
||||
void testLanguageMappingNeon_data();
|
||||
void testLanguageMappingNeon();
|
||||
void testLanguageMappingFreeBSD_data();
|
||||
void testLanguageMappingFreeBSD();
|
||||
void testLanguageSimilarity();
|
||||
|
||||
private:
|
||||
QStringList m_KDEneonLocales;
|
||||
QStringList m_FreeBSDLocales;
|
||||
};
|
||||
|
||||
QTEST_MAIN( LocaleTests )
|
||||
@@ -55,6 +76,12 @@ LocaleTests::~LocaleTests() {}
|
||||
void
|
||||
LocaleTests::initTestCase()
|
||||
{
|
||||
Logger::setupLogLevel( Logger::LOGDEBUG );
|
||||
const auto* settings = Calamares::Settings::instance();
|
||||
if ( !settings )
|
||||
{
|
||||
(void)new Calamares::Settings( true );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@@ -280,10 +307,10 @@ LocaleTests::testLanguageDetection_data()
|
||||
QTest::newRow( "english (US)" ) << QStringLiteral( "en" ) << QStringLiteral( "US" )
|
||||
<< QStringLiteral( "en_US.UTF-8" );
|
||||
QTest::newRow( "english (CA)" ) << QStringLiteral( "en" ) << QStringLiteral( "CA" )
|
||||
<< QStringLiteral( "en" ); // because it's first in the list
|
||||
<< QStringLiteral( "en_US.UTF-8" );
|
||||
QTest::newRow( "english (GB)" ) << QStringLiteral( "en" ) << QStringLiteral( "GB" )
|
||||
<< QStringLiteral( "en_GB.UTF-8" );
|
||||
QTest::newRow( "english (NL)" ) << QStringLiteral( "en" ) << QStringLiteral( "NL" ) << QStringLiteral( "en" );
|
||||
QTest::newRow( "english (NL)" ) << QStringLiteral( "en" ) << QStringLiteral( "NL" ) << QStringLiteral( "en_US.UTF-8" );
|
||||
|
||||
QTest::newRow( "portuguese (PT)" ) << QStringLiteral( "pt" ) << QStringLiteral( "PT" )
|
||||
<< QStringLiteral( "pt_PT.UTF-8" );
|
||||
@@ -293,11 +320,11 @@ LocaleTests::testLanguageDetection_data()
|
||||
<< QStringLiteral( "pt_BR.UTF-8" );
|
||||
|
||||
QTest::newRow( "catalan ()" ) << QStringLiteral( "ca" ) << QStringLiteral( "" )
|
||||
<< QStringLiteral( "ca_AD.UTF-8" ); // no country given? Matches first
|
||||
<< QStringLiteral( "ca_ES.UTF-8" ); // no country given? Matches QLocale-default
|
||||
QTest::newRow( "catalan (ES)" ) << QStringLiteral( "ca" ) << QStringLiteral( "ES" )
|
||||
<< QStringLiteral( "ca_ES.UTF-8" );
|
||||
QTest::newRow( "catalan (NL)" ) << QStringLiteral( "ca" ) << QStringLiteral( "NL" )
|
||||
<< QStringLiteral( "ca_AD.UTF-8" );
|
||||
<< QStringLiteral( "ca_ES.UTF-8" );
|
||||
QTest::newRow( "catalan (@valencia)" ) << QStringLiteral( "ca@valencia" ) << QStringLiteral( "ES" )
|
||||
<< QStringLiteral( "ca_ES@valencia" ); // Prefers regional variant
|
||||
QTest::newRow( "catalan (@valencia_NL)" )
|
||||
@@ -344,7 +371,7 @@ LocaleTests::testLanguageDetectionValencia()
|
||||
{
|
||||
auto r = LocaleConfiguration::fromLanguageAndLocation(
|
||||
QStringLiteral( "sr" ), availableLocales, QStringLiteral( "NL" ) );
|
||||
QCOMPARE( r.language(), "sr_ME" ); // Because that one is first in the list
|
||||
QCOMPARE( r.language(), "sr_RS" ); // Because that one is first in the list
|
||||
}
|
||||
{
|
||||
auto r = LocaleConfiguration::fromLanguageAndLocation(
|
||||
@@ -353,6 +380,206 @@ LocaleTests::testLanguageDetectionValencia()
|
||||
}
|
||||
}
|
||||
|
||||
static QStringList
|
||||
splitTestFileIntoLines( const QString& filename )
|
||||
{
|
||||
// BUILD_AS_TEST is the source-directory path
|
||||
const QFileInfo fi( QString( "%1/tests/%2" ).arg( BUILD_AS_TEST, filename ) );
|
||||
const QString path = fi.absoluteFilePath();
|
||||
QFile testData( path );
|
||||
if ( testData.open( QIODevice::ReadOnly ) )
|
||||
{
|
||||
return QString::fromUtf8( testData.readAll() ).split( '\n', Qt::SkipEmptyParts );
|
||||
}
|
||||
return QStringList {};
|
||||
}
|
||||
|
||||
void
|
||||
LocaleTests::testKDENeonLanguageData()
|
||||
{
|
||||
if ( !m_KDEneonLocales.isEmpty() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
const QStringList neonLocales = splitTestFileIntoLines( QStringLiteral( "locale-data-neon" ) );
|
||||
cDebug() << "Loaded KDE neon locales test data" << neonLocales.front() << "to" << neonLocales.back();
|
||||
QCOMPARE( neonLocales.length(), 318 ); // wc -l tells me 318 lines
|
||||
m_KDEneonLocales = neonLocales;
|
||||
|
||||
const QStringList bsdLocales = splitTestFileIntoLines( QStringLiteral( "locale-data-freebsd" ) );
|
||||
cDebug() << "Loaded FreeBSD locales test data" << bsdLocales.front() << "to" << bsdLocales.back();
|
||||
QCOMPARE( bsdLocales.length(), 79 );
|
||||
m_FreeBSDLocales = bsdLocales;
|
||||
}
|
||||
|
||||
void
|
||||
LocaleTests::MappingData()
|
||||
{
|
||||
QTest::addColumn< QString >( "selectedLanguage" );
|
||||
QTest::addColumn< QString >( "KDEneonLanguage" );
|
||||
QTest::addColumn< QString >( "FreeBSDLanguage" );
|
||||
|
||||
// Tired of writing QString or QStringLiteral all the time.
|
||||
auto l = []( const char* p ) { return QString::fromUtf8( p ); };
|
||||
auto u = []() { return QString(); };
|
||||
|
||||
// The KDEneon columns include the .UTF-8 from the source data
|
||||
// The FreeBSD columns may have u() to indicate "same as KDEneon",
|
||||
// that's an empty string.
|
||||
//
|
||||
// Each row shows how a language -- which can be selected from the
|
||||
// welcome page, and is inserted into GS as the language key that
|
||||
// Calamares knows -- should be mapped to a supported system locale.
|
||||
//
|
||||
// All the mappings are for ".. in NL", which can trigger minor variation
|
||||
// if there are languages with a _NL variant (e.g. nl_NL and nl_BE).
|
||||
|
||||
// clang-format off
|
||||
QTest::newRow( "en " ) << l( "en" ) << l( "en_US.UTF-8" ) << u();
|
||||
QTest::newRow( "en_GB" ) << l( "en_GB" ) << l( "en_GB.UTF-8" ) << u();
|
||||
QTest::newRow( "ca " ) << l( "ca" ) << l( "ca_ES.UTF-8" ) << u();
|
||||
// FreeBSD has no Valencian variant
|
||||
QTest::newRow( "ca@vl" ) << l( "ca@valencia" ) << l( "ca_ES@valencia" ) << l( "ca_ES.UTF-8" );
|
||||
// FreeBSD has the UTF-8 marker before the @region part
|
||||
QTest::newRow( "sr " ) << l( "sr" ) << l( "sr_RS" ) << l( "sr_RS.UTF-8" );
|
||||
QTest::newRow( "sr@lt" ) << l( "sr@latin" ) << l( "sr_RS@latin" ) << l( "sr_RS.UTF-8@latin" );
|
||||
QTest::newRow( "pt_PT" ) << l( "pt_PT" ) << l( "pt_PT.UTF-8" ) << u();
|
||||
QTest::newRow( "pt_BR" ) << l( "pt_BR" ) << l( "pt_BR.UTF-8" ) << u();
|
||||
QTest::newRow( "nl " ) << l( "nl" ) << l( "nl_NL.UTF-8" ) << u();
|
||||
QTest::newRow( "zh_TW" ) << l( "zh_TW" ) << l( "zh_TW.UTF-8" ) << u();
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LocaleTests::testLanguageMappingNeon_data()
|
||||
{
|
||||
MappingData();
|
||||
}
|
||||
|
||||
void
|
||||
LocaleTests::testLanguageMappingFreeBSD_data()
|
||||
{
|
||||
MappingData();
|
||||
}
|
||||
|
||||
void
|
||||
LocaleTests::testLanguageMappingNeon()
|
||||
{
|
||||
testKDENeonLanguageData();
|
||||
QVERIFY( !m_KDEneonLocales.isEmpty() );
|
||||
|
||||
QFETCH( QString, selectedLanguage );
|
||||
QFETCH( QString, KDEneonLanguage );
|
||||
QFETCH( QString, FreeBSDLanguage );
|
||||
|
||||
QVERIFY( Calamares::Locale::availableLanguages().contains( selectedLanguage ) );
|
||||
|
||||
const auto neon = LocaleConfiguration::fromLanguageAndLocation(
|
||||
( selectedLanguage ), m_KDEneonLocales, QStringLiteral( "NL" ) );
|
||||
QCOMPARE( neon.language(), KDEneonLanguage );
|
||||
}
|
||||
|
||||
void
|
||||
LocaleTests::testLanguageMappingFreeBSD()
|
||||
{
|
||||
testKDENeonLanguageData();
|
||||
QVERIFY( !m_FreeBSDLocales.isEmpty() );
|
||||
|
||||
QFETCH( QString, selectedLanguage );
|
||||
QFETCH( QString, KDEneonLanguage );
|
||||
QFETCH( QString, FreeBSDLanguage );
|
||||
|
||||
QVERIFY( Calamares::Locale::availableLanguages().contains( selectedLanguage ) );
|
||||
|
||||
const auto bsd = LocaleConfiguration::fromLanguageAndLocation(
|
||||
( selectedLanguage ), m_FreeBSDLocales, QStringLiteral( "NL" ) );
|
||||
const auto expected = FreeBSDLanguage.isEmpty() ? KDEneonLanguage : FreeBSDLanguage;
|
||||
QCOMPARE( bsd.language(), expected );
|
||||
}
|
||||
|
||||
void
|
||||
LocaleTests::testLocaleNameParts()
|
||||
{
|
||||
testKDENeonLanguageData();
|
||||
QVERIFY( !m_FreeBSDLocales.isEmpty() );
|
||||
QVERIFY( !m_KDEneonLocales.isEmpty() );
|
||||
|
||||
// Example constant locales
|
||||
{
|
||||
auto c_parts = LocaleNameParts::fromName( QStringLiteral( "nl_NL.UTF-8" ) );
|
||||
QCOMPARE( c_parts.language, QStringLiteral( "nl" ) );
|
||||
QCOMPARE( c_parts.country, QStringLiteral( "NL" ) );
|
||||
QCOMPARE( c_parts.encoding, QStringLiteral( "UTF-8" ) );
|
||||
QVERIFY( c_parts.region.isEmpty() );
|
||||
}
|
||||
{
|
||||
auto c_parts = LocaleNameParts::fromName( QStringLiteral( "C.UTF-8" ) );
|
||||
QCOMPARE( c_parts.language, QStringLiteral( "C" ) );
|
||||
QVERIFY( c_parts.country.isEmpty() );
|
||||
QCOMPARE( c_parts.encoding, QStringLiteral( "UTF-8" ) );
|
||||
QVERIFY( c_parts.region.isEmpty() );
|
||||
}
|
||||
|
||||
// Check all the loaded test locales
|
||||
for ( const auto& s : m_FreeBSDLocales )
|
||||
{
|
||||
auto parts = LocaleNameParts::fromName( s );
|
||||
QVERIFY( parts.isValid() );
|
||||
QCOMPARE( parts.name(), s );
|
||||
}
|
||||
|
||||
for ( const auto& s : m_KDEneonLocales )
|
||||
{
|
||||
auto parts = LocaleNameParts::fromName( s );
|
||||
QVERIFY( parts.isValid() );
|
||||
QCOMPARE( parts.name(), s );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LocaleTests::testLanguageSimilarity()
|
||||
{
|
||||
// Empty
|
||||
{
|
||||
QCOMPARE( LocaleNameParts().similarity( LocaleNameParts() ), 0 );
|
||||
}
|
||||
// Some simple Dutch situations
|
||||
{
|
||||
auto nl_parts = LocaleNameParts::fromName( QStringLiteral( "nl_NL.UTF-8" ) );
|
||||
auto be_parts = LocaleNameParts::fromName( QStringLiteral( "nl_BE.UTF-8" ) );
|
||||
auto nl_short_parts = LocaleNameParts::fromName( QStringLiteral( "nl" ) );
|
||||
QCOMPARE( nl_parts.similarity( nl_parts ), 100 );
|
||||
QCOMPARE( nl_parts.similarity( LocaleNameParts() ), 0 );
|
||||
QCOMPARE( nl_parts.similarity( be_parts ), 80 ); // Language + (empty) region match
|
||||
QCOMPARE( nl_parts.similarity( nl_short_parts ), 90 );
|
||||
}
|
||||
|
||||
// Everything matches itself
|
||||
{
|
||||
if ( m_KDEneonLocales.isEmpty() )
|
||||
{
|
||||
testKDENeonLanguageData();
|
||||
}
|
||||
QVERIFY( !m_FreeBSDLocales.isEmpty() );
|
||||
QVERIFY( !m_KDEneonLocales.isEmpty() );
|
||||
for ( const auto& l : m_KDEneonLocales )
|
||||
{
|
||||
auto locale_name = LocaleNameParts::fromName( l );
|
||||
auto self_similarity = locale_name.similarity( locale_name );
|
||||
if ( self_similarity != 100 )
|
||||
{
|
||||
cDebug() << "Locale" << l << "is unusual.";
|
||||
if ( l == QStringLiteral( "eo" ) )
|
||||
{
|
||||
QEXPECT_FAIL( "", "Esperanto has no country to match", Continue );
|
||||
}
|
||||
}
|
||||
QCOMPARE( self_similarity, 100 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#include "utils/moc-warnings.h"
|
||||
|
||||
|
79
src/modules/locale/tests/locale-data-freebsd
Normal file
79
src/modules/locale/tests/locale-data-freebsd
Normal file
@@ -0,0 +1,79 @@
|
||||
C.UTF-8
|
||||
af_ZA.UTF-8
|
||||
am_ET.UTF-8
|
||||
ar_AE.UTF-8
|
||||
ar_EG.UTF-8
|
||||
ar_JO.UTF-8
|
||||
ar_MA.UTF-8
|
||||
ar_QA.UTF-8
|
||||
ar_SA.UTF-8
|
||||
be_BY.UTF-8
|
||||
bg_BG.UTF-8
|
||||
ca_AD.UTF-8
|
||||
ca_ES.UTF-8
|
||||
ca_FR.UTF-8
|
||||
ca_IT.UTF-8
|
||||
cs_CZ.UTF-8
|
||||
da_DK.UTF-8
|
||||
de_AT.UTF-8
|
||||
de_CH.UTF-8
|
||||
de_DE.UTF-8
|
||||
el_GR.UTF-8
|
||||
en_AU.UTF-8
|
||||
en_CA.UTF-8
|
||||
en_GB.UTF-8
|
||||
en_HK.UTF-8
|
||||
en_IE.UTF-8
|
||||
en_NZ.UTF-8
|
||||
en_PH.UTF-8
|
||||
en_SG.UTF-8
|
||||
en_US.UTF-8
|
||||
en_ZA.UTF-8
|
||||
es_AR.UTF-8
|
||||
es_CR.UTF-8
|
||||
es_ES.UTF-8
|
||||
es_MX.UTF-8
|
||||
et_EE.UTF-8
|
||||
eu_ES.UTF-8
|
||||
fi_FI.UTF-8
|
||||
fr_BE.UTF-8
|
||||
fr_CA.UTF-8
|
||||
fr_CH.UTF-8
|
||||
fr_FR.UTF-8
|
||||
ga_IE.UTF-8
|
||||
he_IL.UTF-8
|
||||
hi_IN.UTF-8
|
||||
hr_HR.UTF-8
|
||||
hu_HU.UTF-8
|
||||
hy_AM.UTF-8
|
||||
is_IS.UTF-8
|
||||
it_CH.UTF-8
|
||||
it_IT.UTF-8
|
||||
ja_JP.UTF-8
|
||||
kk_KZ.UTF-8
|
||||
ko_KR.UTF-8
|
||||
lt_LT.UTF-8
|
||||
lv_LV.UTF-8
|
||||
mn_MN.UTF-8
|
||||
nb_NO.UTF-8
|
||||
nl_BE.UTF-8
|
||||
nl_NL.UTF-8
|
||||
nn_NO.UTF-8
|
||||
pl_PL.UTF-8
|
||||
pt_BR.UTF-8
|
||||
pt_PT.UTF-8
|
||||
ro_RO.UTF-8
|
||||
ru_RU.UTF-8
|
||||
se_FI.UTF-8
|
||||
se_NO.UTF-8
|
||||
sk_SK.UTF-8
|
||||
sl_SI.UTF-8
|
||||
sr_RS.UTF-8
|
||||
sr_RS.UTF-8@latin
|
||||
sv_FI.UTF-8
|
||||
sv_SE.UTF-8
|
||||
tr_TR.UTF-8
|
||||
uk_UA.UTF-8
|
||||
zh_CN.UTF-8
|
||||
zh_HK.UTF-8
|
||||
zh_TW.UTF-8
|
318
src/modules/locale/tests/locale-data-neon
Normal file
318
src/modules/locale/tests/locale-data-neon
Normal file
@@ -0,0 +1,318 @@
|
||||
aa_DJ.UTF-8
|
||||
aa_ER
|
||||
aa_ER@saaho
|
||||
aa_ET
|
||||
af_ZA.UTF-8
|
||||
agr_PE
|
||||
ak_GH
|
||||
am_ET
|
||||
an_ES.UTF-8
|
||||
anp_IN
|
||||
ar_AE.UTF-8
|
||||
ar_BH.UTF-8
|
||||
ar_DZ.UTF-8
|
||||
ar_EG.UTF-8
|
||||
ar_IN
|
||||
ar_IQ.UTF-8
|
||||
ar_JO.UTF-8
|
||||
ar_KW.UTF-8
|
||||
ar_LB.UTF-8
|
||||
ar_LY.UTF-8
|
||||
ar_MA.UTF-8
|
||||
ar_OM.UTF-8
|
||||
ar_QA.UTF-8
|
||||
ar_SA.UTF-8
|
||||
ar_SD.UTF-8
|
||||
ar_SS
|
||||
ar_SY.UTF-8
|
||||
ar_TN.UTF-8
|
||||
ar_YE.UTF-8
|
||||
ayc_PE
|
||||
az_AZ
|
||||
az_IR
|
||||
as_IN
|
||||
ast_ES.UTF-8
|
||||
be_BY.UTF-8
|
||||
be_BY@latin
|
||||
bem_ZM
|
||||
ber_DZ
|
||||
ber_MA
|
||||
bg_BG.UTF-8
|
||||
bhb_IN.UTF-8
|
||||
bho_IN
|
||||
bho_NP
|
||||
bi_VU
|
||||
bn_BD
|
||||
bn_IN
|
||||
bo_CN
|
||||
bo_IN
|
||||
br_FR.UTF-8
|
||||
brx_IN
|
||||
bs_BA.UTF-8
|
||||
byn_ER
|
||||
ca_AD.UTF-8
|
||||
ca_ES.UTF-8
|
||||
ca_ES@valencia
|
||||
ca_FR.UTF-8
|
||||
ca_IT.UTF-8
|
||||
ce_RU
|
||||
ckb_IQ
|
||||
chr_US
|
||||
cmn_TW
|
||||
crh_UA
|
||||
cs_CZ.UTF-8
|
||||
csb_PL
|
||||
cv_RU
|
||||
cy_GB.UTF-8
|
||||
da_DK.UTF-8
|
||||
de_AT.UTF-8
|
||||
de_BE.UTF-8
|
||||
de_CH.UTF-8
|
||||
de_DE.UTF-8
|
||||
de_IT.UTF-8
|
||||
de_LI.UTF-8
|
||||
de_LU.UTF-8
|
||||
doi_IN
|
||||
dsb_DE
|
||||
dv_MV
|
||||
dz_BT
|
||||
el_GR.UTF-8
|
||||
el_CY.UTF-8
|
||||
en_AG
|
||||
en_AU.UTF-8
|
||||
en_BW.UTF-8
|
||||
en_CA.UTF-8
|
||||
en_DK.UTF-8
|
||||
en_GB.UTF-8
|
||||
en_HK.UTF-8
|
||||
en_IE.UTF-8
|
||||
en_IL
|
||||
en_IN
|
||||
en_NG
|
||||
en_NZ.UTF-8
|
||||
en_PH.UTF-8
|
||||
en_SC.UTF-8
|
||||
en_SG.UTF-8
|
||||
en_US.UTF-8
|
||||
en_ZA.UTF-8
|
||||
en_ZM
|
||||
en_ZW.UTF-8
|
||||
eo
|
||||
eo_US.UTF-8
|
||||
es_AR.UTF-8
|
||||
es_BO.UTF-8
|
||||
es_CL.UTF-8
|
||||
es_CO.UTF-8
|
||||
es_CR.UTF-8
|
||||
es_CU
|
||||
es_DO.UTF-8
|
||||
es_EC.UTF-8
|
||||
es_ES.UTF-8
|
||||
es_GT.UTF-8
|
||||
es_HN.UTF-8
|
||||
es_MX.UTF-8
|
||||
es_NI.UTF-8
|
||||
es_PA.UTF-8
|
||||
es_PE.UTF-8
|
||||
es_PR.UTF-8
|
||||
es_PY.UTF-8
|
||||
es_SV.UTF-8
|
||||
es_US.UTF-8
|
||||
es_UY.UTF-8
|
||||
es_VE.UTF-8
|
||||
et_EE.UTF-8
|
||||
eu_ES.UTF-8
|
||||
eu_FR.UTF-8
|
||||
fa_IR
|
||||
ff_SN
|
||||
fi_FI.UTF-8
|
||||
fil_PH
|
||||
fo_FO.UTF-8
|
||||
fr_BE.UTF-8
|
||||
fr_CA.UTF-8
|
||||
fr_CH.UTF-8
|
||||
fr_FR.UTF-8
|
||||
fr_LU.UTF-8
|
||||
fur_IT
|
||||
fy_NL
|
||||
fy_DE
|
||||
ga_IE.UTF-8
|
||||
gd_GB.UTF-8
|
||||
gez_ER
|
||||
gez_ER@abegede
|
||||
gez_ET
|
||||
gez_ET@abegede
|
||||
gl_ES.UTF-8
|
||||
gu_IN
|
||||
gv_GB.UTF-8
|
||||
ha_NG
|
||||
hak_TW
|
||||
he_IL.UTF-8
|
||||
hi_IN
|
||||
hif_FJ
|
||||
hne_IN
|
||||
hr_HR.UTF-8
|
||||
hsb_DE.UTF-8
|
||||
ht_HT
|
||||
hu_HU.UTF-8
|
||||
hy_AM
|
||||
ia_FR
|
||||
id_ID.UTF-8
|
||||
ig_NG
|
||||
ik_CA
|
||||
is_IS.UTF-8
|
||||
it_CH.UTF-8
|
||||
it_IT.UTF-8
|
||||
iu_CA
|
||||
ja_JP.UTF-8
|
||||
ka_GE.UTF-8
|
||||
kab_DZ
|
||||
kk_KZ.UTF-8
|
||||
kl_GL.UTF-8
|
||||
km_KH
|
||||
kn_IN
|
||||
ko_KR.UTF-8
|
||||
kok_IN
|
||||
ks_IN
|
||||
ks_IN@devanagari
|
||||
ku_TR.UTF-8
|
||||
kw_GB.UTF-8
|
||||
ky_KG
|
||||
lb_LU
|
||||
lg_UG.UTF-8
|
||||
li_BE
|
||||
li_NL
|
||||
lij_IT
|
||||
ln_CD
|
||||
lo_LA
|
||||
lt_LT.UTF-8
|
||||
lv_LV.UTF-8
|
||||
lzh_TW
|
||||
mag_IN
|
||||
mai_IN
|
||||
mai_NP
|
||||
mfe_MU
|
||||
mg_MG.UTF-8
|
||||
mhr_RU
|
||||
mi_NZ.UTF-8
|
||||
miq_NI
|
||||
mjw_IN
|
||||
mk_MK.UTF-8
|
||||
ml_IN
|
||||
mn_MN
|
||||
mni_IN
|
||||
mnw_MM
|
||||
mr_IN
|
||||
ms_MY.UTF-8
|
||||
mt_MT.UTF-8
|
||||
my_MM
|
||||
nan_TW
|
||||
nan_TW@latin
|
||||
nb_NO.UTF-8
|
||||
nds_DE
|
||||
nds_NL
|
||||
ne_NP
|
||||
nhn_MX
|
||||
niu_NU
|
||||
niu_NZ
|
||||
nl_AW
|
||||
nl_BE.UTF-8
|
||||
nl_NL.UTF-8
|
||||
nn_NO.UTF-8
|
||||
nr_ZA
|
||||
nso_ZA
|
||||
oc_FR.UTF-8
|
||||
om_ET
|
||||
om_KE.UTF-8
|
||||
or_IN
|
||||
os_RU
|
||||
pa_IN
|
||||
pa_PK
|
||||
pap_AW
|
||||
pap_CW
|
||||
pl_PL.UTF-8
|
||||
ps_AF
|
||||
pt_BR.UTF-8
|
||||
pt_PT.UTF-8
|
||||
quz_PE
|
||||
raj_IN
|
||||
ro_RO.UTF-8
|
||||
ru_RU.UTF-8
|
||||
ru_UA.UTF-8
|
||||
rw_RW
|
||||
sa_IN
|
||||
sah_RU
|
||||
sat_IN
|
||||
sc_IT
|
||||
sd_IN
|
||||
sd_IN@devanagari
|
||||
sd_PK
|
||||
se_NO
|
||||
sgs_LT
|
||||
shn_MM
|
||||
shs_CA
|
||||
si_LK
|
||||
sid_ET
|
||||
sk_SK.UTF-8
|
||||
sl_SI.UTF-8
|
||||
sm_WS
|
||||
so_DJ.UTF-8
|
||||
so_ET
|
||||
so_KE.UTF-8
|
||||
so_SO.UTF-8
|
||||
sq_AL.UTF-8
|
||||
sq_MK
|
||||
sr_ME
|
||||
sr_RS
|
||||
sr_RS@latin
|
||||
ss_ZA
|
||||
st_ZA.UTF-8
|
||||
sv_FI.UTF-8
|
||||
sv_SE.UTF-8
|
||||
sw_KE
|
||||
sw_TZ
|
||||
szl_PL
|
||||
ta_IN
|
||||
ta_LK
|
||||
tcy_IN.UTF-8
|
||||
te_IN
|
||||
tg_TJ.UTF-8
|
||||
th_TH.UTF-8
|
||||
the_NP
|
||||
ti_ER
|
||||
ti_ET
|
||||
tig_ER
|
||||
tk_TM
|
||||
tl_PH.UTF-8
|
||||
tn_ZA
|
||||
to_TO
|
||||
tpi_PG
|
||||
tr_CY.UTF-8
|
||||
tr_TR.UTF-8
|
||||
ts_ZA
|
||||
tt_RU
|
||||
tt_RU@iqtelif
|
||||
ug_CN
|
||||
ug_CN@latin
|
||||
uk_UA.UTF-8
|
||||
unm_US
|
||||
ur_IN
|
||||
ur_PK
|
||||
uz_UZ.UTF-8
|
||||
uz_UZ@cyrillic
|
||||
ve_ZA
|
||||
vi_VN
|
||||
wa_BE.UTF-8
|
||||
wae_CH
|
||||
wal_ET
|
||||
wo_SN
|
||||
xh_ZA.UTF-8
|
||||
yi_US.UTF-8
|
||||
yo_NG
|
||||
yue_HK
|
||||
yuw_PG
|
||||
zh_CN.UTF-8
|
||||
zh_HK.UTF-8
|
||||
zh_SG.UTF-8
|
||||
zh_TW.UTF-8
|
||||
zu_ZA.UTF-8
|
@@ -31,8 +31,9 @@ calamares_add_plugin(localeq
|
||||
EXPORT_MACRO PLUGINDLLEXPORT_PRO
|
||||
SOURCES
|
||||
LocaleQmlViewStep.cpp
|
||||
${_locale}/LocaleConfiguration.cpp
|
||||
${_locale}/Config.cpp
|
||||
${_locale}/LocaleConfiguration.cpp
|
||||
${_locale}/LocaleNames.cpp
|
||||
${_locale}/SetTimezoneJob.cpp
|
||||
RESOURCES
|
||||
localeq.qrc
|
||||
|
@@ -12,9 +12,4 @@ calamares_add_plugin(luksbootkeyfile
|
||||
NO_CONFIG
|
||||
)
|
||||
|
||||
calamares_add_test(
|
||||
luksbootkeyfiletest
|
||||
SOURCES
|
||||
Tests.cpp
|
||||
LuksBootKeyFileJob.cpp
|
||||
)
|
||||
calamares_add_test(luksbootkeyfiletest SOURCES Tests.cpp LuksBootKeyFileJob.cpp)
|
||||
|
@@ -165,7 +165,7 @@ globalStoragePartitionInfo( Calamares::GlobalStorage* gs, LOSHInfo& info )
|
||||
{
|
||||
Calamares::String::removeLeading( btrfsRootSubvolume, '/' );
|
||||
info.keyfile_device_mount_options
|
||||
= QStringLiteral( "keyfile_device_mount_options=--options=subvol=" ) + btrfsRootSubvolume;
|
||||
= QStringLiteral( "--options=subvol=" ) + btrfsRootSubvolume;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -14,6 +14,7 @@
|
||||
#include "IDJob.h"
|
||||
|
||||
#include "utils/Retranslator.h"
|
||||
#include "utils/StringExpander.h"
|
||||
#include "utils/Variant.h"
|
||||
|
||||
#include <QDate>
|
||||
@@ -82,14 +83,10 @@ OEMViewStep::isAtEnd() const
|
||||
static QString
|
||||
substitute( QString s )
|
||||
{
|
||||
QString t_date = QStringLiteral( "@@DATE@@" );
|
||||
if ( s.contains( t_date ) )
|
||||
{
|
||||
auto date = QDate::currentDate();
|
||||
s = s.replace( t_date, date.toString( Qt::ISODate ) );
|
||||
}
|
||||
Calamares::String::DictionaryExpander d;
|
||||
d.insert( QStringLiteral( "DATE" ), QDate::currentDate().toString( Qt::ISODate ) );
|
||||
|
||||
return s;
|
||||
return d.expand( s );
|
||||
}
|
||||
|
||||
void
|
||||
|
@@ -5,12 +5,12 @@
|
||||
---
|
||||
# The batch-identifier is written to /var/log/installer/oem-id.
|
||||
# This value is put into the text box as the **suggested**
|
||||
# OEM ID. If @@DATE@@ is included in the identifier, then
|
||||
# OEM ID. If ${DATE} is included in the identifier, then
|
||||
# that is replaced by the current date in yyyy-MM-dd (ISO) format.
|
||||
#
|
||||
# it is ok for the identifier to be empty.
|
||||
# It is ok for the identifier to be empty.
|
||||
#
|
||||
# The identifier is written to the file as UTF-8 (this will be no
|
||||
# different from ASCII, for most inputs) and followed by a newline.
|
||||
# If the identifier is empty, only a newline is written.
|
||||
batch-identifier: neon-@@DATE@@
|
||||
batch-identifier: neon-${DATE}
|
||||
|
@@ -72,7 +72,7 @@ fromComponent( AppStream::Component& component )
|
||||
map.insert( "name", en_name );
|
||||
map.insert( "description", en_description );
|
||||
|
||||
for ( const QString& locale : CalamaresUtils::Locale::availableTranslations()->localeIds() )
|
||||
for ( const QString& locale : Calamares::Locale::availableTranslations()->localeIds() )
|
||||
{
|
||||
component.setActiveLocale( locale );
|
||||
QString name = component.name();
|
||||
|
@@ -18,27 +18,27 @@
|
||||
# modules since the partitions on disk won't match GS, but it can be
|
||||
# useful for debugging simulated installations that don't need to
|
||||
# mount the target filesystems.
|
||||
option( DEBUG_PARTITION_UNSAFE "Allow unsafe partitioning choices." OFF )
|
||||
option( DEBUG_PARTITION_BAIL_OUT "Unsafe partitioning will error out on exec." ON )
|
||||
option( DEBUG_PARTITION_SKIP "Don't actually do any partitioning." OFF)
|
||||
option(DEBUG_PARTITION_UNSAFE "Allow unsafe partitioning choices." OFF)
|
||||
option(DEBUG_PARTITION_BAIL_OUT "Unsafe partitioning will error out on exec." ON)
|
||||
option(DEBUG_PARTITION_SKIP "Don't actually do any partitioning." OFF)
|
||||
|
||||
# This is very chatty, useful mostly if you don't know what KPMCore offers.
|
||||
option(DEBUG_FILESYSTEMS "Log all available Filesystems from KPMCore." OFF)
|
||||
|
||||
include_directories(${CMAKE_SOURCE_DIR}) # For 3rdparty
|
||||
|
||||
set( _partition_defs )
|
||||
if( DEBUG_PARTITION_UNSAFE )
|
||||
if( DEBUG_PARTITION_BAIL_OUT )
|
||||
list( APPEND _partition_defs DEBUG_PARTITION_BAIL_OUT )
|
||||
set(_partition_defs)
|
||||
if(DEBUG_PARTITION_UNSAFE)
|
||||
if(DEBUG_PARTITION_BAIL_OUT)
|
||||
list(APPEND _partition_defs DEBUG_PARTITION_BAIL_OUT)
|
||||
endif()
|
||||
list(APPEND _partition_defs DEBUG_PARTITION_UNSAFE)
|
||||
endif()
|
||||
if(DEBUG_FILESYSTEMS)
|
||||
list(APPEND _partition_defs DEBUG_FILESYSTEMS)
|
||||
endif()
|
||||
if( DEBUG_PARTITION_SKIP )
|
||||
list( APPEND _partition_defs DEBUG_PARTITION_SKIP )
|
||||
if(DEBUG_PARTITION_SKIP)
|
||||
list(APPEND _partition_defs DEBUG_PARTITION_SKIP)
|
||||
endif()
|
||||
|
||||
find_package(ECM ${ECM_VERSION} REQUIRED NO_MODULE)
|
||||
@@ -49,9 +49,7 @@ find_package(KF5Config CONFIG)
|
||||
find_package(KF5I18n CONFIG)
|
||||
find_package(KF5WidgetsAddons CONFIG)
|
||||
|
||||
if(KPMcore_FOUND AND Qt5DBus_FOUND AND KF5CoreAddons_FOUND AND KF5Config_FOUND)
|
||||
list(APPEND _partition_defs ${KPMcore_API_DEFINITIONS})
|
||||
include_directories(${KPMCORE_INCLUDE_DIR})
|
||||
if(KPMcore_FOUND)
|
||||
include_directories(${PROJECT_BINARY_DIR}/src/libcalamaresui)
|
||||
|
||||
add_subdirectory(tests)
|
||||
@@ -118,7 +116,7 @@ if(KPMcore_FOUND AND Qt5DBus_FOUND AND KF5CoreAddons_FOUND AND KF5Config_FOUND)
|
||||
gui/ReplaceWidget.ui
|
||||
gui/VolumeGroupBaseDialog.ui
|
||||
LINK_PRIVATE_LIBRARIES
|
||||
kpmcore
|
||||
calamares::kpmcore
|
||||
KF5::CoreAddons
|
||||
COMPILE_DEFINITIONS ${_partition_defs}
|
||||
SHARED_LIB
|
||||
|
@@ -467,18 +467,6 @@ ChoicePage::onActionChanged()
|
||||
applyActionChoice( m_config->installChoice() );
|
||||
}
|
||||
|
||||
// Whole disk encryption isn't implemented for zfs so disable the option for now
|
||||
if ( m_eraseFsTypesChoiceComboBox != nullptr && m_enableEncryptionWidget )
|
||||
{
|
||||
if ( m_eraseFsTypesChoiceComboBox->currentText() == "zfs" )
|
||||
{
|
||||
m_encryptWidget->hide();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_encryptWidget->show();
|
||||
}
|
||||
}
|
||||
updateNextEnabled();
|
||||
}
|
||||
|
||||
@@ -1075,10 +1063,7 @@ ChoicePage::updateActionChoicePreview( InstallChoice choice )
|
||||
case InstallChoice::Erase:
|
||||
case InstallChoice::Replace:
|
||||
{
|
||||
if ( m_enableEncryptionWidget )
|
||||
{
|
||||
m_encryptWidget->show();
|
||||
}
|
||||
m_encryptWidget->setVisible( shouldShowEncryptWidget( choice ) );
|
||||
m_previewBeforeLabel->setText( tr( "Current:" ) );
|
||||
m_afterPartitionBarsView = new PartitionBarsView( m_previewAfterFrame );
|
||||
m_afterPartitionBarsView->setNestedPartitionsMode( mode );
|
||||
@@ -1745,3 +1730,11 @@ ChoicePage::createBootloaderPanel()
|
||||
|
||||
return panelWidget;
|
||||
}
|
||||
|
||||
bool ChoicePage::shouldShowEncryptWidget( Config::InstallChoice choice ) const
|
||||
{
|
||||
// If there are any choices for FS, check it's not ZFS because that doesn't
|
||||
// support the kind of encryption we enable here.
|
||||
const bool suitableFS = m_eraseFsTypesChoiceComboBox ? m_eraseFsTypesChoiceComboBox->currentText() != "zfs" : true;
|
||||
return (choice == InstallChoice::Erase) && m_enableEncryptionWidget && suitableFS;
|
||||
}
|
||||
|
@@ -126,6 +126,7 @@ private:
|
||||
|
||||
void updateDeviceStatePreview();
|
||||
void updateActionChoicePreview( Config::InstallChoice choice );
|
||||
bool shouldShowEncryptWidget( Config::InstallChoice choice ) const;
|
||||
void setupActions();
|
||||
OsproberEntryList getOsproberEntriesForDevice( Device* device ) const;
|
||||
void doAlongsideApply();
|
||||
@@ -167,7 +168,7 @@ private:
|
||||
int m_lastSelectedDeviceIndex = -1;
|
||||
int m_lastSelectedActionIndex = -1;
|
||||
|
||||
bool m_enableEncryptionWidget;
|
||||
bool m_enableEncryptionWidget = false;
|
||||
|
||||
QMutex m_coreMutex;
|
||||
};
|
||||
|
@@ -25,14 +25,14 @@ calamares_add_test(
|
||||
${PartitionModule_SOURCE_DIR}/jobs/DeletePartitionJob.cpp
|
||||
${PartitionModule_SOURCE_DIR}/jobs/PartitionJob.cpp
|
||||
${PartitionModule_SOURCE_DIR}/jobs/ResizePartitionJob.cpp
|
||||
LIBRARIES kpmcore
|
||||
LIBRARIES calamares::kpmcore
|
||||
DEFINITIONS ${_partition_defs}
|
||||
)
|
||||
|
||||
calamares_add_test(
|
||||
partitionclearmountsjobtest
|
||||
SOURCES ${PartitionModule_SOURCE_DIR}/jobs/ClearMountsJob.cpp ClearMountsJobTests.cpp
|
||||
LIBRARIES kpmcore
|
||||
LIBRARIES calamares::kpmcore
|
||||
DEFINITIONS ${_partition_defs}
|
||||
)
|
||||
|
||||
@@ -45,7 +45,7 @@ calamares_add_test(
|
||||
${PartitionModule_SOURCE_DIR}/core/PartitionLayout.cpp
|
||||
${PartitionModule_SOURCE_DIR}/core/PartUtils.cpp
|
||||
${PartitionModule_SOURCE_DIR}/core/DeviceModel.cpp
|
||||
LIBRARIES kpmcore Calamares::calamaresui
|
||||
LIBRARIES calamares::kpmcore Calamares::calamaresui
|
||||
DEFINITIONS ${_partition_defs}
|
||||
)
|
||||
|
||||
@@ -58,6 +58,6 @@ calamares_add_test(
|
||||
calamares_add_test(
|
||||
partitiondevicestest
|
||||
SOURCES DevicesTests.cpp ${PartitionModule_SOURCE_DIR}/core/DeviceList.cpp
|
||||
LIBRARIES kpmcore
|
||||
LIBRARIES calamares::kpmcore
|
||||
DEFINITIONS ${_partition_defs}
|
||||
)
|
||||
|
@@ -15,6 +15,7 @@
|
||||
#include "utils/CalamaresUtilsSystem.h"
|
||||
#include "utils/CommandList.h"
|
||||
#include "utils/Logger.h"
|
||||
#include "utils/StringExpander.h"
|
||||
#include "utils/Units.h"
|
||||
|
||||
#include <QFile>
|
||||
@@ -37,7 +38,8 @@ atReplacements( QString s )
|
||||
user = gs->value( "username" ).toString();
|
||||
}
|
||||
|
||||
return s.replace( "@@ROOT@@", root ).replace( "@@USER@@", user );
|
||||
Calamares::String::DictionaryExpander d;
|
||||
return d.add( QStringLiteral( "ROOT" ), root ).add( QStringLiteral( "USER" ), user ).expand( s );
|
||||
}
|
||||
|
||||
PreserveFiles::PreserveFiles( QObject* parent )
|
||||
|
@@ -40,11 +40,11 @@
|
||||
# not exist in the host system (e.g. nvidia configuration files that
|
||||
# are created in some boot scenarios and not in others).
|
||||
#
|
||||
# The target path (*dest*) is modified as follows:
|
||||
# - `@@ROOT@@` is replaced by the path to the target root (may be /).
|
||||
# The target path (*dest*) is modified by expanding variables in `${}`:
|
||||
# - `ROOT` is replaced by the path to the target root (may be /).
|
||||
# There is never any reason to use this, since the *dest* is already
|
||||
# interpreted in the target system.
|
||||
# - `@@USER@@` is replaced by the username entered by on the user
|
||||
# - `USER` is replaced by the username entered by on the user
|
||||
# page (may be empty, for instance if no user page is enabled)
|
||||
#
|
||||
#
|
||||
@@ -53,6 +53,9 @@ files:
|
||||
- from: log
|
||||
dest: /var/log/Calamares.log
|
||||
perm: root:wheel:600
|
||||
- from: log
|
||||
dest: /home/${USER}/installation.log
|
||||
optional: true
|
||||
- from: config
|
||||
dest: /var/log/Calamares-install.json
|
||||
perm: root:wheel:600
|
||||
|
@@ -7,10 +7,10 @@
|
||||
# SPDX-FileCopyrightText: 2014 Teo Mrnjavac <teo@kde.org>
|
||||
# SPDX-FileCopyrightText: 2017 Alf Gaida <agaida@siduction.org>
|
||||
# SPDX-FileCopyrightText: 2018-2019 Adriaan de Groot <groot@kde.org>
|
||||
# SPDX-FileCopyrightText: 2022 shivanandvp <shivanandvp@rebornos.org>
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
#
|
||||
# Calamares is Free Software: see the License-Identifier above.
|
||||
#
|
||||
|
||||
import libcalamares
|
||||
|
||||
@@ -23,96 +23,64 @@ _ = gettext.translation("calamares-python",
|
||||
|
||||
|
||||
def pretty_name():
|
||||
return _("Configure systemd services")
|
||||
return _("Configure systemd units")
|
||||
|
||||
|
||||
def systemctl(targets, command, suffix):
|
||||
def systemctl(units):
|
||||
"""
|
||||
For each entry in @p targets, run "systemctl <command> <thing>",
|
||||
where <thing> is the entry's name plus the given @p suffix.
|
||||
(No dot is added between name and suffix; suffix may be empty)
|
||||
For each entry in @p units, run "systemctl <action> <name>",
|
||||
where each unit is a mapping of unit name, action, and a flag.
|
||||
|
||||
Returns a failure message, or None if this was successful.
|
||||
Services that are not mandatory have their failures suppressed
|
||||
Units that are not mandatory have their failures suppressed
|
||||
silently.
|
||||
"""
|
||||
for svc in targets:
|
||||
if isinstance(svc, str):
|
||||
name = svc
|
||||
|
||||
for unit in units:
|
||||
if isinstance(unit, str):
|
||||
name = unit
|
||||
action = "enable"
|
||||
mandatory = False
|
||||
else:
|
||||
name = svc["name"]
|
||||
mandatory = svc.get("mandatory", False)
|
||||
if not unit.has_key("name"):
|
||||
libcalamares.utils.error("The key 'name' is missing from the mapping {_unit!s}. Continuing to the next unit.".format(_unit=str(unit)))
|
||||
continue
|
||||
name = unit["name"]
|
||||
action = unit.get("action", "enable")
|
||||
mandatory = unit.get("mandatory", False)
|
||||
|
||||
ec = libcalamares.utils.target_env_call(
|
||||
['systemctl', command, "{}{}".format(name, suffix)]
|
||||
exit_code = libcalamares.utils.target_env_call(
|
||||
['systemctl', action, name]
|
||||
)
|
||||
|
||||
if exit_code != 0:
|
||||
libcalamares.utils.warning(
|
||||
"Cannot {} systemd unit {}".format(action, name)
|
||||
)
|
||||
|
||||
if ec != 0:
|
||||
libcalamares.utils.warning(
|
||||
"Cannot {} systemd {} {}".format(command, suffix, name)
|
||||
)
|
||||
libcalamares.utils.warning(
|
||||
"systemctl {} call in chroot returned error code {}".format(command, ec)
|
||||
)
|
||||
"systemctl {} call in chroot returned error code {}".format(action, exit_code)
|
||||
)
|
||||
if mandatory:
|
||||
title = _("Cannot modify service")
|
||||
diagnostic = _("<code>systemctl {arg!s}</code> call in chroot returned error code {num!s}.").format(arg=command, num=ec)
|
||||
|
||||
if command == "enable" and suffix == ".service":
|
||||
description = _("Cannot enable systemd service <code>{name!s}</code>.")
|
||||
elif command == "enable" and suffix == ".target":
|
||||
description = _("Cannot enable systemd target <code>{name!s}</code>.")
|
||||
elif command == "enable" and suffix == ".timer":
|
||||
description = _("Cannot enable systemd timer <code>{name!s}</code>.")
|
||||
elif command == "disable" and suffix == ".service":
|
||||
description = _("Cannot enable systemd service <code>{name!s}</code>.")
|
||||
elif command == "disable" and suffix == ".target":
|
||||
description = _("Cannot disable systemd target <code>{name!s}</code>.")
|
||||
elif command == "mask":
|
||||
description = _("Cannot mask systemd unit <code>{name!s}</code>.")
|
||||
else:
|
||||
description = _("Unknown systemd commands <code>{command!s}</code> and <code>{suffix!s}</code> for unit {name!s}.")
|
||||
|
||||
return (title,
|
||||
description.format(name=name, command=command, suffix=suffix) + " " + diagnostic
|
||||
)
|
||||
title = _("Cannot modify unit")
|
||||
diagnostic = _("<code>systemctl {_action!s}</code> call in chroot returned error code {_exit_code!s}.").format(_action=action, _exit_code=exit_code)
|
||||
description = _("Cannot {_action!s} systemd unit <code>{_name!s}</code>.").format(_action=action, _name=name)
|
||||
return (
|
||||
title,
|
||||
description + " " + diagnostic
|
||||
)
|
||||
return None
|
||||
|
||||
|
||||
def run():
|
||||
"""
|
||||
Setup systemd services
|
||||
Setup systemd units
|
||||
"""
|
||||
cfg = libcalamares.job.configuration
|
||||
|
||||
# note that the "systemctl enable" and "systemctl disable" commands used
|
||||
# here will work in a chroot; in fact, they are the only systemctl commands
|
||||
# that support that, see:
|
||||
# http://0pointer.de/blog/projects/changing-roots.html
|
||||
|
||||
r = systemctl(cfg.get("services", []), "enable", ".service")
|
||||
if r is not None:
|
||||
return r
|
||||
|
||||
r = systemctl(cfg.get("targets", []), "enable", ".target")
|
||||
if r is not None:
|
||||
return r
|
||||
|
||||
r = systemctl(cfg.get("timers", []), "enable", ".timer")
|
||||
if r is not None:
|
||||
return r
|
||||
|
||||
r = systemctl(cfg.get("disable", []), "disable", ".service")
|
||||
if r is not None:
|
||||
return r
|
||||
|
||||
r = systemctl(cfg.get("disable-targets", []), "disable", ".target")
|
||||
if r is not None:
|
||||
return r
|
||||
|
||||
r = systemctl(cfg.get("mask", []), "mask", "")
|
||||
if r is not None:
|
||||
return r
|
||||
return_value = systemctl(
|
||||
cfg.get("units", [])
|
||||
)
|
||||
if return_value is not None:
|
||||
return return_value
|
||||
|
||||
return None
|
||||
|
@@ -1,79 +1,53 @@
|
||||
# SPDX-FileCopyrightText: no
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
#
|
||||
# Systemd services manipulation.
|
||||
# Systemd units manipulation.
|
||||
#
|
||||
# This module can enable services, timers and targets for systemd
|
||||
# (if packaging doesn't already do that). It can also
|
||||
# disable services and targets as well as mask units.
|
||||
#
|
||||
# The order of operations is fixed. Enable services, enable targets,
|
||||
# enable timers, disable services, disable targets and finally apply masks.
|
||||
# This module can perform actions using systemd units,
|
||||
# (for example, enabling, disabling, or masking services, sockets, paths, etc.)
|
||||
---
|
||||
|
||||
# There are several configuration keys for this module:
|
||||
# *services*, *targets*, *timers*, *disable*, *disable-targets* and *mask*.
|
||||
# The value of each key is a list of entries. Each entry has two keys:
|
||||
# - *name* is the (string) name of the service or target that is being
|
||||
# changed. Use quotes. Don't include unit suffix in the name. For
|
||||
# example, it should be "NetworkManager", not "NetworkManager.service"
|
||||
# There is one key for this module: *units*. Its value is a list of entries.
|
||||
# Each entry has three keys:
|
||||
# - *name* is the (string) name of the systemd unit that is being changed.
|
||||
# Use quotes. You can use any valid systemd unit here (for example,
|
||||
# "NetworkManager.service", "cups.socket", "lightdm", "gdm", etc.)
|
||||
# - *action* is the (string) action that you want to perform over the unit
|
||||
# (for example, "enable", "disable", "mask", "unmask", etc.). Please
|
||||
# ensure that the action can actually run under chroot (otherwise it is
|
||||
# pointless)
|
||||
# - *mandatory* is a boolean option, which states whether the change
|
||||
# must be done successfully. If systemd reports an error while changing
|
||||
# a mandatory entry, the installation will fail. When mandatory is false,
|
||||
# errors for that systemd unit are ignored. If mandatory
|
||||
# is not specified, the default is false.
|
||||
#
|
||||
# An entry may also be given as a single string, which is then
|
||||
# interpreted as the name of the service. In this case, mandatory
|
||||
# is also set to the default of false.
|
||||
#
|
||||
# Use [] to express an empty list.
|
||||
# The order of operations is the same as the order in which entries
|
||||
# appear in the list
|
||||
|
||||
# # This example enables NetworkManager (and fails if it can't),
|
||||
# # disables cups (and ignores failure). Then it enables the
|
||||
# # This example enables NetworkManager.service (and fails if it can't),
|
||||
# # disables cups.socket (and ignores failure). Then it enables the
|
||||
# # graphical target (e.g. so that SDDM runs for login), and
|
||||
# # finally disables pacman-init (an ArchLinux-only service).
|
||||
# # finally masks pacman-init (an ArchLinux-only service).
|
||||
# #
|
||||
# # Enables <name>.service
|
||||
# services:
|
||||
# units:
|
||||
# - name: "NetworkManager"
|
||||
# action: "enable"
|
||||
# mandatory: true
|
||||
# - name: "cups"
|
||||
#
|
||||
# - name: "cups.socket"
|
||||
# action: "disable"
|
||||
# mandatory: false
|
||||
#
|
||||
# # Enables <name>.target
|
||||
# targets:
|
||||
# - name: "graphical"
|
||||
# mandatory: true
|
||||
# action: "enable"
|
||||
# # The property "mandatory" is taken to be false by default here
|
||||
# # because it is not specified
|
||||
#
|
||||
# # Enables <name>.timer
|
||||
# timers:
|
||||
# - name: "fstrim"
|
||||
# mandatory: false
|
||||
#
|
||||
# # Disables <name>.service
|
||||
# disable:
|
||||
# - name: "pacman-init"
|
||||
# mandatory: false
|
||||
#
|
||||
# # Disables <name>.target
|
||||
# # .. this shows how to use just the name
|
||||
# disable-targets:
|
||||
# - graphical
|
||||
#
|
||||
# # Masks (stronger version of disable). This section
|
||||
# # is unusual because you **must** include the suffix
|
||||
# # (e.g. ".service") as part of the name, so, e.g. to mask
|
||||
# # NetworkManager (rather than just disable it) you must
|
||||
# # specify "NetworkManager.service" as name.
|
||||
# mask:
|
||||
# - name: "NetworkManager.service"
|
||||
# - mandatory: true
|
||||
# action: "mask"
|
||||
# # The property "mandatory" is taken to be false by default here
|
||||
# # because it is not specified
|
||||
|
||||
# By default, no changes are made.
|
||||
services: []
|
||||
targets: []
|
||||
timers: []
|
||||
disable: []
|
||||
disable-targets: []
|
||||
mask: []
|
||||
units: []
|
||||
|
@@ -4,22 +4,18 @@
|
||||
$schema: https://json-schema.org/schema#
|
||||
$id: https://calamares.io/schemas/services-systemd
|
||||
definitions:
|
||||
service:
|
||||
$id: 'definitions/service'
|
||||
unit:
|
||||
$id: 'definitions/unit'
|
||||
type: object
|
||||
description: a name and a flag for services, targets, and others
|
||||
description: a map containing a unit name, an action, and whether it is mandatory
|
||||
additionalProperties: false
|
||||
properties:
|
||||
name: { type: string }
|
||||
action: { type: string, default: "enable" }
|
||||
mandatory: { type: boolean, default: false }
|
||||
required: [ name ]
|
||||
|
||||
additionalProperties: false
|
||||
type: object
|
||||
properties:
|
||||
services: { type: array, items: { $ref: 'definitions/service' } }
|
||||
targets: { type: array, items: { $ref: 'definitions/service' } }
|
||||
timers: { type: array, items: { $ref: 'definitions/service' } }
|
||||
disable: { type: array, items: { $ref: 'definitions/service' } }
|
||||
disable-targets: { type: array, items: { $ref: 'definitions/service' } }
|
||||
mask: { type: array, items: { $ref: 'definitions/service' } }
|
||||
units: { type: array, items: { $ref: 'definitions/unit' } }
|
||||
|
@@ -18,10 +18,9 @@
|
||||
#include "JobQueue.h"
|
||||
#include "utils/Logger.h"
|
||||
#include "utils/String.h"
|
||||
#include "utils/StringExpander.h"
|
||||
#include "utils/Variant.h"
|
||||
|
||||
#include <KMacroExpander>
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QFile>
|
||||
#include <QMetaProperty>
|
||||
@@ -415,20 +414,20 @@ invalidEmpty( const QString& s )
|
||||
STATICTEST QString
|
||||
makeHostnameSuggestion( const QString& templateString, const QStringList& fullNameParts, const QString& loginName )
|
||||
{
|
||||
QHash< QString, QString > replace;
|
||||
Calamares::String::DictionaryExpander d;
|
||||
// User data
|
||||
replace.insert( QStringLiteral( "first" ),
|
||||
invalidEmpty( fullNameParts.isEmpty() ? QString() : cleanupForHostname( fullNameParts.first() ) ) );
|
||||
replace.insert( QStringLiteral( "name" ), invalidEmpty( cleanupForHostname( fullNameParts.join( QString() ) ) ) );
|
||||
replace.insert( QStringLiteral( "login" ), invalidEmpty( cleanupForHostname( loginName ) ) );
|
||||
// Hardware data
|
||||
replace.insert( QStringLiteral( "product" ), guessProductName() );
|
||||
replace.insert( QStringLiteral( "product2" ), cleanupForHostname( QSysInfo::prettyProductName() ) );
|
||||
replace.insert( QStringLiteral( "cpu" ), cleanupForHostname( QSysInfo::currentCpuArchitecture() ) );
|
||||
// Hostname data
|
||||
replace.insert( QStringLiteral( "host" ), invalidEmpty( cleanupForHostname( QSysInfo::machineHostName() ) ) );
|
||||
d.add( QStringLiteral( "first" ),
|
||||
invalidEmpty( fullNameParts.isEmpty() ? QString() : cleanupForHostname( fullNameParts.first() ) ) )
|
||||
.add( QStringLiteral( "name" ), invalidEmpty( cleanupForHostname( fullNameParts.join( QString() ) ) ) )
|
||||
.add( QStringLiteral( "login" ), invalidEmpty( cleanupForHostname( loginName ) ) )
|
||||
// Hardware data
|
||||
.add( QStringLiteral( "product" ), guessProductName() )
|
||||
.add( QStringLiteral( "product2" ), cleanupForHostname( QSysInfo::prettyProductName() ) )
|
||||
.add( QStringLiteral( "cpu" ), cleanupForHostname( QSysInfo::currentCpuArchitecture() ) )
|
||||
// Hostname data
|
||||
.add( QStringLiteral( "host" ), invalidEmpty( cleanupForHostname( QSysInfo::machineHostName() ) ) );
|
||||
|
||||
QString hostnameSuggestion = KMacroExpander::expandMacros( templateString, replace, '$' );
|
||||
QString hostnameSuggestion = d.expand( templateString );
|
||||
|
||||
// RegExp for valid hostnames; if the suggestion produces a valid name, return it
|
||||
static const QRegExp HOSTNAME_RX( "^[a-zA-Z0-9][-a-zA-Z0-9_]*$" );
|
||||
|
@@ -131,7 +131,10 @@ UsersTests::testHostnamed()
|
||||
// root, assume it will succeed.
|
||||
if ( geteuid() != 0 )
|
||||
{
|
||||
QEXPECT_FAIL( "", "Hostname changes are access-controlled", Continue );
|
||||
if ( !setSystemdHostname( QStringLiteral( "tubophone.calamares.io" ) ) )
|
||||
{
|
||||
QEXPECT_FAIL( "", "Hostname changes are access-controlled", Continue );
|
||||
}
|
||||
}
|
||||
QVERIFY( setSystemdHostname( QStringLiteral( "tubophone.calamares.io" ) ) );
|
||||
if ( !m_originalHostName.isEmpty() )
|
||||
|
@@ -1,51 +0,0 @@
|
||||
# === This file is part of Calamares - <https://calamares.io> ===
|
||||
#
|
||||
# SPDX-FileCopyrightText: 2020 Adriaan de Groot <groot@kde.org>
|
||||
# SPDX-License-Identifier: BSD-2-Clause
|
||||
#
|
||||
set(CALA_WEBVIEW_LINK_LIBRARIES "")
|
||||
|
||||
option(WEBVIEW_FORCE_WEBKIT "Always build webview with WebKit instead of WebEngine regardless of Qt version." OFF)
|
||||
|
||||
set(_reason "")
|
||||
|
||||
message(STATUS "Found Qt version ${Qt5Core_VERSION}")
|
||||
if(Qt5Core_VERSION VERSION_LESS 5.6 OR WEBVIEW_FORCE_WEBKIT)
|
||||
message(STATUS " .. using webkit")
|
||||
find_package(Qt5 ${QT_VERSION} CONFIG COMPONENTS WebKit WebKitWidgets)
|
||||
|
||||
if(Qt5WebKit_FOUND AND Qt5WebKitWidgets_FOUND)
|
||||
list(APPEND CALA_WEBVIEW_INCLUDE_DIRECTORIES ${QT_QTWEBKIT_INCLUDE_DIR})
|
||||
list(APPEND CALA_WEBVIEW_LINK_LIBRARIES Qt5::WebKit Qt5::WebKitWidgets)
|
||||
set(WEBVIEW_WITH_WEBKIT 1)
|
||||
else()
|
||||
set(_reason "No suitable WebKit")
|
||||
endif()
|
||||
else()
|
||||
message(STATUS " .. using webengine")
|
||||
find_package(Qt5 ${QT_VERSION} CONFIG COMPONENTS WebEngine WebEngineWidgets)
|
||||
|
||||
if(Qt5WebEngine_FOUND AND Qt5WebEngineWidgets_FOUND)
|
||||
list(APPEND CALA_WEBVIEW_INCLUDE_DIRECTORIES ${QT_QTWEBENGINE_INCLUDE_DIR})
|
||||
list(APPEND CALA_WEBVIEW_LINK_LIBRARIES Qt5::WebEngine Qt5::WebEngineWidgets)
|
||||
set(WEBVIEW_WITH_WEBENGINE 1)
|
||||
else()
|
||||
set(_reason "No suitable WebEngine")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT _reason)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/WebViewConfig.h.in ${CMAKE_CURRENT_BINARY_DIR}/WebViewConfig.h)
|
||||
|
||||
calamares_add_plugin(webview
|
||||
TYPE viewmodule
|
||||
EXPORT_MACRO PLUGINDLLEXPORT_PRO
|
||||
SOURCES
|
||||
WebViewStep.cpp
|
||||
LINK_PRIVATE_LIBRARIES
|
||||
${CALA_WEBVIEW_LINK_LIBRARIES}
|
||||
SHARED_LIB
|
||||
)
|
||||
else()
|
||||
calamares_skip_module( "webview (${_reason})" )
|
||||
endif()
|
@@ -1,10 +0,0 @@
|
||||
/* SPDX-FileCopyrightText: no
|
||||
SPDX-License-Identifier: CC0-1.0
|
||||
*/
|
||||
#ifndef CALAMARESWEBVIEWCONFIG_H
|
||||
#define CALAMARESWEBVIEWCONFIG_H
|
||||
|
||||
#cmakedefine WEBVIEW_WITH_WEBENGINE
|
||||
#cmakedefine WEBVIEW_WITH_WEBKIT
|
||||
|
||||
#endif // CALAMARESWEBVIEWCONFIG_H
|
@@ -1,117 +0,0 @@
|
||||
/* === This file is part of Calamares - <https://calamares.io> ===
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2015 Rohan Garg <rohan@garg.io>
|
||||
* SPDX-FileCopyrightText: 2016 Teo Mrnjavac <teo@kde.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* Calamares is Free Software: see the License-Identifier above.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "WebViewStep.h"
|
||||
|
||||
#include <QVariant>
|
||||
|
||||
#ifdef WEBVIEW_WITH_WEBKIT
|
||||
#include <QWebView>
|
||||
#else
|
||||
#include <QWebEngineView>
|
||||
#include <QtWebEngine>
|
||||
#endif
|
||||
|
||||
CALAMARES_PLUGIN_FACTORY_DEFINITION( WebViewStepFactory, registerPlugin< WebViewStep >(); )
|
||||
|
||||
WebViewStep::WebViewStep( QObject* parent )
|
||||
: Calamares::ViewStep( parent )
|
||||
{
|
||||
emit nextStatusChanged( true );
|
||||
#ifdef WEBVIEW_WITH_WEBENGINE
|
||||
QtWebEngine::initialize();
|
||||
#endif
|
||||
m_view = new WebViewWidget();
|
||||
#ifdef WEBVIEW_WITH_WEBKIT
|
||||
m_view->settings()->setFontFamily( QWebSettings::StandardFont,
|
||||
m_view->settings()->fontFamily( QWebSettings::SansSerifFont ) );
|
||||
m_view->setRenderHints( QPainter::Antialiasing | QPainter::TextAntialiasing | QPainter::SmoothPixmapTransform );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
WebViewStep::~WebViewStep()
|
||||
{
|
||||
if ( m_view && m_view->parent() == nullptr )
|
||||
{
|
||||
m_view->deleteLater();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QString
|
||||
WebViewStep::prettyName() const
|
||||
{
|
||||
return m_prettyName;
|
||||
}
|
||||
|
||||
|
||||
QWidget*
|
||||
WebViewStep::widget()
|
||||
{
|
||||
return m_view;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
WebViewStep::isNextEnabled() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
WebViewStep::isBackEnabled() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
WebViewStep::isAtBeginning() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
WebViewStep::isAtEnd() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
WebViewStep::onActivate()
|
||||
{
|
||||
m_view->load( QUrl( m_url ) );
|
||||
m_view->show();
|
||||
}
|
||||
|
||||
QList< Calamares::job_ptr >
|
||||
WebViewStep::jobs() const
|
||||
{
|
||||
return QList< Calamares::job_ptr >();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
WebViewStep::setConfigurationMap( const QVariantMap& configurationMap )
|
||||
{
|
||||
if ( configurationMap.contains( "url" ) && configurationMap.value( "url" ).type() == QVariant::String )
|
||||
{
|
||||
m_url = configurationMap.value( "url" ).toString();
|
||||
}
|
||||
|
||||
if ( configurationMap.contains( "prettyName" )
|
||||
&& configurationMap.value( "prettyName" ).type() == QVariant::String )
|
||||
{
|
||||
m_prettyName = configurationMap.value( "prettyName" ).toString();
|
||||
}
|
||||
}
|
@@ -1,71 +0,0 @@
|
||||
/* === This file is part of Calamares - <https://calamares.io> ===
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2015 Rohan Garg <rohan@garg.io>
|
||||
* SPDX-FileCopyrightText: 2016 Teo Mrnjavac <teo@kde.org>
|
||||
* SPDX-FileCopyrightText: 2017 Adriaan de Groot <groot@kde.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* Calamares is Free Software: see the License-Identifier above.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef WEBVIEWPLUGIN_H
|
||||
#define WEBVIEWPLUGIN_H
|
||||
|
||||
#include "WebViewConfig.h"
|
||||
|
||||
#include "DllMacro.h"
|
||||
#include "utils/PluginFactory.h"
|
||||
#include "viewpages/ViewStep.h"
|
||||
|
||||
#include <QVariantMap>
|
||||
|
||||
#if defined( WEBVIEW_WITH_WEBKIT ) && defined( WEBVIEW_WITH_WEBENGINE )
|
||||
#error Both WEBENGINE and WEBKIT enabled
|
||||
#endif
|
||||
#if !defined( WEBVIEW_WITH_WEBKIT ) && !defined( WEBVIEW_WITH_WEBENGINE )
|
||||
#error Neither WEBENGINE nor WEBKIT enabled
|
||||
#endif
|
||||
|
||||
#ifdef WEBVIEW_WITH_WEBKIT
|
||||
class QWebView;
|
||||
using WebViewWidget = QWebView;
|
||||
#endif
|
||||
#ifdef WEBVIEW_WITH_WEBENGINE
|
||||
class QWebEngineView;
|
||||
using WebViewWidget = QWebEngineView;
|
||||
#endif
|
||||
|
||||
class PLUGINDLLEXPORT WebViewStep : public Calamares::ViewStep
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit WebViewStep( QObject* parent = nullptr );
|
||||
~WebViewStep() override;
|
||||
|
||||
QString prettyName() const override;
|
||||
|
||||
QWidget* widget() override;
|
||||
|
||||
void onActivate() override;
|
||||
|
||||
bool isNextEnabled() const override;
|
||||
bool isBackEnabled() const override;
|
||||
|
||||
bool isAtBeginning() const override;
|
||||
bool isAtEnd() const override;
|
||||
|
||||
QList< Calamares::job_ptr > jobs() const override;
|
||||
|
||||
void setConfigurationMap( const QVariantMap& configurationMap ) override;
|
||||
|
||||
private:
|
||||
WebViewWidget* m_view;
|
||||
QString m_url;
|
||||
QString m_prettyName;
|
||||
};
|
||||
|
||||
CALAMARES_PLUGIN_FACTORY_DECLARATION( WebViewStepFactory )
|
||||
|
||||
#endif // WEBVIEWPLUGIN_H
|
@@ -1,6 +0,0 @@
|
||||
# SPDX-FileCopyrightText: no
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
#
|
||||
---
|
||||
prettyName: "OwnCloud"
|
||||
url: "https://owncloud.org"
|
@@ -1,6 +0,0 @@
|
||||
# SPDX-FileCopyrightText: no
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
#
|
||||
---
|
||||
prettyName: "Webview"
|
||||
url: "https://calamares.io"
|
@@ -26,7 +26,7 @@
|
||||
|
||||
Config::Config( QObject* parent )
|
||||
: QObject( parent )
|
||||
, m_languages( CalamaresUtils::Locale::availableTranslations() )
|
||||
, m_languages( Calamares::Locale::availableTranslations() )
|
||||
, m_filtermodel( std::make_unique< QSortFilterProxyModel >() )
|
||||
, m_requirementsChecker( std::make_unique< GeneralRequirements >( this ) )
|
||||
{
|
||||
@@ -84,7 +84,7 @@ Config::retranslate()
|
||||
emit warningMessageChanged( m_warningMessage );
|
||||
}
|
||||
|
||||
CalamaresUtils::Locale::TranslationsModel*
|
||||
Calamares::Locale::TranslationsModel*
|
||||
Config::languagesModel() const
|
||||
{
|
||||
return m_languages;
|
||||
@@ -120,7 +120,7 @@ void
|
||||
Config::initLanguages()
|
||||
{
|
||||
// Find the best initial translation
|
||||
CalamaresUtils::Locale::Translation defaultTranslation;
|
||||
Calamares::Locale::Translation defaultTranslation;
|
||||
|
||||
cDebug() << "Trying to match locale" << defaultTranslation.id();
|
||||
int matchedLocaleIndex = m_languages->find( defaultTranslation.id() );
|
||||
@@ -172,7 +172,7 @@ void
|
||||
Config::setCountryCode( const QString& countryCode )
|
||||
{
|
||||
m_countryCode = countryCode;
|
||||
setLocaleIndex( CalamaresUtils::Locale::availableTranslations()->find( m_countryCode ) );
|
||||
setLocaleIndex( Calamares::Locale::availableTranslations()->find( m_countryCode ) );
|
||||
|
||||
emit countryCodeChanged( m_countryCode );
|
||||
}
|
||||
@@ -186,7 +186,7 @@ Config::setLanguageIcon( const QString& languageIcon )
|
||||
void
|
||||
Config::setLocaleIndex( int index )
|
||||
{
|
||||
if ( index == m_localeIndex || index > CalamaresUtils::Locale::availableTranslations()->rowCount( QModelIndex() )
|
||||
if ( index == m_localeIndex || index > Calamares::Locale::availableTranslations()->rowCount( QModelIndex() )
|
||||
|| index < 0 )
|
||||
{
|
||||
return;
|
||||
@@ -347,7 +347,7 @@ setCountry( Config* config, const QString& countryCode, CalamaresUtils::GeoIP::H
|
||||
return;
|
||||
}
|
||||
|
||||
auto c_l = CalamaresUtils::Locale::countryData( countryCode );
|
||||
auto c_l = Calamares::Locale::countryData( countryCode );
|
||||
if ( c_l.first == QLocale::Country::AnyCountry )
|
||||
{
|
||||
cDebug() << "Unusable country code" << countryCode;
|
||||
@@ -356,7 +356,7 @@ setCountry( Config* config, const QString& countryCode, CalamaresUtils::GeoIP::H
|
||||
}
|
||||
else
|
||||
{
|
||||
int r = CalamaresUtils::Locale::availableTranslations()->find( countryCode );
|
||||
int r = Calamares::Locale::availableTranslations()->find( countryCode );
|
||||
if ( r < 0 )
|
||||
{
|
||||
cDebug() << "Unusable country code" << countryCode << "(no suitable translation)";
|
||||
|
@@ -28,7 +28,7 @@ class Config : public QObject
|
||||
* This is a list-model, with names and descriptions for the translations
|
||||
* available to Calamares.
|
||||
*/
|
||||
Q_PROPERTY( CalamaresUtils::Locale::TranslationsModel* languagesModel READ languagesModel CONSTANT FINAL )
|
||||
Q_PROPERTY( Calamares::Locale::TranslationsModel* languagesModel READ languagesModel CONSTANT FINAL )
|
||||
/** @brief The requirements (from modules) and their checked-status
|
||||
*
|
||||
* The model grows rows over time as each module is checked and its
|
||||
@@ -95,7 +95,7 @@ public:
|
||||
QString warningMessage() const;
|
||||
|
||||
public slots:
|
||||
CalamaresUtils::Locale::TranslationsModel* languagesModel() const;
|
||||
Calamares::Locale::TranslationsModel* languagesModel() const;
|
||||
void retranslate();
|
||||
|
||||
///@brief The **global** requirements model, from ModuleManager
|
||||
@@ -122,7 +122,7 @@ signals:
|
||||
private:
|
||||
void initLanguages();
|
||||
|
||||
CalamaresUtils::Locale::TranslationsModel* m_languages = nullptr;
|
||||
Calamares::Locale::TranslationsModel* m_languages = nullptr;
|
||||
std::unique_ptr< QSortFilterProxyModel > m_filtermodel;
|
||||
std::unique_ptr< GeneralRequirements > m_requirementsChecker;
|
||||
|
||||
|
@@ -222,5 +222,5 @@ LocaleTwoColumnDelegate::paint( QPainter* painter, const QStyleOptionViewItem& o
|
||||
Qt::AlignRight | Qt::AlignVCenter,
|
||||
option.palette,
|
||||
false,
|
||||
index.data( CalamaresUtils::Locale::TranslationsModel::EnglishLabelRole ).toString() );
|
||||
index.data( Calamares::Locale::TranslationsModel::EnglishLabelRole ).toString() );
|
||||
}
|
||||
|
@@ -63,7 +63,7 @@ private:
|
||||
|
||||
Ui::WelcomePage* ui;
|
||||
CheckerContainer* m_checkingWidget;
|
||||
CalamaresUtils::Locale::TranslationsModel* m_languages;
|
||||
Calamares::Locale::TranslationsModel* m_languages;
|
||||
|
||||
Config* m_conf;
|
||||
};
|
||||
|
Reference in New Issue
Block a user