Compare commits
56 Commits
loaderqueu
...
artix
| Author | SHA1 | Date | |
|---|---|---|---|
| bc77da0749 | |||
| 1286782422 | |||
| 91712d4f3b | |||
| a163c7d62d | |||
| 3db91dec6a | |||
| 62d997063b | |||
| c7e1783e30 | |||
| bb1212c974 | |||
| 983b9cb68a | |||
| d24d23902c | |||
| efe4b4da71 | |||
| 010ac14221 | |||
|
fcdcc25738
|
|||
|
367995710b
|
|||
| 0f242c944a | |||
| e04b3b69e8 | |||
|
277603cf60
|
|||
|
2cce754737
|
|||
| 23edb4e685 | |||
| 63be1deec3 | |||
| 09edbfeffb | |||
| dd1a91fbbd | |||
| 559daeaa53 | |||
|
8d56cc49df
|
|||
|
80ca6b23eb
|
|||
|
f75efc73a0
|
|||
|
9c0c5ea291
|
|||
| 767a7bac29 | |||
|
3cad76deef
|
|||
|
61ae8c9919
|
|||
| c1a7c4aefb | |||
| 07510419ad | |||
| e48d3912e7 | |||
| 664af6eca5 | |||
| df28217213 | |||
| edcade553c | |||
| cebdcaa19a | |||
| b1e2564198 | |||
| 49424cfeb0 | |||
| 5d0227329a | |||
| f1a447696e | |||
|
|
47cda51f8f | ||
|
|
18e68245c1 | ||
| d8518318d9 | |||
| adaca962ac | |||
| 2681a22b83 | |||
| c32a8b802f | |||
| a391c689e7 | |||
| 787d4c8b5b | |||
| 8816ac53f4 | |||
|
|
51e89e58dd | ||
| 650b048941 | |||
|
|
d8d5a1fb26 | ||
|
|
85f05e8121 | ||
|
|
c28c9b8114 | ||
|
|
935f21ace5 |
3
.gitignore
vendored
@@ -5,3 +5,6 @@
|
||||
build/
|
||||
*.kdev4
|
||||
*.qmlc
|
||||
b.sh
|
||||
modules/netinstall/
|
||||
#modules/packages/
|
||||
|
||||
13
CHANGES
@@ -6,6 +6,19 @@ This is the changelog for Calamares-Extensions. For each release, the major
|
||||
changes and contributors are listed. Note that Calamares-Extensions does not
|
||||
have a historical changelog -- this log starts with version 1.0.0.
|
||||
|
||||
# 3.3.1 (2024-01-15)
|
||||
|
||||
This is the first *calamares-extensions* release to go with a Calamares 3.3
|
||||
release. The extensions now require Calamares 3.3. There is a branch for
|
||||
3.2 legacy support but no releases are planned for it. The main reason
|
||||
for this release is to have a 3.3-compatible release of *-extensions* at all.
|
||||
|
||||
This release contains contributions from (alphabetically by first name):
|
||||
- Adriaan de Groot
|
||||
- Anke Boersma
|
||||
- undef
|
||||
|
||||
|
||||
# 1.3.2 (2023-08-28)
|
||||
|
||||
We skipped a couple of releases in the release-notes, then tagged
|
||||
|
||||
@@ -32,6 +32,9 @@
|
||||
# In this repository, there is just one "group" to which USE_* applies:
|
||||
# USE_os : operating-system-specific modules.
|
||||
#
|
||||
# There is a knob WITH_QT6 which can be used to build against Qt6 rather
|
||||
# than Qt5. This must match what Calamares itself is built with.
|
||||
#
|
||||
### NOTES
|
||||
#
|
||||
# Call this CMake file in script mode, e.g. `cmake -P CMakeLists.txt`
|
||||
@@ -40,7 +43,7 @@
|
||||
#
|
||||
cmake_minimum_required(VERSION 3.16 FATAL_ERROR)
|
||||
|
||||
set( CALAMARES_EXTENSIONS_VERSION 1.4.0 )
|
||||
set( CALAMARES_EXTENSIONS_VERSION 3.3.5 )
|
||||
|
||||
include( ${CMAKE_CURRENT_LIST_DIR}/CMakeModules/ExtendedVersion.cmake )
|
||||
if ( CMAKE_SCRIPT_MODE_FILE )
|
||||
@@ -83,9 +86,11 @@ set_package_properties(
|
||||
# consumers by loading the developer's config from a build
|
||||
# directory (which doesn't have the rest of the config
|
||||
# installed inside it).
|
||||
set( CALAMARES_VERSION_REQUIRED 3.3.0 )
|
||||
set( CALAMARES_VERSION_REQUIRED 3.3.5 )
|
||||
message(STATUS "Looking for Calamares system-wide")
|
||||
find_package(Calamares ${CALAMARES_VERSION_REQUIRED} NO_CMAKE_PACKAGE_REGISTRY)
|
||||
if (NOT TARGET Calamares::calamares OR NOT TARGET Calamares::calamaresui)
|
||||
message(STATUS "Looking for Calamares in the package registry")
|
||||
find_package(Calamares ${CALAMARES_VERSION_REQUIRED} REQUIRED)
|
||||
endif()
|
||||
|
||||
@@ -93,6 +98,32 @@ message(STATUS "Found Calamares version ${Calamares_VERSION}")
|
||||
message(STATUS " libraries ${Calamares_LIB_DIRS}")
|
||||
message(STATUS "")
|
||||
|
||||
### EXTRACTING DEPENDENCIES AND CONFIGURATION FROM CALAMARES
|
||||
#
|
||||
#
|
||||
if(WITH_QT6)
|
||||
set(kfname "KF6")
|
||||
set(KF_VERSION 5.240) # KDE Neon weirdness
|
||||
else()
|
||||
message(STATUS "Building Calamares with Qt5")
|
||||
set(kfname "KF5")
|
||||
set(KF_VERSION 5.78)
|
||||
# API that was deprecated before Qt 5.15 causes a compile error
|
||||
add_compile_definitions(QT_DISABLE_DEPRECATED_BEFORE=0x050f00)
|
||||
endif()
|
||||
|
||||
include( FeatureSummary )
|
||||
find_package(${kfname}CoreAddons ${KF_VERSION} QUIET)
|
||||
set_package_properties(
|
||||
${kfname}CoreAddons
|
||||
PROPERTIES
|
||||
TYPE REQUIRED
|
||||
DESCRIPTION "KDE Framework CoreAddons"
|
||||
URL "https://api.kde.org/frameworks/"
|
||||
PURPOSE "Essential Framework for AboutData and Macros"
|
||||
)
|
||||
|
||||
|
||||
### CMAKE SETUP
|
||||
#
|
||||
# Enable IN_LIST
|
||||
@@ -131,11 +162,18 @@ set(LIST_SKIPPED_MODULES "")
|
||||
calamares_add_module_subdirectory( modules/basestrap LIST_SKIPPED_MODULES )
|
||||
calamares_add_module_subdirectory( modules/services-artix LIST_SKIPPED_MODULES )
|
||||
calamares_add_module_subdirectory( modules/postcfg LIST_SKIPPED_MODULES )
|
||||
calamares_add_module_subdirectory( modules/packagechooser LIST_SKIPPED_MODULES )
|
||||
calamares_add_module_subdirectory( modules/packagechooserq LIST_SKIPPED_MODULES )
|
||||
|
||||
message(STATUS "Calamares extensions ${CALAMARES_EXTENSIONS_VERSION} for Calamares version ${Calamares_VERSION}")
|
||||
|
||||
# If modules cannot be built, they usually call a macro
|
||||
# which builds a list of explanations; show that list.
|
||||
calamares_explain_skipped_modules( ${LIST_SKIPPED_MODULES} )
|
||||
|
||||
install(PROGRAMS scripts/calamares-config-switcher DESTINATION bin)
|
||||
|
||||
if(NOT DEFINED CMAKE_INSTALL_SYSCONFDIR)
|
||||
set(CMAKE_INSTALL_SYSCONFDIR "/etc")
|
||||
endif()
|
||||
|
||||
install(FILES scripts/calamares-config-switcher.conf DESTINATION ${CMAKE_INSTALL_SYSCONFDIR})
|
||||
install(FILES scripts/calamares-config-switcher.desktop DESTINATION ${CMAKE_INSTALL_DATADIR}/applications)
|
||||
|
||||
BIN
branding/artix-next/artix-banner.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 4.4 KiB |
BIN
branding/artix-next/artix-logo.png
Normal file
|
After Width: | Height: | Size: 48 KiB |
205
branding/artix-next/artix-logo.svg
Normal file
@@ -0,0 +1,205 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="46.72533mm"
|
||||
height="46.72533mm"
|
||||
viewBox="0 0 46.72533 46.725331"
|
||||
version="1.1"
|
||||
id="svg4593"
|
||||
inkscape:version="0.92.4 5da689c313, 2019-01-14"
|
||||
sodipodi:docname="Artix_logo_square_frame.svg"
|
||||
inkscape:export-filename="/tmp/Artix_logo_4096.png"
|
||||
inkscape:export-xdpi="2226.6001"
|
||||
inkscape:export-ydpi="2226.6001">
|
||||
<defs
|
||||
id="defs4587">
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient887"
|
||||
id="linearGradient1200-5"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(-1,0,0,1,114.83738,50.597052)"
|
||||
x1="70.512688"
|
||||
y1="62.847496"
|
||||
x2="63.043533"
|
||||
y2="59.204388" />
|
||||
<linearGradient
|
||||
id="linearGradient887"
|
||||
inkscape:collect="always">
|
||||
<stop
|
||||
id="stop883"
|
||||
offset="0"
|
||||
style="stop-color:#ffffff;stop-opacity:0.36470589" />
|
||||
<stop
|
||||
id="stop885"
|
||||
offset="1"
|
||||
style="stop-color:#ffffff;stop-opacity:0" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient887"
|
||||
id="linearGradient1200-8"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(-21.06111,67.884718)"
|
||||
x1="70.512688"
|
||||
y1="62.847496"
|
||||
x2="55.280762"
|
||||
y2="56.393845" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient1849"
|
||||
id="linearGradient1851-9-8-1"
|
||||
x1="70.724701"
|
||||
y1="12.29244"
|
||||
x2="81.157883"
|
||||
y2="19.324032"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(-11.753608,126.58468)" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient1849">
|
||||
<stop
|
||||
style="stop-color:#000000;stop-opacity:0.10217391"
|
||||
offset="0"
|
||||
id="stop1845" />
|
||||
<stop
|
||||
style="stop-color:#000000;stop-opacity:0.30434781"
|
||||
offset="1"
|
||||
id="stop1847" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient1849"
|
||||
id="linearGradient1851-9-8"
|
||||
x1="70.724709"
|
||||
y1="12.29244"
|
||||
x2="87.0924"
|
||||
y2="26.894571"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(-26.40001,101.15201)" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient1849"
|
||||
id="linearGradient1851-9"
|
||||
x1="105.83431"
|
||||
y1="15.35424"
|
||||
x2="80.208908"
|
||||
y2="30.53084"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(-56.382736,115.37787)" />
|
||||
<linearGradient
|
||||
gradientTransform="translate(-16.57152,-7.1090256)"
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient887"
|
||||
id="linearGradient881"
|
||||
x1="75.542618"
|
||||
y1="145.98615"
|
||||
x2="81.200447"
|
||||
y2="143.22675"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="3.1786659"
|
||||
inkscape:cx="55.055788"
|
||||
inkscape:cy="48.998008"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0"
|
||||
inkscape:window-width="1904"
|
||||
inkscape:window-height="1008"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:pagecheckerboard="true"
|
||||
borderlayer="false"
|
||||
inkscape:showpageshadow="true" />
|
||||
<metadata
|
||||
id="metadata4590">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(-23.826174,-99.183391)">
|
||||
<g
|
||||
id="g213"
|
||||
transform="translate(0.57361468)">
|
||||
<path
|
||||
sodipodi:nodetypes="cccccccccccc"
|
||||
style="display:inline;fill:#10a0cc;fill-opacity:1;stroke:none;stroke-width:0.09994879;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 46.614964,99.183394 -8.03465,16.473926 22.112351,12.38944 z m -10.46189,21.450886 -12.3269,25.27444 36.57813,-15.11174 z m 26.955981,12.3672 -11.536252,6.62286 17.831472,6.28438 z"
|
||||
id="path886"
|
||||
inkscape:connector-curvature="0"
|
||||
inkscape:label="Base" />
|
||||
<path
|
||||
style="fill:url(#linearGradient881);fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 58.971096,138.87713 4.137969,-5.87613 6.29521,12.90771 z"
|
||||
id="path947"
|
||||
inkscape:connector-curvature="0"
|
||||
inkscape:label="Light" />
|
||||
<path
|
||||
style="fill:url(#linearGradient1851-9);fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 23.826174,145.90872 25.6254,-15.1766 10.95269,0.065 z"
|
||||
id="path1434-9-4"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccc"
|
||||
inkscape:label="Shadow" />
|
||||
<path
|
||||
style="fill:url(#linearGradient1851-9-8);fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 60.692734,128.04658 -22.11223,-12.38962 5.74419,-2.21251 z"
|
||||
id="path1434-9-4-2"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccc"
|
||||
inkscape:label="Shadow" />
|
||||
<path
|
||||
style="fill:url(#linearGradient1851-9-8-1);fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 69.404275,145.90872 -17.831451,-6.28419 7.398272,-0.7474 z"
|
||||
id="path1434-9-4-2-4"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccc"
|
||||
inkscape:label="Shadow" />
|
||||
<path
|
||||
style="fill:url(#linearGradient1200-8);fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 23.826174,145.90872 25.6254,-15.1766 -13.29865,-10.09774 z"
|
||||
id="path1381-5-9"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccc"
|
||||
inkscape:label="Light" />
|
||||
<path
|
||||
style="fill:url(#linearGradient1200-5);fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 60.692724,128.04658 -16.36803,-14.60213 2.29027,-14.261056 z"
|
||||
id="path1381-5-7"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccc"
|
||||
inkscape:label="Light" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 7.4 KiB |
@@ -8,7 +8,7 @@ welcomeStyleCalamares: false
|
||||
welcomeExpandingLogo: true
|
||||
|
||||
windowExpanding: normal
|
||||
windowSize: 920px,630px
|
||||
windowSize: 1000px,800px
|
||||
windowPlacement: center
|
||||
|
||||
sidebar: qml,top
|
||||
@@ -22,14 +22,15 @@ strings:
|
||||
versionedName: Artix Linux "rolling"
|
||||
shortVersionedName: Artix rolling
|
||||
bootloaderEntryName: Artix
|
||||
productUrl: https://www.artixlinux.org/
|
||||
productUrl: https://artixlinux.org/
|
||||
supportUrl: https://github.com/calamares/calamares/issues
|
||||
knownIssuesUrl: https://calamares.io/about/
|
||||
releaseNotesUrl: https://calamares.io/about/
|
||||
|
||||
images:
|
||||
productLogo: "artix.png"
|
||||
productIcon: "artix.png"
|
||||
productBanner: "artix-banner.png"
|
||||
productLogo: "artix-logo.svg"
|
||||
productIcon: "artix-icon.png"
|
||||
productWelcome: "languages.png"
|
||||
|
||||
slideshow: "show.qml"
|
||||
|
||||
BIN
branding/artix-next/map.png
Normal file
|
After Width: | Height: | Size: 662 KiB |
1487
branding/artix-next/world-map.svg
Normal file
|
After Width: | Height: | Size: 84 KiB |
BIN
branding/artix/artix-banner.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
205
branding/artix/artix-icon.svg
Normal file
@@ -0,0 +1,205 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="46.72533mm"
|
||||
height="46.72533mm"
|
||||
viewBox="0 0 46.72533 46.725331"
|
||||
version="1.1"
|
||||
id="svg4593"
|
||||
inkscape:version="0.92.4 5da689c313, 2019-01-14"
|
||||
sodipodi:docname="Artix_logo_square_frame.svg"
|
||||
inkscape:export-filename="/tmp/Artix_logo_4096.png"
|
||||
inkscape:export-xdpi="2226.6001"
|
||||
inkscape:export-ydpi="2226.6001">
|
||||
<defs
|
||||
id="defs4587">
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient887"
|
||||
id="linearGradient1200-5"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(-1,0,0,1,114.83738,50.597052)"
|
||||
x1="70.512688"
|
||||
y1="62.847496"
|
||||
x2="63.043533"
|
||||
y2="59.204388" />
|
||||
<linearGradient
|
||||
id="linearGradient887"
|
||||
inkscape:collect="always">
|
||||
<stop
|
||||
id="stop883"
|
||||
offset="0"
|
||||
style="stop-color:#ffffff;stop-opacity:0.36470589" />
|
||||
<stop
|
||||
id="stop885"
|
||||
offset="1"
|
||||
style="stop-color:#ffffff;stop-opacity:0" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient887"
|
||||
id="linearGradient1200-8"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(-21.06111,67.884718)"
|
||||
x1="70.512688"
|
||||
y1="62.847496"
|
||||
x2="55.280762"
|
||||
y2="56.393845" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient1849"
|
||||
id="linearGradient1851-9-8-1"
|
||||
x1="70.724701"
|
||||
y1="12.29244"
|
||||
x2="81.157883"
|
||||
y2="19.324032"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(-11.753608,126.58468)" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient1849">
|
||||
<stop
|
||||
style="stop-color:#000000;stop-opacity:0.10217391"
|
||||
offset="0"
|
||||
id="stop1845" />
|
||||
<stop
|
||||
style="stop-color:#000000;stop-opacity:0.30434781"
|
||||
offset="1"
|
||||
id="stop1847" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient1849"
|
||||
id="linearGradient1851-9-8"
|
||||
x1="70.724709"
|
||||
y1="12.29244"
|
||||
x2="87.0924"
|
||||
y2="26.894571"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(-26.40001,101.15201)" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient1849"
|
||||
id="linearGradient1851-9"
|
||||
x1="105.83431"
|
||||
y1="15.35424"
|
||||
x2="80.208908"
|
||||
y2="30.53084"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(-56.382736,115.37787)" />
|
||||
<linearGradient
|
||||
gradientTransform="translate(-16.57152,-7.1090256)"
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient887"
|
||||
id="linearGradient881"
|
||||
x1="75.542618"
|
||||
y1="145.98615"
|
||||
x2="81.200447"
|
||||
y2="143.22675"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="3.1786659"
|
||||
inkscape:cx="55.055788"
|
||||
inkscape:cy="48.998008"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0"
|
||||
inkscape:window-width="1904"
|
||||
inkscape:window-height="1008"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:pagecheckerboard="true"
|
||||
borderlayer="false"
|
||||
inkscape:showpageshadow="true" />
|
||||
<metadata
|
||||
id="metadata4590">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(-23.826174,-99.183391)">
|
||||
<g
|
||||
id="g213"
|
||||
transform="translate(0.57361468)">
|
||||
<path
|
||||
sodipodi:nodetypes="cccccccccccc"
|
||||
style="display:inline;fill:#10a0cc;fill-opacity:1;stroke:none;stroke-width:0.09994879;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 46.614964,99.183394 -8.03465,16.473926 22.112351,12.38944 z m -10.46189,21.450886 -12.3269,25.27444 36.57813,-15.11174 z m 26.955981,12.3672 -11.536252,6.62286 17.831472,6.28438 z"
|
||||
id="path886"
|
||||
inkscape:connector-curvature="0"
|
||||
inkscape:label="Base" />
|
||||
<path
|
||||
style="fill:url(#linearGradient881);fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 58.971096,138.87713 4.137969,-5.87613 6.29521,12.90771 z"
|
||||
id="path947"
|
||||
inkscape:connector-curvature="0"
|
||||
inkscape:label="Light" />
|
||||
<path
|
||||
style="fill:url(#linearGradient1851-9);fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 23.826174,145.90872 25.6254,-15.1766 10.95269,0.065 z"
|
||||
id="path1434-9-4"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccc"
|
||||
inkscape:label="Shadow" />
|
||||
<path
|
||||
style="fill:url(#linearGradient1851-9-8);fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 60.692734,128.04658 -22.11223,-12.38962 5.74419,-2.21251 z"
|
||||
id="path1434-9-4-2"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccc"
|
||||
inkscape:label="Shadow" />
|
||||
<path
|
||||
style="fill:url(#linearGradient1851-9-8-1);fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 69.404275,145.90872 -17.831451,-6.28419 7.398272,-0.7474 z"
|
||||
id="path1434-9-4-2-4"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccc"
|
||||
inkscape:label="Shadow" />
|
||||
<path
|
||||
style="fill:url(#linearGradient1200-8);fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 23.826174,145.90872 25.6254,-15.1766 -13.29865,-10.09774 z"
|
||||
id="path1381-5-9"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccc"
|
||||
inkscape:label="Light" />
|
||||
<path
|
||||
style="fill:url(#linearGradient1200-5);fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 60.692724,128.04658 -16.36803,-14.60213 2.29027,-14.261056 z"
|
||||
id="path1381-5-7"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccc"
|
||||
inkscape:label="Light" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 7.4 KiB |
205
branding/artix/artix-logo.svg
Normal file
@@ -0,0 +1,205 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="46.72533mm"
|
||||
height="46.72533mm"
|
||||
viewBox="0 0 46.72533 46.725331"
|
||||
version="1.1"
|
||||
id="svg4593"
|
||||
inkscape:version="0.92.4 5da689c313, 2019-01-14"
|
||||
sodipodi:docname="Artix_logo_square_frame.svg"
|
||||
inkscape:export-filename="/tmp/Artix_logo_4096.png"
|
||||
inkscape:export-xdpi="2226.6001"
|
||||
inkscape:export-ydpi="2226.6001">
|
||||
<defs
|
||||
id="defs4587">
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient887"
|
||||
id="linearGradient1200-5"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(-1,0,0,1,114.83738,50.597052)"
|
||||
x1="70.512688"
|
||||
y1="62.847496"
|
||||
x2="63.043533"
|
||||
y2="59.204388" />
|
||||
<linearGradient
|
||||
id="linearGradient887"
|
||||
inkscape:collect="always">
|
||||
<stop
|
||||
id="stop883"
|
||||
offset="0"
|
||||
style="stop-color:#ffffff;stop-opacity:0.36470589" />
|
||||
<stop
|
||||
id="stop885"
|
||||
offset="1"
|
||||
style="stop-color:#ffffff;stop-opacity:0" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient887"
|
||||
id="linearGradient1200-8"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(-21.06111,67.884718)"
|
||||
x1="70.512688"
|
||||
y1="62.847496"
|
||||
x2="55.280762"
|
||||
y2="56.393845" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient1849"
|
||||
id="linearGradient1851-9-8-1"
|
||||
x1="70.724701"
|
||||
y1="12.29244"
|
||||
x2="81.157883"
|
||||
y2="19.324032"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(-11.753608,126.58468)" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient1849">
|
||||
<stop
|
||||
style="stop-color:#000000;stop-opacity:0.10217391"
|
||||
offset="0"
|
||||
id="stop1845" />
|
||||
<stop
|
||||
style="stop-color:#000000;stop-opacity:0.30434781"
|
||||
offset="1"
|
||||
id="stop1847" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient1849"
|
||||
id="linearGradient1851-9-8"
|
||||
x1="70.724709"
|
||||
y1="12.29244"
|
||||
x2="87.0924"
|
||||
y2="26.894571"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(-26.40001,101.15201)" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient1849"
|
||||
id="linearGradient1851-9"
|
||||
x1="105.83431"
|
||||
y1="15.35424"
|
||||
x2="80.208908"
|
||||
y2="30.53084"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(-56.382736,115.37787)" />
|
||||
<linearGradient
|
||||
gradientTransform="translate(-16.57152,-7.1090256)"
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient887"
|
||||
id="linearGradient881"
|
||||
x1="75.542618"
|
||||
y1="145.98615"
|
||||
x2="81.200447"
|
||||
y2="143.22675"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="3.1786659"
|
||||
inkscape:cx="55.055788"
|
||||
inkscape:cy="48.998008"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0"
|
||||
inkscape:window-width="1904"
|
||||
inkscape:window-height="1008"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:pagecheckerboard="true"
|
||||
borderlayer="false"
|
||||
inkscape:showpageshadow="true" />
|
||||
<metadata
|
||||
id="metadata4590">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(-23.826174,-99.183391)">
|
||||
<g
|
||||
id="g213"
|
||||
transform="translate(0.57361468)">
|
||||
<path
|
||||
sodipodi:nodetypes="cccccccccccc"
|
||||
style="display:inline;fill:#10a0cc;fill-opacity:1;stroke:none;stroke-width:0.09994879;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 46.614964,99.183394 -8.03465,16.473926 22.112351,12.38944 z m -10.46189,21.450886 -12.3269,25.27444 36.57813,-15.11174 z m 26.955981,12.3672 -11.536252,6.62286 17.831472,6.28438 z"
|
||||
id="path886"
|
||||
inkscape:connector-curvature="0"
|
||||
inkscape:label="Base" />
|
||||
<path
|
||||
style="fill:url(#linearGradient881);fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 58.971096,138.87713 4.137969,-5.87613 6.29521,12.90771 z"
|
||||
id="path947"
|
||||
inkscape:connector-curvature="0"
|
||||
inkscape:label="Light" />
|
||||
<path
|
||||
style="fill:url(#linearGradient1851-9);fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 23.826174,145.90872 25.6254,-15.1766 10.95269,0.065 z"
|
||||
id="path1434-9-4"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccc"
|
||||
inkscape:label="Shadow" />
|
||||
<path
|
||||
style="fill:url(#linearGradient1851-9-8);fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 60.692734,128.04658 -22.11223,-12.38962 5.74419,-2.21251 z"
|
||||
id="path1434-9-4-2"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccc"
|
||||
inkscape:label="Shadow" />
|
||||
<path
|
||||
style="fill:url(#linearGradient1851-9-8-1);fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 69.404275,145.90872 -17.831451,-6.28419 7.398272,-0.7474 z"
|
||||
id="path1434-9-4-2-4"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccc"
|
||||
inkscape:label="Shadow" />
|
||||
<path
|
||||
style="fill:url(#linearGradient1200-8);fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 23.826174,145.90872 25.6254,-15.1766 -13.29865,-10.09774 z"
|
||||
id="path1381-5-9"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccc"
|
||||
inkscape:label="Light" />
|
||||
<path
|
||||
style="fill:url(#linearGradient1200-5);fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 60.692724,128.04658 -16.36803,-14.60213 2.29027,-14.261056 z"
|
||||
id="path1381-5-7"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccc"
|
||||
inkscape:label="Light" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 7.4 KiB |
|
Before Width: | Height: | Size: 70 KiB After Width: | Height: | Size: 144 KiB |
BIN
branding/artix/background.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 6.8 KiB |
@@ -48,7 +48,7 @@ windowExpanding: normal
|
||||
# This setting is ignored if "fullscreen" is selected for
|
||||
# *windowExpanding*, above. If not set, use constants defined
|
||||
# in CalamaresUtilsGui, 800x520.
|
||||
windowSize: 800px,520px
|
||||
windowSize: 1100px,700px
|
||||
|
||||
# Placement of Calamares window. Either "center" or "free".
|
||||
# Whether "center" actually works does depend on the window
|
||||
@@ -162,9 +162,9 @@ strings:
|
||||
#
|
||||
# These filenames can also use substitutions from os-release (see above).
|
||||
images:
|
||||
productBanner: "banner.png"
|
||||
productIcon: "logo.png"
|
||||
productLogo: "logo.png"
|
||||
productBanner: "artix-banner.png"
|
||||
productLogo: "artix-logo.svg"
|
||||
productIcon: "artix-icon.svg"
|
||||
# productWallpaper: "wallpaper.png"
|
||||
productWelcome: "languages.png"
|
||||
|
||||
@@ -216,7 +216,7 @@ slideshow: "show.qml"
|
||||
# the QML components).
|
||||
#
|
||||
# An image slideshow does not need to have the API defined.
|
||||
slideshowAPI: 2
|
||||
slideshowAPI: 1
|
||||
|
||||
|
||||
# These options are to customize online uploading of logs to pastebins:
|
||||
|
||||
|
Before Width: | Height: | Size: 399 KiB After Width: | Height: | Size: 1.1 MiB |
|
Before Width: | Height: | Size: 818 KiB After Width: | Height: | Size: 2.6 MiB |
|
Before Width: | Height: | Size: 151 KiB After Width: | Height: | Size: 332 KiB |
BIN
branding/artix/games.png
Normal file
|
After Width: | Height: | Size: 720 KiB |
BIN
branding/artix/inits.png
Normal file
|
After Width: | Height: | Size: 217 KiB |
|
Before Width: | Height: | Size: 84 KiB After Width: | Height: | Size: 2.7 MiB |
|
Before Width: | Height: | Size: 4.4 KiB |
BIN
branding/artix/map.png
Normal file
|
After Width: | Height: | Size: 662 KiB |
|
Before Width: | Height: | Size: 363 KiB After Width: | Height: | Size: 1.1 MiB |
|
Before Width: | Height: | Size: 359 KiB After Width: | Height: | Size: 957 KiB |
|
Before Width: | Height: | Size: 873 KiB After Width: | Height: | Size: 2.6 MiB |
|
Before Width: | Height: | Size: 1.3 MiB After Width: | Height: | Size: 4.3 MiB |
BIN
branding/artix/packages3.png
Normal file
|
After Width: | Height: | Size: 5.5 MiB |
BIN
branding/artix/packages4.png
Normal file
|
After Width: | Height: | Size: 6.0 MiB |
|
Before Width: | Height: | Size: 502 KiB After Width: | Height: | Size: 1.5 MiB |
|
Before Width: | Height: | Size: 121 KiB After Width: | Height: | Size: 209 KiB |
@@ -27,152 +27,249 @@ Presentation
|
||||
id: presentation
|
||||
|
||||
Timer {
|
||||
interval: 10000
|
||||
interval: 5000
|
||||
running: true
|
||||
repeat: true
|
||||
onTriggered: presentation.goToNextSlide()
|
||||
}
|
||||
|
||||
Slide {
|
||||
Image {
|
||||
source: "background.png"
|
||||
width: parent.width * 4; height: parent.height * 4
|
||||
fillMode: Image.Stretch
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
Image {
|
||||
id: pic0
|
||||
source: "thanks.png"
|
||||
width: parent.width * 1.12; height: parent.height * 1.5
|
||||
fillMode: Image.Stretch
|
||||
fillMode: Image.PreserveAspectFit
|
||||
anchors.centerIn: parent
|
||||
anchors.verticalCenterOffset: -20
|
||||
anchors.verticalCenterOffset: - parent.height / 16
|
||||
}
|
||||
}
|
||||
|
||||
Slide {
|
||||
Image {
|
||||
source: "background.png"
|
||||
width: parent.width * 4; height: parent.height * 4
|
||||
fillMode: Image.Stretch
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
Image {
|
||||
id: pic00
|
||||
source: "artix.png"
|
||||
width: parent.width * 1.12; height: parent.height * 1.5
|
||||
fillMode: Image.Stretch
|
||||
fillMode: Image.PreserveAspectFit
|
||||
anchors.centerIn: parent
|
||||
anchors.verticalCenterOffset: -20
|
||||
anchors.verticalCenterOffset: - parent.height / 16
|
||||
}
|
||||
}
|
||||
|
||||
Slide {
|
||||
Image {
|
||||
source: "background.png"
|
||||
width: parent.width * 4; height: parent.height * 4
|
||||
fillMode: Image.Stretch
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
Image {
|
||||
id: pic02
|
||||
source: "tools.png"
|
||||
width: parent.width * 1.12; height: parent.height * 1.5
|
||||
fillMode: Image.Stretch
|
||||
fillMode: Image.PreserveAspectFit
|
||||
anchors.centerIn: parent
|
||||
anchors.verticalCenterOffset: -20
|
||||
anchors.verticalCenterOffset: - parent.height / 16
|
||||
}
|
||||
}
|
||||
|
||||
Slide {
|
||||
Image {
|
||||
source: "background.png"
|
||||
width: parent.width * 4; height: parent.height * 4
|
||||
fillMode: Image.Stretch
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
Image {
|
||||
id: pic03
|
||||
source: "desktops.png"
|
||||
width: parent.width * 1.12; height: parent.height * 1.5
|
||||
fillMode: Image.Stretch
|
||||
fillMode: Image.PreserveAspectFit
|
||||
anchors.centerIn: parent
|
||||
anchors.verticalCenterOffset: -20
|
||||
anchors.verticalCenterOffset: - parent.height / 16
|
||||
}
|
||||
}
|
||||
|
||||
Slide {
|
||||
Image {
|
||||
source: "background.png"
|
||||
width: parent.width * 4; height: parent.height * 4
|
||||
fillMode: Image.Stretch
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
Image {
|
||||
id: pic04
|
||||
source: "productivity.png"
|
||||
width: parent.width * 1.12; height: parent.height * 1.5
|
||||
fillMode: Image.Stretch
|
||||
fillMode: Image.PreserveAspectFit
|
||||
anchors.centerIn: parent
|
||||
anchors.verticalCenterOffset: -20
|
||||
anchors.verticalCenterOffset: - parent.height / 16
|
||||
}
|
||||
}
|
||||
|
||||
Slide {
|
||||
Image {
|
||||
source: "background.png"
|
||||
width: parent.width * 4; height: parent.height * 4
|
||||
fillMode: Image.Stretch
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
Image {
|
||||
id: pic06
|
||||
source: "browsers.png"
|
||||
width: parent.width * 1.12; height: parent.height * 1.5
|
||||
fillMode: Image.Stretch
|
||||
fillMode: Image.PreserveAspectFit
|
||||
anchors.centerIn: parent
|
||||
anchors.verticalCenterOffset: -20
|
||||
anchors.verticalCenterOffset: - parent.height / 16
|
||||
}
|
||||
}
|
||||
|
||||
Slide {
|
||||
Image {
|
||||
source: "background.png"
|
||||
width: parent.width * 4; height: parent.height * 4
|
||||
fillMode: Image.Stretch
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
Image {
|
||||
id: pic07
|
||||
source: "office.png"
|
||||
width: parent.width * 1.12; height: parent.height * 1.5
|
||||
fillMode: Image.Stretch
|
||||
fillMode: Image.PreserveAspectFit
|
||||
anchors.centerIn: parent
|
||||
anchors.verticalCenterOffset: -20
|
||||
anchors.verticalCenterOffset: - parent.height / 16
|
||||
}
|
||||
}
|
||||
|
||||
Slide {
|
||||
Image {
|
||||
source: "background.png"
|
||||
width: parent.width * 4; height: parent.height * 4
|
||||
fillMode: Image.Stretch
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
Image {
|
||||
id: pic08
|
||||
source: "multimedia.png"
|
||||
width: parent.width * 1.12; height: parent.height * 1.5
|
||||
fillMode: Image.Stretch
|
||||
fillMode: Image.PreserveAspectFit
|
||||
anchors.centerIn: parent
|
||||
anchors.verticalCenterOffset: -20
|
||||
anchors.verticalCenterOffset: - parent.height / 16
|
||||
}
|
||||
}
|
||||
|
||||
Slide {
|
||||
Image {
|
||||
source: "background.png"
|
||||
width: parent.width * 4; height: parent.height * 4
|
||||
fillMode: Image.Stretch
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
Image {
|
||||
id: pic09
|
||||
source: "web.png"
|
||||
width: parent.width * 1.12; height: parent.height * 1.5
|
||||
fillMode: Image.Stretch
|
||||
fillMode: Image.PreserveAspectFit
|
||||
anchors.centerIn: parent
|
||||
anchors.verticalCenterOffset: -20
|
||||
anchors.verticalCenterOffset: - parent.height / 16
|
||||
}
|
||||
}
|
||||
|
||||
Slide {
|
||||
Image {
|
||||
source: "background.png"
|
||||
width: parent.width * 4; height: parent.height * 4
|
||||
fillMode: Image.Stretch
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
Image {
|
||||
id: pic11
|
||||
source: "packages1.png"
|
||||
width: parent.width * 1.12; height: parent.height * 1.5
|
||||
fillMode: Image.Stretch
|
||||
fillMode: Image.PreserveAspectFit
|
||||
anchors.centerIn: parent
|
||||
anchors.verticalCenterOffset: -20
|
||||
anchors.verticalCenterOffset: - parent.height / 16
|
||||
}
|
||||
}
|
||||
|
||||
Slide {
|
||||
Image {
|
||||
source: "background.png"
|
||||
width: parent.width * 4; height: parent.height * 4
|
||||
fillMode: Image.Stretch
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
Image {
|
||||
id: pic13
|
||||
source: "packages2.png"
|
||||
width: parent.width * 1.12; height: parent.height * 1.5
|
||||
fillMode: Image.Stretch
|
||||
fillMode: Image.PreserveAspectFit
|
||||
anchors.centerIn: parent
|
||||
anchors.verticalCenterOffset: -20
|
||||
anchors.verticalCenterOffset: - parent.height / 16
|
||||
}
|
||||
}
|
||||
|
||||
Slide {
|
||||
Image {
|
||||
source: "background.png"
|
||||
width: parent.width * 4; height: parent.height * 4
|
||||
fillMode: Image.Stretch
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
Image {
|
||||
source: "packages3.png"
|
||||
width: parent.width * 1.12; height: parent.height * 1.5
|
||||
fillMode: Image.PreserveAspectFit
|
||||
anchors.centerIn: parent
|
||||
anchors.verticalCenterOffset: - parent.height / 16
|
||||
}
|
||||
}
|
||||
|
||||
Slide {
|
||||
Image {
|
||||
source: "background.png"
|
||||
width: parent.width * 4; height: parent.height * 4
|
||||
fillMode: Image.Stretch
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
Image {
|
||||
source: "packages4.png"
|
||||
width: parent.width * 1.12; height: parent.height * 1.5
|
||||
fillMode: Image.PreserveAspectFit
|
||||
anchors.centerIn: parent
|
||||
anchors.verticalCenterOffset: - parent.height / 16
|
||||
}
|
||||
}
|
||||
|
||||
Slide {
|
||||
Image {
|
||||
source: "background.png"
|
||||
width: parent.width * 4; height: parent.height * 4
|
||||
fillMode: Image.Stretch
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
Image {
|
||||
id: pic15
|
||||
source: "customise.png"
|
||||
width: parent.width * 1.12; height: parent.height * 1.5
|
||||
fillMode: Image.Stretch
|
||||
fillMode: Image.PreserveAspectFit
|
||||
anchors.centerIn: parent
|
||||
anchors.verticalCenterOffset: -20
|
||||
anchors.verticalCenterOffset: - parent.height / 16
|
||||
}
|
||||
}
|
||||
|
||||
Slide {
|
||||
Image {
|
||||
id: pic16
|
||||
source: "rolling.png"
|
||||
width: parent.width * 1.12; height: parent.height * 1.5
|
||||
Image {
|
||||
source: "background.png"
|
||||
width: parent.width * 4; height: parent.height * 4
|
||||
fillMode: Image.Stretch
|
||||
anchors.centerIn: parent
|
||||
anchors.verticalCenterOffset: -20
|
||||
}
|
||||
Image {
|
||||
source: "rolling.png"
|
||||
width: parent.width * 1.12; height: parent.height * 1.5
|
||||
fillMode: Image.PreserveAspectFit
|
||||
anchors.centerIn: parent
|
||||
anchors.verticalCenterOffset: - parent.height / 16
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 75 KiB After Width: | Height: | Size: 157 KiB |
BIN
branding/artix/theme.png
Normal file
|
After Width: | Height: | Size: 1.0 MiB |
|
Before Width: | Height: | Size: 160 KiB After Width: | Height: | Size: 364 KiB |
|
Before Width: | Height: | Size: 136 KiB After Width: | Height: | Size: 300 KiB |
@@ -43,6 +43,8 @@ backend: dummy
|
||||
# when set to true. If missing, false is assumed.
|
||||
# *copy_pacconf* is a boolean that includes copying the host's pacman.conf
|
||||
# to the install root. If missing, false is assumed.
|
||||
# *requirements* filesystem requirements to install base
|
||||
# *keyrings* list of keyrings to initialize and populate
|
||||
|
||||
pacman:
|
||||
num_retries: 0
|
||||
@@ -51,27 +53,68 @@ pacman:
|
||||
handle_keyrings: false
|
||||
copy_pacconf: false
|
||||
requirements:
|
||||
- name: /etc
|
||||
- dest: /etc
|
||||
mode: "0o755"
|
||||
- name: /var
|
||||
- dest: /var
|
||||
mode: "0o755"
|
||||
- name: /var/cache
|
||||
- dest: /var/cache
|
||||
mode: "0o755"
|
||||
- name: /var/cache/pacman
|
||||
- dest: /var/cache/pacman
|
||||
mode: "0o755"
|
||||
- name: /var/cache/pacman/pkg
|
||||
- dest: /var/cache/pacman/pkg
|
||||
mode: "0o755"
|
||||
- name: /var/lib
|
||||
- dest: /var/lib
|
||||
mode: "0o755"
|
||||
- name: /var/lib/pacman
|
||||
- dest: /var/lib/pacman
|
||||
mode: "0o755"
|
||||
keyrings:
|
||||
- artix
|
||||
|
||||
|
||||
# the artix base package allows selection of the init system tied to elogind
|
||||
# this option is artix specific
|
||||
# base_init: elogind
|
||||
|
||||
|
||||
# List of maps with package operations such as install or remove.
|
||||
# Distro developers can provide a list of packages to remove
|
||||
# from the installed system (for instance packages meant only
|
||||
# for the live system).
|
||||
#
|
||||
# A job implementing a distro specific logic to determine other
|
||||
# packages that need to be installed or removed can run before
|
||||
# this one. Distro developers may want to install locale packages
|
||||
# or remove drivers not needed on the installed system.
|
||||
# Such a job would populate a list of dictionaries in the global
|
||||
# storage called "packageOperations" and that list is processed
|
||||
# after the static list in the job configuration (i.e. the list
|
||||
# that is in this configuration file).
|
||||
#
|
||||
# Allowed package operations are:
|
||||
# - *install*, *try_install*: will call the package manager to
|
||||
# install one or more packages. The install target will
|
||||
# abort the whole installation if package-installation
|
||||
# fails, while try_install carries on. Packages may be
|
||||
# listed as (localized) names, or as (localized) package-data.
|
||||
# See below for the description of the format.
|
||||
# - *localInstall*: this is used to call the package manager
|
||||
# to install a package from a path-to-a-package. This is
|
||||
# useful if you have a static package archive on the install media.
|
||||
# The *pacman* package manager is the only one to specially support
|
||||
# this operation (all others treat this the same as *install*).
|
||||
# - *remove*, *try_remove*: will call the package manager to
|
||||
# remove one or more packages. The remove target will
|
||||
# abort the whole installation if package-removal fails,
|
||||
# while try_remove carries on. Packages may be listed as
|
||||
# (localized) names.
|
||||
# One additional key is recognized, to help netinstall out:
|
||||
# - *source*: ignored, does get logged
|
||||
# Any other key is ignored, and logged as a warning.
|
||||
#
|
||||
# There are two formats for naming packages: as a name or as package-data,
|
||||
# which is an object notation providing package-name, as well as pre- and
|
||||
# post-install scripts.
|
||||
|
||||
operations:
|
||||
- install:
|
||||
- base
|
||||
|
||||
@@ -239,6 +239,23 @@ class PackageManager(metaclass=abc.ABCMeta):
|
||||
# even the Dummy implementation.
|
||||
#
|
||||
|
||||
class PMDummy(PackageManager):
|
||||
backend = "dummy"
|
||||
|
||||
def install(self, pkgs, from_local=False):
|
||||
from time import sleep
|
||||
libcalamares.utils.debug("Dummy backend: Installing " + str(pkgs))
|
||||
sleep(3)
|
||||
|
||||
def remove(self, pkgs):
|
||||
from time import sleep
|
||||
libcalamares.utils.debug("Dummy backend: Removing " + str(pkgs))
|
||||
sleep(3)
|
||||
|
||||
def run(self, script):
|
||||
libcalamares.utils.debug("Dummy backend: Running script '" + str(script) + "'")
|
||||
|
||||
|
||||
class PMPacman(PackageManager):
|
||||
backend = "pacman"
|
||||
|
||||
@@ -310,29 +327,13 @@ class PMPacman(PackageManager):
|
||||
|
||||
install_root = libcalamares.globalstorage.value("rootMountPoint")
|
||||
|
||||
cal_umask = os.umask(0)
|
||||
for target in self.pacman_requirements:
|
||||
dest = install_root + target["name"]
|
||||
if not os.path.exists(dest):
|
||||
mod = int(target["mode"],8)
|
||||
os.mkdir(dest, mode=mod)
|
||||
libcalamares.utils.debug("Mode: {!s}".format(oct(mod)))
|
||||
libcalamares.utils.debug("Created: {!s}".format(dest))
|
||||
self.setup_requirements(install_root)
|
||||
|
||||
path = join(install_root, "run")
|
||||
os.chmod(path, 0o755)
|
||||
os.umask(cal_umask)
|
||||
|
||||
f = "etc/resolv.conf"
|
||||
if os.path.exists(join("/",f)):
|
||||
shutil.copy2(join("/",f), join(install_root, f))
|
||||
self.copy_file(install_root, "etc/resolv.conf")
|
||||
|
||||
command = ["pacman"]
|
||||
|
||||
cachedir = join(install_root, "var/cache/pacman/pkg")
|
||||
dbdir = join(install_root, "var/lib/pacman")
|
||||
pacman_args = ["--root", install_root, "--dbpath", dbdir, "--cachedir", cachedir]
|
||||
command.extend(pacman_args)
|
||||
command.extend(self.get_optargs(install_root))
|
||||
|
||||
# Don't ask for user intervention, take the default action
|
||||
command.append("--noconfirm")
|
||||
@@ -340,10 +341,10 @@ class PMPacman(PackageManager):
|
||||
# Don't report download progress for each file
|
||||
command.append("--noprogressbar")
|
||||
|
||||
if self.pacman_needed_only is True:
|
||||
if self.pacman_needed_only:
|
||||
command.append("--needed")
|
||||
|
||||
if self.pacman_disable_timeout is True:
|
||||
if self.pacman_disable_timeout:
|
||||
command.append("--disable-download-timeout")
|
||||
|
||||
if from_local:
|
||||
@@ -363,14 +364,36 @@ class PMPacman(PackageManager):
|
||||
self.populate_keyring()
|
||||
|
||||
if self.pacman_pacconf:
|
||||
f = "etc/pacman.conf"
|
||||
if os.path.exists(join("/",f)):
|
||||
shutil.copy2(join("/",f), join(install_root, f))
|
||||
self.copy_file(install_root, "etc/pacman.conf")
|
||||
|
||||
def remove(self, pkgs):
|
||||
self.reset_progress()
|
||||
self.run_pacman(["pacman", "-Rs", "--noconfirm"] + pkgs, True)
|
||||
|
||||
def get_optargs(self, rootdir):
|
||||
cachedir = join(rootdir, "var/cache/pacman/pkg")
|
||||
dbpath = join(rootdir, "var/lib/pacman")
|
||||
args = ["--root", rootdir, "--dbpath", dbpath, "--cachedir", cachedir]
|
||||
return args
|
||||
|
||||
def setup_requirements(self, rootdir):
|
||||
cal_umask = os.umask(0)
|
||||
for target in self.pacman_requirements:
|
||||
dest = rootdir + target["dest"]
|
||||
if not os.path.exists(dest):
|
||||
mod = int(target["mode"],8)
|
||||
os.mkdir(dest, mode=mod)
|
||||
libcalamares.utils.debug("Mode: {!s}".format(oct(mod)))
|
||||
libcalamares.utils.debug("Created: {!s}".format(dest))
|
||||
|
||||
path = join(rootdir, "run")
|
||||
os.chmod(path, 0o755)
|
||||
os.umask(cal_umask)
|
||||
|
||||
def copy_file(self, rootdir, f):
|
||||
if os.path.exists(join("/",f)):
|
||||
shutil.copy2(join("/",f), join(rootdir, f))
|
||||
|
||||
def init_keyring(self):
|
||||
target_env_process_output(["pacman-key", "--init"])
|
||||
|
||||
@@ -492,16 +515,14 @@ def run():
|
||||
if identifier == backend:
|
||||
pkgman = impl()
|
||||
break
|
||||
else:
|
||||
return "Bad backend", "backend=\"{}\"".format(backend)
|
||||
else:
|
||||
return "Bad backend", "backend=\"{}\"".format(backend)
|
||||
|
||||
if not libcalamares.globalstorage.value("hasInternet"):
|
||||
libcalamares.utils.warning( "Package installation has been skipped: no internet" )
|
||||
return None
|
||||
|
||||
operations = libcalamares.job.configuration.get("operations", [])
|
||||
# if libcalamares.globalstorage.contains("packageOperations"):
|
||||
# operations += libcalamares.globalstorage.value("packageOperations")
|
||||
|
||||
if libcalamares.job.configuration.get("base_init"):
|
||||
base_init = libcalamares.job.configuration.get("base_init", None)
|
||||
|
||||
@@ -1,68 +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
|
||||
#
|
||||
find_package(${qtname} COMPONENTS Core Gui Widgets REQUIRED)
|
||||
set(_extra_libraries "")
|
||||
set(_extra_src "")
|
||||
|
||||
### OPTIONAL AppData XML support in PackageModel
|
||||
#
|
||||
#
|
||||
option(BUILD_APPDATA "Support appdata: items in PackageChooser (requires QtXml)" ON)
|
||||
if(BUILD_APPDATA)
|
||||
find_package(${qtname} COMPONENTS Xml)
|
||||
if(TARGET ${qtname}::Xml)
|
||||
add_definitions(-DHAVE_APPDATA)
|
||||
list(APPEND _extra_libraries ${qtname}::Xml)
|
||||
list(APPEND _extra_src ItemAppData.cpp)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
### OPTIONAL AppStream support in PackageModel
|
||||
#
|
||||
#
|
||||
option(BUILD_APPSTREAM "Support appstream: items in PackageChooser (requires libappstream-qt)" ON)
|
||||
if(BUILD_APPSTREAM)
|
||||
find_package(AppStreamQt)
|
||||
set_package_properties(
|
||||
AppStreamQt
|
||||
PROPERTIES
|
||||
DESCRIPTION "Support for AppStream (cache) data"
|
||||
URL "https://github.com/ximion/appstream"
|
||||
PURPOSE "AppStream provides package data"
|
||||
TYPE OPTIONAL
|
||||
)
|
||||
if(AppStreamQt_FOUND)
|
||||
add_definitions(-DHAVE_APPSTREAM_VERSION=${AppStreamQt_VERSION_MAJOR})
|
||||
list(APPEND _extra_libraries AppStreamQt)
|
||||
list(APPEND _extra_src ItemAppStream.cpp)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
calamares_add_plugin(packagechooser
|
||||
TYPE viewmodule
|
||||
EXPORT_MACRO PLUGINDLLEXPORT_PRO
|
||||
SOURCES
|
||||
Config.cpp
|
||||
PackageChooserPage.cpp
|
||||
PackageChooserViewStep.cpp
|
||||
PackageModel.cpp
|
||||
${_extra_src}
|
||||
RESOURCES
|
||||
packagechooser.qrc
|
||||
UI
|
||||
page_package.ui
|
||||
LINK_PRIVATE_LIBRARIES
|
||||
${_extra_libraries}
|
||||
SHARED_LIB
|
||||
)
|
||||
|
||||
# include(CalamaresAddTest)
|
||||
# calamares_add_test(
|
||||
# packagechoosertest
|
||||
# GUI
|
||||
# SOURCES Tests.cpp
|
||||
# LIBRARIES calamares_viewmodule_packagechooser ${_extra_libraries}
|
||||
# )
|
||||
@@ -1,361 +0,0 @@
|
||||
/* === This file is part of Calamares - <https://calamares.io> ===
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2021 Adriaan de Groot <groot@kde.org>
|
||||
* SPDX-FileCopyrightText: 2021 Anke Boersma <demm@kaosx.us>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* Calamares is Free Software: see the License-Identifier above.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "Config.h"
|
||||
|
||||
#ifdef HAVE_APPDATA
|
||||
#include "ItemAppData.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_APPSTREAM_VERSION
|
||||
#include "ItemAppStream.h"
|
||||
#include <AppStreamQt/pool.h>
|
||||
#include <memory>
|
||||
#endif
|
||||
|
||||
#include "GlobalStorage.h"
|
||||
#include "JobQueue.h"
|
||||
#include "compat/Variant.h"
|
||||
#include "packages/Globals.h"
|
||||
#include "utils/Logger.h"
|
||||
#include "utils/Variant.h"
|
||||
|
||||
/** @brief This removes any values from @p groups that match @p source
|
||||
*
|
||||
* This is used to remove duplicates from the netinstallAdd structure
|
||||
* It iterates over @p groups and for each map in the list, if the
|
||||
* "source" element matches @p source, it is removed from the returned
|
||||
* list.
|
||||
*/
|
||||
static QVariantList
|
||||
pruneNetinstallAdd( const QString& source, const QVariant& groups )
|
||||
{
|
||||
QVariantList newGroupList;
|
||||
const QVariantList groupList = groups.toList();
|
||||
for ( const QVariant& group : groupList )
|
||||
{
|
||||
QVariantMap groupMap = group.toMap();
|
||||
if ( groupMap.value( "source", "" ).toString() != source )
|
||||
{
|
||||
newGroupList.append( groupMap );
|
||||
}
|
||||
}
|
||||
return newGroupList;
|
||||
}
|
||||
|
||||
const NamedEnumTable< PackageChooserMode >&
|
||||
packageChooserModeNames()
|
||||
{
|
||||
static const NamedEnumTable< PackageChooserMode > names {
|
||||
{ "optional", PackageChooserMode::Optional },
|
||||
{ "required", PackageChooserMode::Required },
|
||||
{ "optionalmultiple", PackageChooserMode::OptionalMultiple },
|
||||
{ "requiredmultiple", PackageChooserMode::RequiredMultiple },
|
||||
// and a bunch of aliases
|
||||
{ "zero-or-one", PackageChooserMode::Optional },
|
||||
{ "radio", PackageChooserMode::Required },
|
||||
{ "one", PackageChooserMode::Required },
|
||||
{ "set", PackageChooserMode::OptionalMultiple },
|
||||
{ "zero-or-more", PackageChooserMode::OptionalMultiple },
|
||||
{ "multiple", PackageChooserMode::RequiredMultiple },
|
||||
{ "one-or-more", PackageChooserMode::RequiredMultiple }
|
||||
};
|
||||
return names;
|
||||
}
|
||||
|
||||
const NamedEnumTable< PackageChooserMethod >&
|
||||
PackageChooserMethodNames()
|
||||
{
|
||||
static const NamedEnumTable< PackageChooserMethod > names {
|
||||
{ "legacy", PackageChooserMethod::Legacy },
|
||||
{ "custom", PackageChooserMethod::Legacy },
|
||||
{ "contextualprocess", PackageChooserMethod::Legacy },
|
||||
{ "packages", PackageChooserMethod::Packages },
|
||||
{ "netinstall-add", PackageChooserMethod::NetAdd },
|
||||
{ "netinstall-select", PackageChooserMethod::NetSelect },
|
||||
};
|
||||
return names;
|
||||
}
|
||||
|
||||
Config::Config( QObject* parent )
|
||||
: Calamares::ModuleSystem::Config( parent )
|
||||
, m_model( new PackageListModel( this ) )
|
||||
, m_mode( PackageChooserMode::Required )
|
||||
{
|
||||
}
|
||||
|
||||
Config::~Config() {}
|
||||
|
||||
const PackageItem&
|
||||
Config::introductionPackage() const
|
||||
{
|
||||
for ( int i = 0; i < m_model->packageCount(); ++i )
|
||||
{
|
||||
const auto& package = m_model->packageData( i );
|
||||
if ( package.isNonePackage() )
|
||||
{
|
||||
return package;
|
||||
}
|
||||
}
|
||||
|
||||
static PackageItem* defaultIntroduction = nullptr;
|
||||
if ( !defaultIntroduction )
|
||||
{
|
||||
const auto name = QT_TR_NOOP( "Package Selection" );
|
||||
const auto description
|
||||
= QT_TR_NOOP( "Please pick a product from the list. The selected product will be installed." );
|
||||
defaultIntroduction = new PackageItem( QString(), name, description );
|
||||
defaultIntroduction->screenshot = QPixmap( QStringLiteral( ":/images/no-selection.png" ) );
|
||||
defaultIntroduction->name = Calamares::Locale::TranslatedString( name, metaObject()->className() );
|
||||
defaultIntroduction->description
|
||||
= Calamares::Locale::TranslatedString( description, metaObject()->className() );
|
||||
}
|
||||
return *defaultIntroduction;
|
||||
}
|
||||
|
||||
static inline QString
|
||||
make_gs_key( const Calamares::ModuleSystem::InstanceKey& key )
|
||||
{
|
||||
return QStringLiteral( "packagechooser_" ) + key.id();
|
||||
}
|
||||
|
||||
void
|
||||
Config::updateGlobalStorage( const QStringList& selected ) const
|
||||
{
|
||||
if ( m_packageChoice.has_value() )
|
||||
{
|
||||
cWarning() << "Inconsistent package choices -- both model and single-selection QML";
|
||||
}
|
||||
if ( m_method == PackageChooserMethod::Legacy )
|
||||
{
|
||||
QString value = selected.join( ',' );
|
||||
Calamares::JobQueue::instance()->globalStorage()->insert( make_gs_key( m_defaultId ), value );
|
||||
cDebug() << m_defaultId << "selected" << value;
|
||||
}
|
||||
else if ( m_method == PackageChooserMethod::Packages )
|
||||
{
|
||||
QStringList packageNames = m_model->getInstallPackagesForNames( selected );
|
||||
cDebug() << m_defaultId << "packages to install" << packageNames;
|
||||
Calamares::Packages::setGSPackageAdditions(
|
||||
Calamares::JobQueue::instance()->globalStorage(), m_defaultId, packageNames );
|
||||
}
|
||||
else if ( m_method == PackageChooserMethod::NetAdd )
|
||||
{
|
||||
QVariantList netinstallDataList = m_model->getNetinstallDataForNames( selected );
|
||||
if ( netinstallDataList.isEmpty() )
|
||||
{
|
||||
cWarning() << "No netinstall information found for " << selected;
|
||||
}
|
||||
else
|
||||
{
|
||||
// If an earlier packagechooser instance added this data to global storage, combine them
|
||||
auto* gs = Calamares::JobQueue::instance()->globalStorage();
|
||||
if ( gs->contains( "netinstallAdd" ) )
|
||||
{
|
||||
netinstallDataList
|
||||
+= pruneNetinstallAdd( QStringLiteral( "packageChooser" ), gs->value( "netinstallAdd" ) );
|
||||
}
|
||||
gs->insert( "netinstallAdd", netinstallDataList );
|
||||
}
|
||||
}
|
||||
else if ( m_method == PackageChooserMethod::NetSelect )
|
||||
{
|
||||
cDebug() << m_defaultId << "groups to select in netinstall" << selected;
|
||||
QStringList newSelected = selected;
|
||||
auto* gs = Calamares::JobQueue::instance()->globalStorage();
|
||||
|
||||
// If an earlier packagechooser instance added this data to global storage, combine them
|
||||
if ( gs->contains( "netinstallSelect" ) )
|
||||
{
|
||||
auto selectedOrig = gs->value( "netinstallSelect" );
|
||||
if ( selectedOrig.canConvert< QStringList >() )
|
||||
{
|
||||
newSelected += selectedOrig.toStringList();
|
||||
}
|
||||
else
|
||||
{
|
||||
cWarning() << "Invalid NetinstallSelect data in global storage. Earlier selections purged";
|
||||
}
|
||||
gs->remove( "netinstallSelect" );
|
||||
}
|
||||
gs->insert( "netinstallSelect", newSelected );
|
||||
}
|
||||
else
|
||||
{
|
||||
cWarning() << "Unknown packagechooser method" << smash( m_method );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Config::updateGlobalStorage() const
|
||||
{
|
||||
if ( m_model->packageCount() > 0 )
|
||||
{
|
||||
cWarning() << "Inconsistent package choices -- both model and single-selection QML";
|
||||
}
|
||||
if ( m_method == PackageChooserMethod::Legacy )
|
||||
{
|
||||
auto* gs = Calamares::JobQueue::instance()->globalStorage();
|
||||
if ( m_packageChoice.has_value() )
|
||||
{
|
||||
gs->insert( make_gs_key( m_defaultId ), m_packageChoice.value() );
|
||||
}
|
||||
else
|
||||
{
|
||||
gs->remove( make_gs_key( m_defaultId ) );
|
||||
}
|
||||
}
|
||||
else if ( m_method == PackageChooserMethod::Packages )
|
||||
{
|
||||
cWarning() << "Unsupported single-selection packagechooser method 'Packages'";
|
||||
}
|
||||
else
|
||||
{
|
||||
cWarning() << "Unknown packagechooser method" << smash( m_method );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Config::setPackageChoice( const QString& packageChoice )
|
||||
{
|
||||
if ( packageChoice.isEmpty() )
|
||||
{
|
||||
m_packageChoice.reset();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_packageChoice = packageChoice;
|
||||
}
|
||||
emit packageChoiceChanged( m_packageChoice.value_or( QString() ) );
|
||||
}
|
||||
|
||||
QString
|
||||
Config::prettyName() const
|
||||
{
|
||||
return m_stepName ? m_stepName->get() : tr( "Packages" );
|
||||
}
|
||||
|
||||
QString
|
||||
Config::prettyStatus() const
|
||||
{
|
||||
return tr( "Install option: <strong>%1</strong>" ).arg( m_packageChoice.value_or( tr( "None" ) ) );
|
||||
}
|
||||
|
||||
static void
|
||||
fillModel( PackageListModel* model, const QVariantList& items )
|
||||
{
|
||||
if ( items.isEmpty() )
|
||||
{
|
||||
cWarning() << "No *items* for PackageChooser module.";
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef HAVE_APPSTREAM_VERSION
|
||||
std::unique_ptr< AppStream::Pool > pool;
|
||||
bool poolOk = false;
|
||||
#endif
|
||||
|
||||
cDebug() << "Loading PackageChooser model items from config";
|
||||
int item_index = 0;
|
||||
for ( const auto& item_it : items )
|
||||
{
|
||||
++item_index;
|
||||
QVariantMap item_map = item_it.toMap();
|
||||
if ( item_map.isEmpty() )
|
||||
{
|
||||
cWarning() << "PackageChooser entry" << item_index << "is not valid.";
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( item_map.contains( "appdata" ) )
|
||||
{
|
||||
#ifdef HAVE_XML
|
||||
model->addPackage( fromAppData( item_map ) );
|
||||
#else
|
||||
cWarning() << "Loading AppData XML is not supported.";
|
||||
#endif
|
||||
}
|
||||
else if ( item_map.contains( "appstream" ) )
|
||||
{
|
||||
#ifdef HAVE_APPSTREAM_VERSION
|
||||
if ( !pool )
|
||||
{
|
||||
pool = std::make_unique< AppStream::Pool >();
|
||||
pool->setLocale( QStringLiteral( "ALL" ) );
|
||||
poolOk = pool->load();
|
||||
}
|
||||
if ( pool && poolOk )
|
||||
{
|
||||
model->addPackage( fromAppStream( *pool, item_map ) );
|
||||
}
|
||||
#else
|
||||
cWarning() << "Loading AppStream data is not supported.";
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
model->addPackage( PackageItem( item_map ) );
|
||||
}
|
||||
}
|
||||
cDebug() << Logger::SubEntry << "Loaded PackageChooser with" << model->packageCount() << "entries.";
|
||||
}
|
||||
|
||||
void
|
||||
Config::setConfigurationMap( const QVariantMap& configurationMap )
|
||||
{
|
||||
m_mode = packageChooserModeNames().find( Calamares::getString( configurationMap, "mode" ),
|
||||
PackageChooserMode::Required );
|
||||
m_method = PackageChooserMethodNames().find( Calamares::getString( configurationMap, "method" ),
|
||||
PackageChooserMethod::Legacy );
|
||||
|
||||
if ( m_method == PackageChooserMethod::Legacy )
|
||||
{
|
||||
cDebug() << "Using module ID" << m_defaultId;
|
||||
}
|
||||
|
||||
if ( configurationMap.contains( "items" ) )
|
||||
{
|
||||
fillModel( m_model, configurationMap.value( "items" ).toList() );
|
||||
|
||||
QString default_item_id = Calamares::getString( configurationMap, "default" );
|
||||
if ( !default_item_id.isEmpty() )
|
||||
{
|
||||
for ( int item_n = 0; item_n < m_model->packageCount(); ++item_n )
|
||||
{
|
||||
QModelIndex item_idx = m_model->index( item_n, 0 );
|
||||
QVariant item_id = m_model->data( item_idx, PackageListModel::IdRole );
|
||||
|
||||
if ( item_id.toString() == default_item_id )
|
||||
{
|
||||
m_defaultModelIndex = item_idx;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
setPackageChoice( Calamares::getString( configurationMap, "packageChoice" ) );
|
||||
if ( m_method != PackageChooserMethod::Legacy )
|
||||
{
|
||||
cWarning() << "Single-selection QML module must use 'Legacy' method.";
|
||||
}
|
||||
}
|
||||
|
||||
bool labels_ok = false;
|
||||
auto labels = Calamares::getSubMap( configurationMap, "labels", labels_ok );
|
||||
if ( labels_ok )
|
||||
{
|
||||
if ( labels.contains( "step" ) )
|
||||
{
|
||||
m_stepName = new Calamares::Locale::TranslatedString( labels, "step" );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,128 +0,0 @@
|
||||
/* === This file is part of Calamares - <https://calamares.io> ===
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2021 Adriaan de Groot <groot@kde.org>
|
||||
* SPDX-FileCopyrightText: 2021 Anke Boersma <demm@kaosx.us>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* Calamares is Free Software: see the License-Identifier above.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PACKAGECHOOSER_CONFIG_H
|
||||
#define PACKAGECHOOSER_CONFIG_H
|
||||
|
||||
#include "PackageModel.h"
|
||||
|
||||
#include "modulesystem/Config.h"
|
||||
#include "modulesystem/InstanceKey.h"
|
||||
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
|
||||
enum class PackageChooserMode
|
||||
{
|
||||
Optional, // zero or one
|
||||
Required, // exactly one
|
||||
OptionalMultiple, // zero or more
|
||||
RequiredMultiple // one or more
|
||||
};
|
||||
|
||||
const NamedEnumTable< PackageChooserMode >& packageChooserModeNames();
|
||||
|
||||
enum class PackageChooserMethod
|
||||
{
|
||||
Legacy, // use contextualprocess or other custom
|
||||
Packages, // use the packages module
|
||||
NetAdd, // adds packages to the netinstall module
|
||||
NetSelect, // makes selections in the netinstall module
|
||||
};
|
||||
|
||||
const NamedEnumTable< PackageChooserMethod >& PackageChooserMethodNames();
|
||||
|
||||
class Config : public Calamares::ModuleSystem::Config
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
/** @brief This is the single-select package-choice
|
||||
*
|
||||
* For (QML) modules that support only a single selection and
|
||||
* just want to do things in a straightforward pick-this-one
|
||||
* way, the packageChoice property is a (the) way to go.
|
||||
*
|
||||
* Writing to this property means that any other form of package-
|
||||
* choice or selection is ignored.
|
||||
*/
|
||||
Q_PROPERTY( QString packageChoice READ packageChoice WRITE setPackageChoice NOTIFY packageChoiceChanged )
|
||||
Q_PROPERTY( QString prettyStatus READ prettyStatus NOTIFY prettyStatusChanged FINAL )
|
||||
|
||||
public:
|
||||
Config( QObject* parent = nullptr );
|
||||
~Config() override;
|
||||
|
||||
/** @brief Sets the default Id for this Config
|
||||
*
|
||||
* The default Id is the (owning) module identifier for the config,
|
||||
* and it is used when the Id read from the config file is empty.
|
||||
* The **usual** configuration when using method *packages* is
|
||||
* to rely on the default Id.
|
||||
*/
|
||||
void setDefaultId( const Calamares::ModuleSystem::InstanceKey& defaultId ) { m_defaultId = defaultId; }
|
||||
void setConfigurationMap( const QVariantMap& ) override;
|
||||
|
||||
PackageChooserMode mode() const { return m_mode; }
|
||||
PackageListModel* model() const { return m_model; }
|
||||
QModelIndex defaultSelectionIndex() const { return m_defaultModelIndex; }
|
||||
|
||||
/** @brief Returns an "introductory package" which describes packagechooser
|
||||
*
|
||||
* If the model contains a "none" package, returns that one on
|
||||
* the assumption that it is one to describe the whole; otherwise
|
||||
* returns a totally generic description.
|
||||
*/
|
||||
const PackageItem& introductionPackage() const;
|
||||
|
||||
/** @brief Write selection to global storage
|
||||
*
|
||||
* Updates the GS keys for this packagechooser, marking all
|
||||
* (and only) the packages in @p selected as selected.
|
||||
*/
|
||||
void updateGlobalStorage( const QStringList& selected ) const;
|
||||
/** @brief Write selection to global storage
|
||||
*
|
||||
* Updates the GS keys for this packagechooser, marking **only**
|
||||
* the package choice as selected. This assumes that the single-
|
||||
* selection QML code is in use.
|
||||
*/
|
||||
void updateGlobalStorage() const;
|
||||
|
||||
QString packageChoice() const { return m_packageChoice.value_or( QString() ); }
|
||||
void setPackageChoice( const QString& packageChoice );
|
||||
|
||||
QString prettyName() const;
|
||||
QString prettyStatus() const;
|
||||
|
||||
signals:
|
||||
void packageChoiceChanged( QString packageChoice );
|
||||
void prettyStatusChanged();
|
||||
|
||||
private:
|
||||
PackageListModel* m_model = nullptr;
|
||||
QModelIndex m_defaultModelIndex;
|
||||
|
||||
/// Selection mode for this module
|
||||
PackageChooserMode m_mode = PackageChooserMode::Optional;
|
||||
/// How this module stores to GS
|
||||
PackageChooserMethod m_method = PackageChooserMethod::Legacy;
|
||||
/// Value to use for id if none is set in the config file
|
||||
Calamares::ModuleSystem::InstanceKey m_defaultId;
|
||||
/** @brief QML selection (for single-selection approaches)
|
||||
*
|
||||
* If there is no value, then there has been no selection.
|
||||
* Reading the property will return an empty QString.
|
||||
*/
|
||||
std::optional< QString > m_packageChoice;
|
||||
Calamares::Locale::TranslatedString* m_stepName; // As it appears in the sidebar
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
@@ -1,225 +0,0 @@
|
||||
/* === This file is part of Calamares - <https://calamares.io> ===
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2019 Adriaan de Groot <groot@kde.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* Calamares is Free Software: see the License-Identifier above.
|
||||
*
|
||||
*/
|
||||
|
||||
/** @brief Loading items from AppData XML files.
|
||||
*
|
||||
* Only used if QtXML is found, implements PackageItem::fromAppData().
|
||||
*/
|
||||
#include "PackageModel.h"
|
||||
|
||||
#include "utils/Logger.h"
|
||||
#include "utils/Variant.h"
|
||||
|
||||
#include <QDomDocument>
|
||||
#include <QDomNodeList>
|
||||
#include <QFile>
|
||||
|
||||
/** @brief try to load the given @p fileName XML document
|
||||
*
|
||||
* Returns a QDomDocument, which will be valid iff the file can
|
||||
* be read and contains valid XML data.
|
||||
*/
|
||||
static inline QDomDocument
|
||||
loadAppData( const QString& fileName )
|
||||
{
|
||||
QFile file( fileName );
|
||||
if ( !file.open( QIODevice::ReadOnly ) )
|
||||
{
|
||||
return QDomDocument();
|
||||
}
|
||||
QDomDocument doc( "AppData" );
|
||||
if ( !doc.setContent( &file ) )
|
||||
{
|
||||
file.close();
|
||||
return QDomDocument();
|
||||
}
|
||||
file.close();
|
||||
return doc;
|
||||
}
|
||||
|
||||
/** @brief gets the text of child element @p tagName
|
||||
*/
|
||||
static inline QString
|
||||
getChildText( const QDomNode& n, const QString& tagName )
|
||||
{
|
||||
QDomElement e = n.firstChildElement( tagName );
|
||||
return e.isNull() ? QString() : e.text();
|
||||
}
|
||||
|
||||
/** @brief Gets a suitable screenshot path
|
||||
*
|
||||
* The <screenshots> element contains zero or more <screenshot>
|
||||
* elements, which can have a *type* associated with them.
|
||||
* Scan the screenshot elements, return the <image> path
|
||||
* for the one labeled with type=default or, if there is no
|
||||
* default, the first element.
|
||||
*/
|
||||
static inline QString
|
||||
getScreenshotPath( const QDomNode& n )
|
||||
{
|
||||
QDomElement shotsNode = n.firstChildElement( "screenshots" );
|
||||
if ( shotsNode.isNull() )
|
||||
{
|
||||
return QString();
|
||||
}
|
||||
|
||||
const QDomNodeList shotList = shotsNode.childNodes();
|
||||
int firstScreenshot = -1; // Use which screenshot node?
|
||||
for ( int i = 0; i < shotList.count(); ++i )
|
||||
{
|
||||
if ( !shotList.at( i ).isElement() )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
QDomElement e = shotList.at( i ).toElement();
|
||||
if ( e.tagName() != "screenshot" )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
// If none has the "type=default" attribute, use the first one
|
||||
if ( firstScreenshot < 0 )
|
||||
{
|
||||
firstScreenshot = i;
|
||||
}
|
||||
// But type=default takes precedence.
|
||||
if ( e.hasAttribute( "type" ) && e.attribute( "type" ) == "default" )
|
||||
{
|
||||
firstScreenshot = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( firstScreenshot >= 0 )
|
||||
{
|
||||
return shotList.at( firstScreenshot ).firstChildElement( "image" ).text();
|
||||
}
|
||||
|
||||
return QString();
|
||||
}
|
||||
|
||||
/** @brief Returns language of the given element @p e
|
||||
*
|
||||
* Transforms the attribute value for xml:lang to something
|
||||
* suitable for TranslatedString (e.g. [lang]).
|
||||
*/
|
||||
static inline QString
|
||||
getLanguage( const QDomElement& e )
|
||||
{
|
||||
QString language = e.attribute( "xml:lang" );
|
||||
if ( !language.isEmpty() )
|
||||
{
|
||||
language.replace( '-', '_' );
|
||||
language.prepend( '[' );
|
||||
language.append( ']' );
|
||||
}
|
||||
return language;
|
||||
}
|
||||
|
||||
/** @brief Scan the list of @p children for @p tagname elements and add them to the map
|
||||
*
|
||||
* Uses @p mapname instead of @p tagname for the entries in map @p m
|
||||
* to allow renaming from XML to map keys (in particular for
|
||||
* TranslatedString). Also transforms xml:lang attributes to suitable
|
||||
* key-decorations on @p mapname.
|
||||
*/
|
||||
static inline void
|
||||
fillMap( QVariantMap& m, const QDomNodeList& children, const QString& tagname, const QString& mapname )
|
||||
{
|
||||
for ( int i = 0; i < children.count(); ++i )
|
||||
{
|
||||
if ( !children.at( i ).isElement() )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
QDomElement e = children.at( i ).toElement();
|
||||
if ( e.tagName() != tagname )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
m[ mapname + getLanguage( e ) ] = e.text();
|
||||
}
|
||||
}
|
||||
|
||||
/** @brief gets the <name> and <description> elements
|
||||
*
|
||||
* Builds up a map of the <name> elements (which may have a *lang*
|
||||
* attribute to indicate translations and paragraphs of the
|
||||
* <description> element (also with lang). Uses the <summary>
|
||||
* elements to supplement the description if no description
|
||||
* is available for a given language.
|
||||
*
|
||||
* Returns a map with keys suitable for use by TranslatedString.
|
||||
*/
|
||||
static inline QVariantMap
|
||||
getNameAndSummary( const QDomNode& n )
|
||||
{
|
||||
QVariantMap m;
|
||||
|
||||
const QDomNodeList children = n.childNodes();
|
||||
fillMap( m, children, "name", "name" );
|
||||
fillMap( m, children, "summary", "description" );
|
||||
|
||||
const QDomElement description = n.firstChildElement( "description" );
|
||||
if ( !description.isNull() )
|
||||
{
|
||||
fillMap( m, description.childNodes(), "p", "description" );
|
||||
}
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
PackageItem
|
||||
fromAppData( const QVariantMap& item_map )
|
||||
{
|
||||
QString fileName = Calamares::getString( item_map, "appdata" );
|
||||
if ( fileName.isEmpty() )
|
||||
{
|
||||
cWarning() << "Can't load AppData without a suitable key.";
|
||||
return PackageItem();
|
||||
}
|
||||
cDebug() << "Loading AppData XML from" << fileName;
|
||||
|
||||
QDomDocument doc = loadAppData( fileName );
|
||||
if ( doc.isNull() )
|
||||
{
|
||||
return PackageItem();
|
||||
}
|
||||
|
||||
QDomElement componentNode = doc.documentElement();
|
||||
if ( !componentNode.isNull() && componentNode.tagName() == "component" )
|
||||
{
|
||||
// An "id" entry in the Calamares config overrides ID in the AppData
|
||||
QString id = Calamares::getString( item_map, "id" );
|
||||
if ( id.isEmpty() )
|
||||
{
|
||||
id = getChildText( componentNode, "id" );
|
||||
}
|
||||
if ( id.isEmpty() )
|
||||
{
|
||||
return PackageItem();
|
||||
}
|
||||
|
||||
// A "screenshot" entry in the Calamares config overrides AppData
|
||||
QString screenshotPath = Calamares::getString( item_map, "screenshot" );
|
||||
if ( screenshotPath.isEmpty() )
|
||||
{
|
||||
screenshotPath = getScreenshotPath( componentNode );
|
||||
}
|
||||
|
||||
QVariantMap map = getNameAndSummary( componentNode );
|
||||
map.insert( "id", id );
|
||||
map.insert( "screenshot", screenshotPath );
|
||||
|
||||
return PackageItem( map );
|
||||
}
|
||||
|
||||
return PackageItem();
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
/* === This file is part of Calamares - <https://calamares.io> ===
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2019 Adriaan de Groot <groot@kde.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* Calamares is Free Software: see the License-Identifier above.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ITEMAPPDATA_H
|
||||
#define ITEMAPPDATA_H
|
||||
|
||||
#include "PackageModel.h"
|
||||
|
||||
/** @brief Loads an AppData XML file and returns a PackageItem
|
||||
*
|
||||
* The @p map must have a key *appdata*. That is used as the
|
||||
* primary source of information, but keys *id* and *screenshotPath*
|
||||
* may be used to override parts of the AppData -- so that the
|
||||
* ID is under the control of Calamares, and the screenshot can be
|
||||
* forced to a local path available on the installation medium.
|
||||
*
|
||||
* Requires XML support in libcalamares, if not present will
|
||||
* return invalid PackageItems.
|
||||
*/
|
||||
PackageItem fromAppData( const QVariantMap& map );
|
||||
|
||||
#endif
|
||||
@@ -1,169 +0,0 @@
|
||||
/* === This file is part of Calamares - <https://calamares.io> ===
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2019 Adriaan de Groot <groot@kde.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* Calamares is Free Software: see the License-Identifier above.
|
||||
*
|
||||
*/
|
||||
|
||||
/** @brief Loading items from AppData XML files.
|
||||
*
|
||||
* Only used if QtXML is found, implements PackageItem::fromAppData().
|
||||
*/
|
||||
#include "PackageModel.h"
|
||||
|
||||
#include "locale/TranslationsModel.h"
|
||||
#include "utils/Logger.h"
|
||||
#include "utils/Variant.h"
|
||||
|
||||
#include <AppStreamQt/image.h>
|
||||
#include <AppStreamQt/pool.h>
|
||||
#include <AppStreamQt/screenshot.h>
|
||||
|
||||
/// @brief Return number of pixels in a size, for < ordering purposes
|
||||
static inline quint64
|
||||
sizeOrder( const QSize& size )
|
||||
{
|
||||
return static_cast<quint64>(size.width()) * static_cast<quint64>(size.height());
|
||||
}
|
||||
|
||||
/// @brief Sets a screenshot in @p map from @p screenshot, if a usable one is found
|
||||
static void
|
||||
setScreenshot( QVariantMap& map, const AppStream::Screenshot& screenshot )
|
||||
{
|
||||
if ( screenshot.images().count() < 1 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Pick the smallest
|
||||
QUrl url;
|
||||
quint64 size = sizeOrder( screenshot.images().first().size() );
|
||||
for ( const auto& img : screenshot.images() )
|
||||
{
|
||||
if ( sizeOrder( img.size() ) <= size )
|
||||
{
|
||||
url = img.url();
|
||||
}
|
||||
}
|
||||
|
||||
if ( url.isValid() )
|
||||
{
|
||||
map.insert( "screenshot", url.toString() );
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief Interpret an AppStream Component
|
||||
static PackageItem
|
||||
fromComponent( AppStream::Pool& pool, AppStream::Component& component )
|
||||
{
|
||||
#if HAVE_APPSTREAM_VERSION == 0
|
||||
auto setActiveLocale = [&component](const QString & locale)
|
||||
{
|
||||
component.setActiveLocale( locale );
|
||||
};
|
||||
#else
|
||||
auto setActiveLocale = [&pool](const QString & locale)
|
||||
{
|
||||
pool.setLocale( locale );
|
||||
};
|
||||
#endif
|
||||
|
||||
QVariantMap map;
|
||||
map.insert( "id", component.id() );
|
||||
map.insert( "package", component.packageNames().join( "," ) );
|
||||
|
||||
// Assume that the pool has loaded "ALL" locales, but it might be set
|
||||
// to any of them; get the en_US locale as "untranslated" and then
|
||||
// loop over Calamares locales (since there is no way to query for
|
||||
// available locales in the Component) to see if there's anything else.
|
||||
setActiveLocale( QStringLiteral( "en_US" ) );
|
||||
QString en_name = component.name();
|
||||
QString en_description = component.description();
|
||||
map.insert( "name", en_name );
|
||||
map.insert( "description", en_description );
|
||||
|
||||
for ( const QString& locale : Calamares::Locale::availableTranslations()->localeIds() )
|
||||
{
|
||||
setActiveLocale( locale );
|
||||
QString name = component.name();
|
||||
if ( name != en_name )
|
||||
{
|
||||
map.insert( QStringLiteral( "name[%1]" ).arg( locale ), name );
|
||||
}
|
||||
QString description = component.description();
|
||||
if ( description != en_description )
|
||||
{
|
||||
map.insert( QStringLiteral( "description[%1]" ).arg( locale ), description );
|
||||
}
|
||||
}
|
||||
|
||||
#if HAVE_APPSTREAM_VERSION == 0
|
||||
auto screenshots = component.screenshots();
|
||||
#else
|
||||
auto screenshots = component.screenshotsAll();
|
||||
#endif
|
||||
if ( screenshots.count() > 0 )
|
||||
{
|
||||
bool done = false;
|
||||
for ( const auto& s : screenshots )
|
||||
{
|
||||
if ( s.isDefault() )
|
||||
{
|
||||
setScreenshot( map, s );
|
||||
done = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( !done )
|
||||
{
|
||||
setScreenshot( map, screenshots.first() );
|
||||
}
|
||||
}
|
||||
|
||||
return PackageItem( map );
|
||||
}
|
||||
|
||||
PackageItem
|
||||
fromAppStream( AppStream::Pool& pool, const QVariantMap& item_map )
|
||||
{
|
||||
QString appstreamId = Calamares::getString( item_map, "appstream" );
|
||||
if ( appstreamId.isEmpty() )
|
||||
{
|
||||
cWarning() << "Can't load AppStream without a suitable appstreamId.";
|
||||
return PackageItem();
|
||||
}
|
||||
cDebug() << "Loading AppStream data for" << appstreamId;
|
||||
|
||||
#if HAVE_APPSTREAM_VERSION == 0
|
||||
auto itemList = pool.componentsById( appstreamId );
|
||||
#else
|
||||
auto itemList = pool.componentsById( appstreamId ).toList();
|
||||
#endif
|
||||
if ( itemList.count() < 1 )
|
||||
{
|
||||
cWarning() << "No AppStream data for" << appstreamId;
|
||||
return PackageItem();
|
||||
}
|
||||
if ( itemList.count() > 1 )
|
||||
{
|
||||
cDebug() << "Multiple AppStream data for" << appstreamId << "using first.";
|
||||
}
|
||||
|
||||
auto r = fromComponent( pool, itemList.first() );
|
||||
if ( r.isValid() )
|
||||
{
|
||||
QString id = Calamares::getString( item_map, "id" );
|
||||
QString screenshotPath = Calamares::getString( item_map, "screenshot" );
|
||||
if ( !id.isEmpty() )
|
||||
{
|
||||
r.id = id;
|
||||
}
|
||||
if ( !screenshotPath.isEmpty() )
|
||||
{
|
||||
r.screenshot = screenshotPath;
|
||||
}
|
||||
}
|
||||
return r;
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
/* === This file is part of Calamares - <https://calamares.io> ===
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2019 Adriaan de Groot <groot@kde.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* Calamares is Free Software: see the License-Identifier above.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef ITEMAPPSTREAM_H
|
||||
#define ITEMAPPSTREAM_H
|
||||
|
||||
#include "PackageModel.h"
|
||||
|
||||
namespace AppStream
|
||||
{
|
||||
class Pool;
|
||||
} // namespace AppStream
|
||||
|
||||
/** @brief Loads an item from AppStream data.
|
||||
*
|
||||
* The @p map must have a key *appstream*. That is used as the
|
||||
* primary source of information from the AppStream cache, but
|
||||
* keys *id* and *screenshotPath* may be used to override parts
|
||||
* of the AppStream data -- so that the ID is under the control
|
||||
* of Calamares, and the screenshot can be forced to a local path
|
||||
* available on the installation medium.
|
||||
*
|
||||
* Requires AppStreamQt, if not present will return invalid
|
||||
* PackageItems.
|
||||
*/
|
||||
PackageItem fromAppStream( AppStream::Pool& pool, const QVariantMap& map );
|
||||
|
||||
#endif
|
||||
@@ -1,145 +0,0 @@
|
||||
/* === This file is part of Calamares - <https://calamares.io> ===
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2019 Adriaan de Groot <groot@kde.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* Calamares is Free Software: see the License-Identifier above.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "PackageChooserPage.h"
|
||||
|
||||
#include "ui_page_package.h"
|
||||
|
||||
#include "utils/Gui.h"
|
||||
#include "utils/Logger.h"
|
||||
#include "utils/Retranslator.h"
|
||||
|
||||
#include <QLabel>
|
||||
|
||||
PackageChooserPage::PackageChooserPage( PackageChooserMode mode, QWidget* parent )
|
||||
: QWidget( parent )
|
||||
, ui( new Ui::PackageChooserPage )
|
||||
, m_introduction( QString(),
|
||||
QString(),
|
||||
tr( "Package Selection" ),
|
||||
tr( "Please pick a product from the list. The selected product will be installed." ) )
|
||||
{
|
||||
m_introduction.screenshot = QPixmap( QStringLiteral( ":/images/no-selection.png" ) );
|
||||
|
||||
ui->setupUi( this );
|
||||
CALAMARES_RETRANSLATE( updateLabels(); );
|
||||
|
||||
switch ( mode )
|
||||
{
|
||||
case PackageChooserMode::Optional:
|
||||
[[fallthrough]];
|
||||
case PackageChooserMode::Required:
|
||||
ui->products->setSelectionMode( QAbstractItemView::SingleSelection );
|
||||
break;
|
||||
case PackageChooserMode::OptionalMultiple:
|
||||
[[fallthrough]];
|
||||
case PackageChooserMode::RequiredMultiple:
|
||||
ui->products->setSelectionMode( QAbstractItemView::ExtendedSelection );
|
||||
}
|
||||
|
||||
ui->products->setMinimumWidth( 10 * Calamares::defaultFontHeight() );
|
||||
}
|
||||
|
||||
void
|
||||
PackageChooserPage::currentChanged( const QModelIndex& index )
|
||||
{
|
||||
if ( !index.isValid() || !ui->products->selectionModel()->hasSelection() )
|
||||
{
|
||||
ui->productName->setText( m_introduction.name.get() );
|
||||
ui->productScreenshot->setPixmap( m_introduction.screenshot );
|
||||
ui->productDescription->setText( m_introduction.description.get() );
|
||||
}
|
||||
else
|
||||
{
|
||||
const auto* model = ui->products->model();
|
||||
|
||||
ui->productName->setText( model->data( index, PackageListModel::NameRole ).toString() );
|
||||
ui->productDescription->setText( model->data( index, PackageListModel::DescriptionRole ).toString() );
|
||||
|
||||
QPixmap currentScreenshot = model->data( index, PackageListModel::ScreenshotRole ).value< QPixmap >();
|
||||
if ( currentScreenshot.isNull() )
|
||||
{
|
||||
ui->productScreenshot->setPixmap( m_introduction.screenshot );
|
||||
}
|
||||
else
|
||||
{
|
||||
ui->productScreenshot->setPixmap( currentScreenshot );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PackageChooserPage::updateLabels()
|
||||
{
|
||||
if ( ui && ui->products && ui->products->selectionModel() )
|
||||
{
|
||||
currentChanged( ui->products->selectionModel()->currentIndex() );
|
||||
}
|
||||
else
|
||||
{
|
||||
currentChanged( QModelIndex() );
|
||||
}
|
||||
emit selectionChanged();
|
||||
}
|
||||
|
||||
void
|
||||
PackageChooserPage::setModel( QAbstractItemModel* model )
|
||||
{
|
||||
ui->products->setModel( model );
|
||||
currentChanged( QModelIndex() );
|
||||
connect( ui->products->selectionModel(),
|
||||
&QItemSelectionModel::selectionChanged,
|
||||
this,
|
||||
&PackageChooserPage::updateLabels );
|
||||
}
|
||||
|
||||
void
|
||||
PackageChooserPage::setSelection( const QModelIndex& index )
|
||||
{
|
||||
if ( index.isValid() )
|
||||
{
|
||||
ui->products->selectionModel()->select( index, QItemSelectionModel::Select );
|
||||
}
|
||||
currentChanged( index );
|
||||
}
|
||||
|
||||
bool
|
||||
PackageChooserPage::hasSelection() const
|
||||
{
|
||||
return ui && ui->products && ui->products->selectionModel() && ui->products->selectionModel()->hasSelection();
|
||||
}
|
||||
|
||||
QStringList
|
||||
PackageChooserPage::selectedPackageIds() const
|
||||
{
|
||||
if ( !( ui && ui->products && ui->products->selectionModel() ) )
|
||||
{
|
||||
return QStringList();
|
||||
}
|
||||
|
||||
const auto* model = ui->products->model();
|
||||
QStringList ids;
|
||||
for ( const auto& index : ui->products->selectionModel()->selectedIndexes() )
|
||||
{
|
||||
QString pid = model->data( index, PackageListModel::IdRole ).toString();
|
||||
if ( !pid.isEmpty() )
|
||||
{
|
||||
ids.append( pid );
|
||||
}
|
||||
}
|
||||
return ids;
|
||||
}
|
||||
|
||||
void
|
||||
PackageChooserPage::setIntroduction( const PackageItem& item )
|
||||
{
|
||||
m_introduction.name = item.name;
|
||||
m_introduction.description = item.description;
|
||||
m_introduction.screenshot = item.screenshot;
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
/* === This file is part of Calamares - <https://calamares.io> ===
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2019 Adriaan de Groot <groot@kde.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* Calamares is Free Software: see the License-Identifier above.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PACKAGECHOOSERPAGE_H
|
||||
#define PACKAGECHOOSERPAGE_H
|
||||
|
||||
#include "Config.h"
|
||||
#include "PackageModel.h"
|
||||
|
||||
#include <QAbstractItemModel>
|
||||
#include <QWidget>
|
||||
|
||||
namespace Ui
|
||||
{
|
||||
class PackageChooserPage;
|
||||
} // namespace Ui
|
||||
|
||||
class PackageChooserPage : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit PackageChooserPage( PackageChooserMode mode, QWidget* parent = nullptr );
|
||||
|
||||
/// @brief Sets the data model for the listview
|
||||
void setModel( QAbstractItemModel* model );
|
||||
|
||||
/// @brief Sets the introductory (no-package-selected) texts
|
||||
void setIntroduction( const PackageItem& item );
|
||||
/// @brief Selects a listview item
|
||||
void setSelection( const QModelIndex& index );
|
||||
/// @brief Is anything selected?
|
||||
bool hasSelection() const;
|
||||
/** @brief Get the list of selected ids
|
||||
*
|
||||
* This list may be empty (if none is selected).
|
||||
*/
|
||||
QStringList selectedPackageIds() const;
|
||||
|
||||
public slots:
|
||||
void currentChanged( const QModelIndex& index );
|
||||
void updateLabels();
|
||||
|
||||
signals:
|
||||
void selectionChanged();
|
||||
|
||||
private:
|
||||
Ui::PackageChooserPage* ui;
|
||||
PackageItem m_introduction;
|
||||
};
|
||||
|
||||
#endif // PACKAGECHOOSERPAGE_H
|
||||
@@ -1,158 +0,0 @@
|
||||
/* === This file is part of Calamares - <https://calamares.io> ===
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2019 Adriaan de Groot <groot@kde.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* Calamares is Free Software: see the License-Identifier above.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "PackageChooserViewStep.h"
|
||||
|
||||
#include "Config.h"
|
||||
#include "PackageChooserPage.h"
|
||||
#include "PackageModel.h"
|
||||
|
||||
#include "GlobalStorage.h"
|
||||
#include "JobQueue.h"
|
||||
#include "locale/TranslatableConfiguration.h"
|
||||
#include "utils/Logger.h"
|
||||
#include "utils/System.h"
|
||||
#include "utils/Variant.h"
|
||||
|
||||
#include <QDesktopServices>
|
||||
#include <QVariantMap>
|
||||
|
||||
CALAMARES_PLUGIN_FACTORY_DEFINITION( PackageChooserViewStepFactory, registerPlugin< PackageChooserViewStep >(); )
|
||||
|
||||
PackageChooserViewStep::PackageChooserViewStep( QObject* parent )
|
||||
: Calamares::ViewStep( parent )
|
||||
, m_config( new Config( this ) )
|
||||
, m_widget( nullptr )
|
||||
{
|
||||
emit nextStatusChanged( false );
|
||||
}
|
||||
|
||||
|
||||
PackageChooserViewStep::~PackageChooserViewStep()
|
||||
{
|
||||
if ( m_widget && m_widget->parent() == nullptr )
|
||||
{
|
||||
m_widget->deleteLater();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QString
|
||||
PackageChooserViewStep::prettyName() const
|
||||
{
|
||||
return m_config->prettyName();
|
||||
}
|
||||
|
||||
|
||||
QWidget*
|
||||
PackageChooserViewStep::widget()
|
||||
{
|
||||
if ( !m_widget )
|
||||
{
|
||||
m_widget = new PackageChooserPage( m_config->mode(), nullptr );
|
||||
connect( m_widget,
|
||||
&PackageChooserPage::selectionChanged,
|
||||
[ = ]() { emit nextStatusChanged( this->isNextEnabled() ); } );
|
||||
hookupModel();
|
||||
}
|
||||
return m_widget;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
PackageChooserViewStep::isNextEnabled() const
|
||||
{
|
||||
if ( !m_widget )
|
||||
{
|
||||
// No way to have changed anything
|
||||
return true;
|
||||
}
|
||||
|
||||
switch ( m_config->mode() )
|
||||
{
|
||||
case PackageChooserMode::Optional:
|
||||
case PackageChooserMode::OptionalMultiple:
|
||||
// zero or one OR zero or more
|
||||
return true;
|
||||
case PackageChooserMode::Required:
|
||||
case PackageChooserMode::RequiredMultiple:
|
||||
// exactly one OR one or more
|
||||
return m_widget->hasSelection();
|
||||
}
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
PackageChooserViewStep::isBackEnabled() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
PackageChooserViewStep::isAtBeginning() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
PackageChooserViewStep::isAtEnd() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
PackageChooserViewStep::onActivate()
|
||||
{
|
||||
if ( !m_widget->hasSelection() )
|
||||
{
|
||||
m_widget->setSelection( m_config->defaultSelectionIndex() );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PackageChooserViewStep::onLeave()
|
||||
{
|
||||
m_config->updateGlobalStorage( m_widget->selectedPackageIds() );
|
||||
}
|
||||
|
||||
Calamares::JobList
|
||||
PackageChooserViewStep::jobs() const
|
||||
{
|
||||
Calamares::JobList l;
|
||||
return l;
|
||||
}
|
||||
|
||||
void
|
||||
PackageChooserViewStep::setConfigurationMap( const QVariantMap& configurationMap )
|
||||
{
|
||||
m_config->setDefaultId( moduleInstanceKey() );
|
||||
m_config->setConfigurationMap( configurationMap );
|
||||
|
||||
if ( m_widget )
|
||||
{
|
||||
hookupModel();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PackageChooserViewStep::hookupModel()
|
||||
{
|
||||
if ( !m_config->model() || !m_widget )
|
||||
{
|
||||
cError() << "Can't hook up model until widget and model both exist.";
|
||||
return;
|
||||
}
|
||||
|
||||
m_widget->setModel( m_config->model() );
|
||||
m_widget->setIntroduction( m_config->introductionPackage() );
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
/* === This file is part of Calamares - <https://calamares.io> ===
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2019 Adriaan de Groot <groot@kde.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* Calamares is Free Software: see the License-Identifier above.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PACKAGECHOOSERVIEWSTEP_H
|
||||
#define PACKAGECHOOSERVIEWSTEP_H
|
||||
|
||||
#include "DllMacro.h"
|
||||
#include "locale/TranslatableConfiguration.h"
|
||||
#include "utils/PluginFactory.h"
|
||||
#include "viewpages/ViewStep.h"
|
||||
|
||||
#include <QVariantMap>
|
||||
|
||||
class Config;
|
||||
class PackageChooserPage;
|
||||
|
||||
class PLUGINDLLEXPORT PackageChooserViewStep : public Calamares::ViewStep
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit PackageChooserViewStep( QObject* parent = nullptr );
|
||||
~PackageChooserViewStep() override;
|
||||
|
||||
QString prettyName() const override;
|
||||
|
||||
QWidget* widget() override;
|
||||
|
||||
bool isNextEnabled() const override;
|
||||
bool isBackEnabled() const override;
|
||||
|
||||
bool isAtBeginning() const override;
|
||||
bool isAtEnd() const override;
|
||||
|
||||
void onActivate() override;
|
||||
void onLeave() override;
|
||||
|
||||
Calamares::JobList jobs() const override;
|
||||
|
||||
void setConfigurationMap( const QVariantMap& configurationMap ) override;
|
||||
|
||||
private:
|
||||
void hookupModel();
|
||||
|
||||
Config* m_config;
|
||||
PackageChooserPage* m_widget;
|
||||
};
|
||||
|
||||
CALAMARES_PLUGIN_FACTORY_DECLARATION( PackageChooserViewStepFactory )
|
||||
|
||||
#endif // PACKAGECHOOSERVIEWSTEP_H
|
||||
@@ -1,196 +0,0 @@
|
||||
/* === This file is part of Calamares - <https://calamares.io> ===
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2019 Adriaan de Groot <groot@kde.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* Calamares is Free Software: see the License-Identifier above.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "PackageModel.h"
|
||||
|
||||
#include "Branding.h"
|
||||
#include "utils/Logger.h"
|
||||
#include "utils/Variant.h"
|
||||
|
||||
#include <QFileInfo>
|
||||
|
||||
/** @brief A wrapper for Calamares::getSubMap that excludes the success param
|
||||
*/
|
||||
static QVariantMap
|
||||
getSubMap( const QVariantMap& map, const QString& key )
|
||||
{
|
||||
bool success;
|
||||
|
||||
return Calamares::getSubMap( map, key, success );
|
||||
}
|
||||
|
||||
static QPixmap
|
||||
loadScreenshot( const QString& path )
|
||||
{
|
||||
if ( QFileInfo::exists( path ) )
|
||||
{
|
||||
return QPixmap( path );
|
||||
}
|
||||
|
||||
const auto* branding = Calamares::Branding::instance();
|
||||
if ( !branding )
|
||||
{
|
||||
return QPixmap();
|
||||
}
|
||||
return QPixmap( branding->componentDirectory() + QStringLiteral( "/" ) + path );
|
||||
}
|
||||
|
||||
PackageItem::PackageItem() {}
|
||||
|
||||
PackageItem::PackageItem( const QString& a_id, const QString& a_name, const QString& a_description )
|
||||
: id( a_id )
|
||||
, name( a_name )
|
||||
, description( a_description )
|
||||
{
|
||||
}
|
||||
|
||||
PackageItem::PackageItem( const QString& a_id,
|
||||
const QString& a_name,
|
||||
const QString& a_description,
|
||||
const QString& screenshotPath )
|
||||
: id( a_id )
|
||||
, name( a_name )
|
||||
, description( a_description )
|
||||
, screenshot( screenshotPath )
|
||||
{
|
||||
}
|
||||
|
||||
PackageItem::PackageItem( const QVariantMap& item_map )
|
||||
: id( Calamares::getString( item_map, "id" ) )
|
||||
, name( Calamares::Locale::TranslatedString( item_map, "name" ) )
|
||||
, description( Calamares::Locale::TranslatedString( item_map, "description" ) )
|
||||
, screenshot( loadScreenshot( Calamares::getString( item_map, "screenshot" ) ) )
|
||||
, packageNames( Calamares::getStringList( item_map, "packages" ) )
|
||||
, netinstallData( getSubMap( item_map, "netinstall" ) )
|
||||
{
|
||||
if ( name.isEmpty() && id.isEmpty() )
|
||||
{
|
||||
name = QObject::tr( "No product" );
|
||||
}
|
||||
else if ( name.isEmpty() )
|
||||
{
|
||||
cWarning() << "PackageChooser item" << id << "has an empty name.";
|
||||
}
|
||||
if ( description.isEmpty() )
|
||||
{
|
||||
description = QObject::tr( "No description provided." );
|
||||
}
|
||||
}
|
||||
|
||||
PackageListModel::PackageListModel( QObject* parent )
|
||||
: QAbstractListModel( parent )
|
||||
{
|
||||
}
|
||||
|
||||
PackageListModel::PackageListModel( PackageList&& items, QObject* parent )
|
||||
: QAbstractListModel( parent )
|
||||
, m_packages( std::move( items ) )
|
||||
{
|
||||
}
|
||||
|
||||
PackageListModel::~PackageListModel() {}
|
||||
|
||||
void
|
||||
PackageListModel::addPackage( PackageItem&& p )
|
||||
{
|
||||
// Only add valid packages
|
||||
if ( p.isValid() )
|
||||
{
|
||||
int c = m_packages.count();
|
||||
beginInsertRows( QModelIndex(), c, c );
|
||||
m_packages.append( p );
|
||||
endInsertRows();
|
||||
}
|
||||
}
|
||||
|
||||
QStringList
|
||||
PackageListModel::getInstallPackagesForName( const QString& id ) const
|
||||
{
|
||||
for ( const auto& p : qAsConst( m_packages ) )
|
||||
{
|
||||
if ( p.id == id )
|
||||
{
|
||||
return p.packageNames;
|
||||
}
|
||||
}
|
||||
return QStringList();
|
||||
}
|
||||
|
||||
QStringList
|
||||
PackageListModel::getInstallPackagesForNames( const QStringList& ids ) const
|
||||
{
|
||||
QStringList l;
|
||||
for ( const auto& p : qAsConst( m_packages ) )
|
||||
{
|
||||
if ( ids.contains( p.id ) )
|
||||
{
|
||||
l.append( p.packageNames );
|
||||
}
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
QVariantList
|
||||
PackageListModel::getNetinstallDataForNames( const QStringList& ids ) const
|
||||
{
|
||||
QVariantList l;
|
||||
for ( auto& p : m_packages )
|
||||
{
|
||||
if ( ids.contains( p.id ) )
|
||||
{
|
||||
if ( !p.netinstallData.isEmpty() )
|
||||
{
|
||||
QVariantMap newData = p.netinstallData;
|
||||
newData[ "source" ] = QStringLiteral( "packageChooser" );
|
||||
l.append( newData );
|
||||
}
|
||||
}
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
int
|
||||
PackageListModel::rowCount( const QModelIndex& index ) const
|
||||
{
|
||||
// For lists, valid indexes have zero children; only the root index has them
|
||||
return index.isValid() ? 0 : m_packages.count();
|
||||
}
|
||||
|
||||
QVariant
|
||||
PackageListModel::data( const QModelIndex& index, int role ) const
|
||||
{
|
||||
if ( !index.isValid() )
|
||||
{
|
||||
return QVariant();
|
||||
}
|
||||
int row = index.row();
|
||||
if ( row >= m_packages.count() || row < 0 )
|
||||
{
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
if ( role == Qt::DisplayRole /* Also PackageNameRole */ )
|
||||
{
|
||||
return m_packages[ row ].name.get();
|
||||
}
|
||||
else if ( role == DescriptionRole )
|
||||
{
|
||||
return m_packages[ row ].description.get();
|
||||
}
|
||||
else if ( role == ScreenshotRole )
|
||||
{
|
||||
return m_packages[ row ].screenshot;
|
||||
}
|
||||
else if ( role == IdRole )
|
||||
{
|
||||
return m_packages[ row ].id;
|
||||
}
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
@@ -1,135 +0,0 @@
|
||||
/* === This file is part of Calamares - <https://calamares.io> ===
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2019 Adriaan de Groot <groot@kde.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* Calamares is Free Software: see the License-Identifier above.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PACKAGEMODEL_H
|
||||
#define PACKAGEMODEL_H
|
||||
|
||||
#include "locale/TranslatableConfiguration.h"
|
||||
#include "utils/NamedEnum.h"
|
||||
|
||||
#include <QAbstractListModel>
|
||||
#include <QObject>
|
||||
#include <QPixmap>
|
||||
#include <QVector>
|
||||
|
||||
|
||||
struct PackageItem
|
||||
{
|
||||
QString id;
|
||||
Calamares::Locale::TranslatedString name;
|
||||
Calamares::Locale::TranslatedString description;
|
||||
QPixmap screenshot;
|
||||
QStringList packageNames;
|
||||
QVariantMap netinstallData;
|
||||
|
||||
/// @brief Create blank PackageItem
|
||||
PackageItem();
|
||||
/** @brief Creates a PackageItem from given strings
|
||||
*
|
||||
* This constructor sets all the text members,
|
||||
* but leaves the screenshot blank. Set that separately.
|
||||
*/
|
||||
PackageItem( const QString& id, const QString& name, const QString& description );
|
||||
|
||||
/** @brief Creates a PackageItem from given strings.
|
||||
*
|
||||
* Set all the text members and load the screenshot from the given
|
||||
* @p screenshotPath, which may be a QRC path (:/path/in/qrc) or
|
||||
* a filesystem path, whatever QPixmap understands.
|
||||
*/
|
||||
PackageItem( const QString& id, const QString& name, const QString& description, const QString& screenshotPath );
|
||||
|
||||
/** @brief Creates a PackageItem from a QVariantMap
|
||||
*
|
||||
* This is intended for use when loading PackageItems from a
|
||||
* configuration map. It will look up the various keys in the map
|
||||
* and handle translation strings as well.
|
||||
*
|
||||
* The following keys are used:
|
||||
* - *id*: the identifier for this item; if it is the empty string
|
||||
* then this is the special "no-package".
|
||||
* - *name* (and *name[lang]*): for the name and its translations
|
||||
* - *description* (and *description[lang]*)
|
||||
* - *screenshot*: a path to a screenshot for this package
|
||||
* - *packages*: a list of package names
|
||||
*/
|
||||
PackageItem( const QVariantMap& map );
|
||||
|
||||
/** @brief Is this item valid?
|
||||
*
|
||||
* A valid item has an untranslated name available.
|
||||
*/
|
||||
bool isValid() const { return !name.isEmpty(); }
|
||||
|
||||
/** @brief Is this a (the) No-Package package?
|
||||
*
|
||||
* There should be at most one No-Package item in a collection
|
||||
* of PackageItems. That one will be used to describe a
|
||||
* "no package" situation.
|
||||
*/
|
||||
bool isNonePackage() const { return id.isEmpty(); }
|
||||
};
|
||||
|
||||
using PackageList = QVector< PackageItem >;
|
||||
|
||||
class PackageListModel : public QAbstractListModel
|
||||
{
|
||||
public:
|
||||
PackageListModel( PackageList&& items, QObject* parent );
|
||||
PackageListModel( QObject* parent );
|
||||
~PackageListModel() override;
|
||||
|
||||
/** @brief Add a package @p to the model
|
||||
*
|
||||
* Only valid packages are added -- that is, they must have a name.
|
||||
*/
|
||||
void addPackage( PackageItem&& p );
|
||||
|
||||
int rowCount( const QModelIndex& index ) const override;
|
||||
QVariant data( const QModelIndex& index, int role ) const override;
|
||||
|
||||
/// @brief Direct (non-abstract) access to package data
|
||||
const PackageItem& packageData( int r ) const { return m_packages[ r ]; }
|
||||
/// @brief Direct (non-abstract) count of package data
|
||||
int packageCount() const { return m_packages.count(); }
|
||||
|
||||
/** @brief Does a name lookup (based on id) and returns the packages member
|
||||
*
|
||||
* If there is a package with the given @p id, returns its packages
|
||||
* (e.g. the names of underlying packages to install for it); returns
|
||||
* an empty list if the id is not found.
|
||||
*/
|
||||
QStringList getInstallPackagesForName( const QString& id ) const;
|
||||
/** @brief Name-lookup all the @p ids and returns the packages members
|
||||
*
|
||||
* Concatenates installPackagesForName() for each id in @p ids.
|
||||
*/
|
||||
QStringList getInstallPackagesForNames( const QStringList& ids ) const;
|
||||
|
||||
/** @brief Does a name lookup (based on id) and returns the netinstall data
|
||||
*
|
||||
* If there is a package with an id in @p ids, returns their netinstall data
|
||||
*
|
||||
* returns a list of netinstall data or an emply list if none is found
|
||||
*/
|
||||
QVariantList getNetinstallDataForNames( const QStringList& ids ) const;
|
||||
|
||||
enum Roles : int
|
||||
{
|
||||
NameRole = Qt::DisplayRole,
|
||||
DescriptionRole = Qt::UserRole,
|
||||
ScreenshotRole,
|
||||
IdRole
|
||||
};
|
||||
|
||||
private:
|
||||
PackageList m_packages;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,84 +0,0 @@
|
||||
/* === This file is part of Calamares - <https://calamares.io> ===
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2019 Adriaan de Groot <groot@kde.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* Calamares is Free Software: see the License-Identifier above.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "Tests.h"
|
||||
|
||||
#ifdef HAVE_APPDATA
|
||||
#include "ItemAppData.h"
|
||||
#endif
|
||||
#ifdef HAVE_APPSTREAM_VERSION
|
||||
#include "ItemAppStream.h"
|
||||
#endif
|
||||
#include "PackageModel.h"
|
||||
|
||||
#include "utils/Logger.h"
|
||||
|
||||
#include <QtTest/QtTest>
|
||||
|
||||
QTEST_MAIN( PackageChooserTests )
|
||||
|
||||
PackageChooserTests::PackageChooserTests() {}
|
||||
|
||||
PackageChooserTests::~PackageChooserTests() {}
|
||||
|
||||
void
|
||||
PackageChooserTests::initTestCase()
|
||||
{
|
||||
Logger::setupLogLevel( Logger::LOGDEBUG );
|
||||
}
|
||||
|
||||
void
|
||||
PackageChooserTests::testBogus()
|
||||
{
|
||||
QVERIFY( true );
|
||||
}
|
||||
|
||||
void
|
||||
PackageChooserTests::testAppData()
|
||||
{
|
||||
// Path from the build-dir and from the running-the-test varies,
|
||||
// for in-source build, for build/, and for tests-in-build/,
|
||||
// so look in multiple places.
|
||||
QString appdataName( "io.calamares.calamares.appdata.xml" );
|
||||
for ( const auto& prefix : QStringList { "", "../", "../../../", "../../../../" } )
|
||||
{
|
||||
if ( QFile::exists( prefix + appdataName ) )
|
||||
{
|
||||
appdataName = prefix + appdataName;
|
||||
break;
|
||||
}
|
||||
}
|
||||
QVERIFY( QFile::exists( appdataName ) );
|
||||
|
||||
QVariantMap m;
|
||||
m.insert( "appdata", appdataName );
|
||||
|
||||
#ifdef HAVE_XML
|
||||
PackageItem p1 = fromAppData( m );
|
||||
QVERIFY( p1.isValid() );
|
||||
QCOMPARE( p1.id, QStringLiteral( "io.calamares.calamares.desktop" ) );
|
||||
QCOMPARE( p1.name.get(), QStringLiteral( "Calamares" ) );
|
||||
// The <description> entry has precedence
|
||||
QCOMPARE( p1.description.get(), QStringLiteral( "Calamares is an installer program for Linux distributions." ) );
|
||||
// .. but en_GB doesn't have an entry in description, so uses <summary>
|
||||
QCOMPARE( p1.description.get( QLocale( "en_GB" ) ), QStringLiteral( "Calamares Linux Installer" ) );
|
||||
QCOMPARE( p1.description.get( QLocale( "nl" ) ),
|
||||
QStringLiteral( "Calamares is een installatieprogramma voor Linux distributies." ) );
|
||||
QVERIFY( p1.screenshot.isNull() );
|
||||
|
||||
m.insert( "id", "calamares" );
|
||||
m.insert( "screenshot", ":/images/calamares.png" );
|
||||
PackageItem p2 = fromAppData( m );
|
||||
QVERIFY( p2.isValid() );
|
||||
QCOMPARE( p2.id, QStringLiteral( "calamares" ) );
|
||||
QCOMPARE( p2.description.get( QLocale( "nl" ) ),
|
||||
QStringLiteral( "Calamares is een installatieprogramma voor Linux distributies." ) );
|
||||
QVERIFY( !p2.screenshot.isNull() );
|
||||
#endif
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
/* === This file is part of Calamares - <https://calamares.io> ===
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2019 Adriaan de Groot <groot@kde.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* Calamares is Free Software: see the License-Identifier above.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PACKAGECHOOSERTESTS_H
|
||||
#define PACKAGECHOOSERTESTS_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
class PackageChooserTests : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
PackageChooserTests();
|
||||
~PackageChooserTests() override;
|
||||
|
||||
private Q_SLOTS:
|
||||
void initTestCase();
|
||||
void testBogus();
|
||||
void testAppData();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Before Width: | Height: | Size: 20 KiB |
@@ -1,2 +0,0 @@
|
||||
SPDX-FileCopyrightText: 2014 Uri Herrera <uri_herrera@nitrux.in> and others
|
||||
SPDX-License-Identifier: LGPL-3.0-or-later
|
||||
@@ -1,172 +0,0 @@
|
||||
# SPDX-FileCopyrightText: no
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
#
|
||||
# Configuration for the low-density software chooser
|
||||
---
|
||||
# Software selection mode, to set whether the software packages
|
||||
# can be chosen singly, or multiply.
|
||||
#
|
||||
# Possible modes are "optional", "required" (for zero-or-one or exactly-one)
|
||||
# or "optionalmultiple", "requiredmultiple" (for zero-or-more
|
||||
# or one-or-more).
|
||||
mode: required
|
||||
|
||||
# Software installation method:
|
||||
#
|
||||
# - "legacy" or "custom" or "contextualprocess"
|
||||
# When set to "legacy", writes a GlobalStorage value for the choice that
|
||||
# has been made. The key is *packagechooser_<id>*. The module's
|
||||
# instance name is used; see the *instances* section of `settings.conf`.
|
||||
# If there is just one packagechooser module, and no special instance is set,
|
||||
# resulting GS key is probably *packagechooser_packagechooser*.
|
||||
#
|
||||
# The GS value is a comma-separated list of the IDs of the selected
|
||||
# packages, or an empty string if none is selected.
|
||||
#
|
||||
# With "legacy" installation, you should have a contextualprocess or similar
|
||||
# module somewhere in the `exec` phase to process the GlobalStorage key
|
||||
# and actually **do** something for the packages.
|
||||
#
|
||||
# - "packages"
|
||||
# When set to "packages", writes GlobalStorage values suitable for
|
||||
# consumption by the *packages* module (which should appear later
|
||||
# in the `exec` section. These package settings will then be handed
|
||||
# off to whatever package manager is configured there.
|
||||
#
|
||||
# - "netinstall-select"
|
||||
# When this is set, the id(s) selected are passed to the netinstall module.
|
||||
# Any id that matches a group name in that module is set to checked
|
||||
#
|
||||
# - "netinstall-add"
|
||||
# With this method, the packagechooser module is used to add groups to the
|
||||
# netinstall module. For this to have any effect. You must set netinstall,
|
||||
# which is described below.
|
||||
#
|
||||
# There is no need to put this module in the `exec` section. There
|
||||
# are no jobs that this module provides. You should put **other**
|
||||
# modules, either *contextualprocess* or *packages* or some custom
|
||||
# module, in the `exec` section to do the actual work.
|
||||
method: legacy
|
||||
|
||||
|
||||
# Human-visible strings in this module. These are all optional.
|
||||
# The following translated keys are used:
|
||||
# - *step*, used in the overall progress view (left-hand pane)
|
||||
#
|
||||
# Each key can have a [locale] added to it, which is used as
|
||||
# the translated string for that locale. For the strings
|
||||
# associated with the "no-selection" item, see *items*, below
|
||||
# with the explicit item-*id* "".
|
||||
#
|
||||
labels:
|
||||
step: "Packages"
|
||||
step[nl]: "Pakketten"
|
||||
|
||||
# (Optional) item-*id* of pre-selected list-view item.
|
||||
# Pre-selects one of the items below.
|
||||
# default: kde
|
||||
|
||||
# Items to display in the chooser. In general, this should be a
|
||||
# pretty short list to avoid overwhelming the UI. This is a list
|
||||
# of objects, and the items are displayed in list order.
|
||||
#
|
||||
# Either provide the data for an item in the list (using the keys
|
||||
# below), or use existing AppData XML files, or use AppStream cache
|
||||
# as a source for the data.
|
||||
#
|
||||
# For data provided by the list: the item has an id, which is used in
|
||||
# setting the value of *packagechooser_<module-id>*. The following field
|
||||
# is mandatory:
|
||||
#
|
||||
# - *id*
|
||||
# ID for the product. The ID "" is special, and is used for
|
||||
# "no package selected". Only include this if the mode allows
|
||||
# selecting none. The name and description given for the "no package
|
||||
# selected" item are displayed when the module starts.
|
||||
#
|
||||
# Each item must adhere to one of three "styles" of item. Which styles
|
||||
# are supported depends on compile-time dependencies of Calamares.
|
||||
# Both AppData and AppStream may **optionally** be available.
|
||||
#
|
||||
# # Generic Items #
|
||||
#
|
||||
# These items are always supported. They require the most configuration
|
||||
# **in this file** and duplicate information that may be available elsewhere
|
||||
# (e.g. in AppData or AppStream), but do not require any additional
|
||||
# dependencies. These items have the following **mandatory** fields:
|
||||
#
|
||||
# - *name*
|
||||
# Human-readable name of the product. To provide translations,
|
||||
# add a *[lang]* decoration as part of the key name, e.g. `name[nl]`
|
||||
# for Dutch. The list of usable languages can be found in
|
||||
# `CMakeLists.txt` or as part of the debug output of Calamares.
|
||||
# - *description*
|
||||
# Human-readable description. These can be translated as well.
|
||||
# - *screenshot*
|
||||
# Path to a single screenshot of the product. May be a filesystem
|
||||
# path or a QRC path, e.g. ":/images/no-selection.png". If the path
|
||||
# is not found (e.g. is a non-existent absolute path, or is a relative
|
||||
# path that does not exist in the current working directory) then
|
||||
# an additional attempt is made to load the image from the **branding**
|
||||
# directory.
|
||||
#
|
||||
# The following fields are **optional** for an item:
|
||||
#
|
||||
# - *packages* :
|
||||
# List of package names for the product. If using the *method*
|
||||
# "packages", consider this item mandatory (because otherwise
|
||||
# selecting the item would install no packages).
|
||||
#
|
||||
# - *netinstall* :
|
||||
# The data in this field should follow the format of a group
|
||||
# from the netinstall module documented in
|
||||
# src/modules/netinstall/netinstall.conf. This is only used
|
||||
# when method is set to "netinstall-add"
|
||||
#
|
||||
# # AppData Items #
|
||||
#
|
||||
# For data provided by AppData XML: the item has an *appdata*
|
||||
# key which points to an AppData XML file in the local filesystem.
|
||||
# This file is parsed to provide the id (from AppData id), name
|
||||
# (from AppData name), description (from AppData description paragraphs
|
||||
# or the summary entries), and a screenshot (the default screenshot
|
||||
# from AppData). No package is set (but that is unused anyway).
|
||||
#
|
||||
# AppData may contain IDs that are not useful inside Calamares,
|
||||
# and the screenshot URL may be remote -- a remote URL will not
|
||||
# be loaded and the screenshot will be missing. An item with *appdata*
|
||||
# **may** specify an ID or screenshot path, as above. This will override
|
||||
# the settings from AppData.
|
||||
#
|
||||
# # AppStream Items #
|
||||
#
|
||||
# For data provided by AppStream cache: the item has an *appstream*
|
||||
# key which matches the AppStream identifier in the cache (e.g.
|
||||
# *org.kde.kwrite.desktop*). Data is retrieved from the AppStream
|
||||
# cache for that ID. The package name is set from the AppStream data.
|
||||
#
|
||||
# An item for AppStream may also contain an *id* and a *screenshot*
|
||||
# key which will override the data from AppStream.
|
||||
items:
|
||||
- id: ""
|
||||
# packages: [] # This item installs no packages
|
||||
name: "No Desktop"
|
||||
name[nl]: "Geen desktop"
|
||||
description: "Please pick a desktop environment from the list. If you don't want to install a desktop, that's fine, your system will start up in text-only mode and you can install a desktop environment later."
|
||||
description[nl]: "Kies eventueel een desktop-omgeving uit deze lijst. Als u geen desktop-omgeving wenst te gebruiken, kies er dan geen. In dat geval start het systeem straks op in tekst-modus en kunt u later alsnog een desktop-omgeving installeren."
|
||||
screenshot: ":/images/no-selection.png"
|
||||
- id: kde
|
||||
packages: [ kde-frameworks, kde-plasma, kde-gear ]
|
||||
name: Plasma Desktop
|
||||
description: "KDE Plasma Desktop, simple by default, a clean work area for real-world usage which intends to stay out of your way. Plasma is powerful when needed, enabling the user to create the workflow that makes them more effective to complete their tasks."
|
||||
screenshot: ":/images/kde.png"
|
||||
- id: gnome
|
||||
packages: [ gnome-all ]
|
||||
name: GNOME
|
||||
description: GNU Networked Object Modeling Environment Desktop
|
||||
screenshot: ":/images/gnome.png"
|
||||
- id: calamares
|
||||
appdata: ../io.calamares.calamares.appdata.xml
|
||||
screenshot: ":/images/calamares.png"
|
||||
- id: kate
|
||||
appstream: org.kde.kwrite.desktop
|
||||
@@ -1,5 +0,0 @@
|
||||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file>images/if.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
@@ -1,104 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<author>
|
||||
SPDX-FileCopyrightText: 2019 Adriaan de Groot <groot@kde.org>
|
||||
SPDX-License-Identifier: GPL-3.0-or-later
|
||||
</author>
|
||||
<class>PackageChooserPage</class>
|
||||
<widget class="QWidget" name="PackageChooserPage">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>400</width>
|
||||
<height>500</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>1</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string notr="true">Form</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout" stretch="1,4">
|
||||
<item>
|
||||
<widget class="QListView" name="products">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>1</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout" stretch="1,30,1">
|
||||
<item>
|
||||
<widget class="QLabel" name="productName">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Product Name</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="FixedAspectRatioLabel" name="productScreenshot">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>1</horstretch>
|
||||
<verstretch>1</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>TextLabel</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="productDescription">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Long Product Description</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="openExternalLinks">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>FixedAspectRatioLabel</class>
|
||||
<extends>QLabel</extends>
|
||||
<header>widgets/FixedAspectRatioLabel.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
@@ -1,69 +0,0 @@
|
||||
# === This file is part of Calamares - <https://calamares.io> ===
|
||||
#
|
||||
# SPDX-FileCopyrightText: 2020 Adriaan de Groot <groot@kde.org>
|
||||
# SPDX-FileCopyrightText: 2021 Anke Boersma <demm@kaosx.us>
|
||||
# SPDX-License-Identifier: BSD-2-Clause
|
||||
#
|
||||
if( NOT Calamares_WITH_QML )
|
||||
calamares_skip_module( "packagechooserq (QML is not supported in this build)" )
|
||||
return()
|
||||
endif()
|
||||
|
||||
find_package(${qtname} ${QT_VERSION} CONFIG REQUIRED Core)
|
||||
|
||||
# Add optional libraries here
|
||||
set(USER_EXTRA_LIB)
|
||||
|
||||
# include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/../packagechooser )
|
||||
set(_packagechooser ${CMAKE_CURRENT_SOURCE_DIR}/../packagechooser)
|
||||
include_directories(${_packagechooser})
|
||||
|
||||
### OPTIONAL AppData XML support in PackageModel
|
||||
#
|
||||
#
|
||||
option(BUILD_APPDATA "Support appdata: items in PackageChooser (requires QtXml)" ON)
|
||||
if(BUILD_APPDATA)
|
||||
find_package(${qtname} COMPONENTS Xml)
|
||||
if(TARGET ${qtname}::Xml)
|
||||
add_definitions(-DHAVE_APPDATA)
|
||||
list(APPEND _extra_libraries ${qtname}::Xml)
|
||||
list(APPEND _extra_src ${_packagechooser}/ItemAppData.cpp)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
### OPTIONAL AppStream support in PackageModel
|
||||
#
|
||||
#
|
||||
option(BUILD_APPSTREAM "Support appstream: items in PackageChooser (requires libappstream-qt)" ON)
|
||||
if(BUILD_APPSTREAM)
|
||||
find_package(AppStreamQt)
|
||||
set_package_properties(
|
||||
AppStreamQt
|
||||
PROPERTIES
|
||||
DESCRIPTION "Support for AppStream (cache) data"
|
||||
URL "https://github.com/ximion/appstream"
|
||||
PURPOSE "AppStream provides package data"
|
||||
TYPE OPTIONAL
|
||||
)
|
||||
if(AppStreamQt_FOUND)
|
||||
add_definitions(-DHAVE_APPSTREAM_VERSION=${AppStreamQt_VERSION_MAJOR})
|
||||
list(APPEND _extra_libraries AppStreamQt)
|
||||
list(APPEND _extra_src ${_packagechooser}/ItemAppStream.cpp)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
calamares_add_plugin(packagechooserq
|
||||
TYPE viewmodule
|
||||
EXPORT_MACRO PLUGINDLLEXPORT_PRO
|
||||
SOURCES
|
||||
PackageChooserQmlViewStep.cpp
|
||||
${_packagechooser}/Config.cpp
|
||||
${_packagechooser}/PackageModel.cpp
|
||||
${_extra_src}
|
||||
RESOURCES
|
||||
packagechooserq${QT_VERSION_SUFFIX}.qrc
|
||||
LINK_PRIVATE_LIBRARIES
|
||||
calamaresui
|
||||
${_extra_libraries}
|
||||
SHARED_LIB
|
||||
)
|
||||
@@ -1,86 +0,0 @@
|
||||
/* === This file is part of Calamares - <https://calamares.io> ===
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2019 Adriaan de Groot <groot@kde.org>
|
||||
* SPDX-FileCopyrightText: 2021 Anke Boersma <demm@kaosx.us>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* Calamares is Free Software: see the License-Identifier above.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "PackageChooserQmlViewStep.h"
|
||||
|
||||
#include "GlobalStorage.h"
|
||||
#include "JobQueue.h"
|
||||
#include "locale/TranslatableConfiguration.h"
|
||||
#include "utils/Logger.h"
|
||||
#include "utils/System.h"
|
||||
#include "utils/Variant.h"
|
||||
|
||||
CALAMARES_PLUGIN_FACTORY_DEFINITION( PackageChooserQmlViewStepFactory, registerPlugin< PackageChooserQmlViewStep >(); )
|
||||
|
||||
PackageChooserQmlViewStep::PackageChooserQmlViewStep( QObject* parent )
|
||||
: Calamares::QmlViewStep( parent )
|
||||
, m_config( new Config( this ) )
|
||||
{
|
||||
emit nextStatusChanged( true );
|
||||
}
|
||||
|
||||
QString
|
||||
PackageChooserQmlViewStep::prettyName() const
|
||||
{
|
||||
return m_config->prettyName();
|
||||
}
|
||||
|
||||
QString
|
||||
PackageChooserQmlViewStep::prettyStatus() const
|
||||
{
|
||||
//QString option = m_pkgc;
|
||||
//return tr( "Install option: %1" ).arg( option );
|
||||
return m_config->prettyStatus();
|
||||
}
|
||||
|
||||
bool
|
||||
PackageChooserQmlViewStep::isNextEnabled() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
PackageChooserQmlViewStep::isBackEnabled() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
PackageChooserQmlViewStep::isAtBeginning() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
PackageChooserQmlViewStep::isAtEnd() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
Calamares::JobList
|
||||
PackageChooserQmlViewStep::jobs() const
|
||||
{
|
||||
Calamares::JobList l;
|
||||
return l;
|
||||
}
|
||||
|
||||
void
|
||||
PackageChooserQmlViewStep::onLeave()
|
||||
{
|
||||
m_config->updateGlobalStorage();
|
||||
}
|
||||
|
||||
void
|
||||
PackageChooserQmlViewStep::setConfigurationMap( const QVariantMap& configurationMap )
|
||||
{
|
||||
m_config->setDefaultId( moduleInstanceKey() );
|
||||
m_config->setConfigurationMap( configurationMap );
|
||||
Calamares::QmlViewStep::setConfigurationMap( configurationMap ); // call parent implementation last
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
/* === This file is part of Calamares - <https://calamares.io> ===
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2019 Adriaan de Groot <groot@kde.org>
|
||||
* SPDX-FileCopyrightText: 2021 Anke Boersma <demm@kaosx.us>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* Calamares is Free Software: see the License-Identifier above.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef PACKAGECHOOSERQMLVIEWSTEP_H
|
||||
#define PACKAGECHOOSERQMLVIEWSTEP_H
|
||||
|
||||
// Config from packagechooser module
|
||||
#include "Config.h"
|
||||
|
||||
#include "DllMacro.h"
|
||||
#include "locale/TranslatableConfiguration.h"
|
||||
#include "utils/PluginFactory.h"
|
||||
#include "viewpages/QmlViewStep.h"
|
||||
|
||||
#include <QVariantMap>
|
||||
|
||||
class Config;
|
||||
class PackageChooserPage;
|
||||
|
||||
class PLUGINDLLEXPORT PackageChooserQmlViewStep : public Calamares::QmlViewStep
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit PackageChooserQmlViewStep( QObject* parent = nullptr );
|
||||
|
||||
QString prettyName() const override;
|
||||
QString prettyStatus() const override;
|
||||
|
||||
bool isNextEnabled() const override;
|
||||
bool isBackEnabled() const override;
|
||||
|
||||
bool isAtBeginning() const override;
|
||||
bool isAtEnd() const override;
|
||||
|
||||
//void onActivate() override;
|
||||
void onLeave() override;
|
||||
|
||||
Calamares::JobList jobs() const override;
|
||||
|
||||
void setConfigurationMap( const QVariantMap& configurationMap ) override;
|
||||
|
||||
QObject* getConfig() override { return m_config; }
|
||||
|
||||
private:
|
||||
Config* m_config;
|
||||
};
|
||||
|
||||
CALAMARES_PLUGIN_FACTORY_DECLARATION( PackageChooserQmlViewStepFactory )
|
||||
|
||||
#endif // PACKAGECHOOSERQMLVIEWSTEP_H
|
||||
|
Before Width: | Height: | Size: 20 KiB |
@@ -1,2 +0,0 @@
|
||||
SPDX-FileCopyrightText: 2020 demmm <anke62@gmail.com>
|
||||
SPDX-License-Identifier: GPL-3.0-or-later
|
||||
@@ -1,304 +0,0 @@
|
||||
/* === This file is part of Calamares - <https://calamares.io> ===
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2021 Anke Boersma <demm@kaosx.us>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* Calamares is Free Software: see the License-Identifier above.
|
||||
*
|
||||
*/
|
||||
|
||||
import io.calamares.core 1.0
|
||||
import io.calamares.ui 1.0
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
|
||||
Item {
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: "#f2f2f2"
|
||||
|
||||
ButtonGroup {
|
||||
id: switchGroup
|
||||
}
|
||||
|
||||
Column {
|
||||
id: column
|
||||
anchors.centerIn: parent
|
||||
spacing: 5
|
||||
|
||||
Rectangle {
|
||||
//id: rectangle
|
||||
width: 700
|
||||
height: 150
|
||||
color: "#ffffff"
|
||||
radius: 10
|
||||
border.width: 0
|
||||
Text {
|
||||
width: 450
|
||||
height: 104
|
||||
anchors.centerIn: parent
|
||||
text: qsTr("OpenRC base system.<br/>
|
||||
Default option.")
|
||||
font.pointSize: 10
|
||||
anchors.verticalCenterOffset: -10
|
||||
anchors.horizontalCenterOffset: 100
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
|
||||
Switch {
|
||||
id: element1
|
||||
x: 500
|
||||
y: 110
|
||||
width: 187
|
||||
height: 14
|
||||
text: qsTr("OpenRC")
|
||||
checked: true
|
||||
hoverEnabled: true
|
||||
ButtonGroup.group: switchGroup
|
||||
|
||||
indicator: Rectangle {
|
||||
implicitWidth: 40
|
||||
implicitHeight: 14
|
||||
radius: 10
|
||||
color: element1.checked ? "#3498db" : "#B9B9B9"
|
||||
border.color: element1.checked ? "#3498db" : "#cccccc"
|
||||
|
||||
Rectangle {
|
||||
x: element1.checked ? parent.width - width : 0
|
||||
y: (parent.height - height) / 2
|
||||
width: 20
|
||||
height: 20
|
||||
radius: 10
|
||||
color: element1.down ? "#cccccc" : "#ffffff"
|
||||
border.color: element1.checked ? (element1.down ? "#3498db" : "#3498db") : "#999999"
|
||||
}
|
||||
}
|
||||
|
||||
onCheckedChanged: {
|
||||
if ( checked ) {
|
||||
config.packageChoice = "openrc"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Image {
|
||||
id: image1
|
||||
x: 8
|
||||
y: 25
|
||||
height: 100
|
||||
fillMode: Image.PreserveAspectFit
|
||||
source: "images/if.png"
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: 700
|
||||
height: 150
|
||||
radius: 10
|
||||
border.width: 0
|
||||
Text {
|
||||
width: 450
|
||||
height: 104
|
||||
anchors.centerIn: parent
|
||||
text: qsTr("Dinit base system.")
|
||||
font.pointSize: 10
|
||||
anchors.verticalCenterOffset: -10
|
||||
anchors.horizontalCenterOffset: 100
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
|
||||
Switch {
|
||||
id: element2
|
||||
x: 500
|
||||
y: 110
|
||||
width: 187
|
||||
height: 14
|
||||
text: qsTr("Dinit")
|
||||
checked: false
|
||||
hoverEnabled: true
|
||||
ButtonGroup.group: switchGroup
|
||||
|
||||
indicator: Rectangle {
|
||||
implicitWidth: 40
|
||||
implicitHeight: 14
|
||||
radius: 10
|
||||
color: element2.checked ? "#3498db" : "#B9B9B9"
|
||||
border.color: element2.checked ? "#3498db" : "#cccccc"
|
||||
|
||||
Rectangle {
|
||||
x: element2.checked ? parent.width - width : 0
|
||||
y: (parent.height - height) / 2
|
||||
width: 20
|
||||
height: 20
|
||||
radius: 10
|
||||
color: element2.down ? "#cccccc" : "#ffffff"
|
||||
border.color: element2.checked ? (element2.down ? "#3498db" : "#3498db") : "#999999"
|
||||
}
|
||||
}
|
||||
|
||||
onCheckedChanged: {
|
||||
if ( checked ) {
|
||||
config.packageChoice = "dinit"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Image {
|
||||
id: image2
|
||||
x: 8
|
||||
y: 25
|
||||
height: 100
|
||||
fillMode: Image.PreserveAspectFit
|
||||
source: "images/if.png"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: 700
|
||||
height: 150
|
||||
color: "#ffffff"
|
||||
radius: 10
|
||||
border.width: 0
|
||||
Text {
|
||||
width: 450
|
||||
height: 104
|
||||
anchors.centerIn: parent
|
||||
text: qsTr("Runit base system.")
|
||||
font.pointSize: 10
|
||||
anchors.verticalCenterOffset: -10
|
||||
anchors.horizontalCenterOffset: 100
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
|
||||
Switch {
|
||||
id: element3
|
||||
x: 500
|
||||
y: 110
|
||||
width: 187
|
||||
height: 14
|
||||
text: qsTr("Runit")
|
||||
checked: false
|
||||
hoverEnabled: true
|
||||
ButtonGroup.group: switchGroup
|
||||
|
||||
indicator: Rectangle {
|
||||
implicitWidth: 40
|
||||
implicitHeight: 14
|
||||
radius: 10
|
||||
color: element3.checked ? "#3498db" : "#B9B9B9"
|
||||
border.color: element3.checked ? "#3498db" : "#cccccc"
|
||||
|
||||
Rectangle {
|
||||
x: element3.checked ? parent.width - width : 0
|
||||
y: (parent.height - height) / 2
|
||||
width: 20
|
||||
height: 20
|
||||
radius: 10
|
||||
color: element3.down ? "#cccccc" : "#ffffff"
|
||||
border.color: element3.checked ? (element3.down ? "#3498db" : "#3498db") : "#999999"
|
||||
}
|
||||
}
|
||||
|
||||
onCheckedChanged: {
|
||||
if ( checked ) {
|
||||
config.packageChoice = "runit"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Image {
|
||||
id: image3
|
||||
x: 8
|
||||
y: 25
|
||||
height: 100
|
||||
fillMode: Image.PreserveAspectFit
|
||||
source: "images/if.png"
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: 700
|
||||
height: 150
|
||||
color: "#ffffff"
|
||||
radius: 10
|
||||
border.width: 0
|
||||
Text {
|
||||
width: 450
|
||||
height: 104
|
||||
anchors.centerIn: parent
|
||||
text: qsTr("S6 base system.")
|
||||
font.pointSize: 10
|
||||
anchors.verticalCenterOffset: -10
|
||||
anchors.horizontalCenterOffset: 100
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
|
||||
Switch {
|
||||
id: element4
|
||||
x: 500
|
||||
y: 110
|
||||
width: 187
|
||||
height: 14
|
||||
text: qsTr("S6")
|
||||
checked: false
|
||||
hoverEnabled: true
|
||||
ButtonGroup.group: switchGroup
|
||||
|
||||
indicator: Rectangle {
|
||||
implicitWidth: 40
|
||||
implicitHeight: 14
|
||||
radius: 10
|
||||
color: element4.checked ? "#3498db" : "#B9B9B9"
|
||||
border.color: element4.checked ? "#3498db" : "#cccccc"
|
||||
|
||||
Rectangle {
|
||||
x: element4.checked ? parent.width - width : 0
|
||||
y: (parent.height - height) / 2
|
||||
width: 20
|
||||
height: 20
|
||||
radius: 10
|
||||
color: element4.down ? "#cccccc" : "#ffffff"
|
||||
border.color: element4.checked ? (element4.down ? "#3498db" : "#3498db") : "#999999"
|
||||
}
|
||||
}
|
||||
|
||||
onCheckedChanged: {
|
||||
if ( checked ) {
|
||||
config.packageChoice = "s6"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Image {
|
||||
id: image4
|
||||
x: 8
|
||||
y: 25
|
||||
height: 100
|
||||
fillMode: Image.PreserveAspectFit
|
||||
source: "images/if.png"
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: 700
|
||||
height: 25
|
||||
color: "#f2f2f2"
|
||||
border.width: 0
|
||||
Text {
|
||||
height: 25
|
||||
anchors.centerIn: parent
|
||||
text: qsTr("Please select an option for your install, or use the default: OpenRC.")
|
||||
font.pointSize: 10
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
<RCC>
|
||||
<qresource>
|
||||
<file alias="packagechooserq.qml">packagechooserq-qt6.qml</file>
|
||||
<file>images/if.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
@@ -1,66 +0,0 @@
|
||||
# SPDX-FileCopyrightText: no
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
#
|
||||
# Configuration for the low-density software chooser, QML implementation
|
||||
#
|
||||
# The example QML implementation uses single-selection, rather than
|
||||
# a model for the available packages. That makes it simpler: the
|
||||
# QML itself codes the available options, descriptions and images
|
||||
# -- after all, this is **low density** selection, so a custom UI
|
||||
# can make sense for the few choices that need to be made.
|
||||
#
|
||||
#
|
||||
|
||||
---
|
||||
# Software installation method:
|
||||
#
|
||||
# - "legacy" or "custom" or "contextualprocess"
|
||||
# When set to "legacy", writes a GlobalStorage value for the choice that
|
||||
# has been made. The key is *packagechooser_<id>*. The module's
|
||||
# instance name is used; see the *instances* section of `settings.conf`.
|
||||
# If there is just one packagechooserq module, and no special instance is set,
|
||||
# resulting GS key is probably *packagechooser_packagechooserq*.
|
||||
# (Do note that the prefix of the GS key remains "packagechooser_")
|
||||
#
|
||||
# The GS value is a comma-separated list of the IDs of the selected
|
||||
# packages, or an empty string if none is selected.
|
||||
#
|
||||
# With "legacy" installation, you should have a contextualprocess or similar
|
||||
# module somewhere in the `exec` phase to process the GlobalStorage key
|
||||
# and actually **do** something for the packages.
|
||||
#
|
||||
# - "packages"
|
||||
# When set to "packages", writes GlobalStorage values suitable for
|
||||
# consumption by the *packages* module (which should appear later
|
||||
# in the `exec` section. These package settings will then be handed
|
||||
# off to whatever package manager is configured there.
|
||||
#
|
||||
# There is no need to put this module in the `exec` section. There
|
||||
# are no jobs that this module provides. You should put **other**
|
||||
# modules, either *contextualprocess* or *packages* or some custom
|
||||
# module, in the `exec` section to do the actual work.
|
||||
#
|
||||
method: legacy
|
||||
|
||||
# Human-visible strings in this module. These are all optional.
|
||||
# The following translated keys are used:
|
||||
# - *step*, used in the overall progress view (left-hand pane)
|
||||
#
|
||||
# Each key can have a [locale] added to it, which is used as
|
||||
# the translated string for that locale. For the strings
|
||||
# associated with the "no-selection" item, see *items*, below
|
||||
# with the explicit item-*id* "".
|
||||
#
|
||||
labels:
|
||||
step: "Packages"
|
||||
step[nl]: "Pakketten"
|
||||
|
||||
# The *packageChoice* value is used for setting the default selection
|
||||
# in the QML view; this should match one of the keys used in the QML
|
||||
# module for package names.
|
||||
#
|
||||
# (e.g. the sample QML uses "no_office_suite", "minimal_install" and
|
||||
# "libreoffice" as possible choices).
|
||||
#
|
||||
packageChoice: libreoffice
|
||||
|
||||
@@ -1,304 +0,0 @@
|
||||
/* === This file is part of Calamares - <https://calamares.io> ===
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2021 Anke Boersma <demm@kaosx.us>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* Calamares is Free Software: see the License-Identifier above.
|
||||
*
|
||||
*/
|
||||
|
||||
import io.calamares.core 1.0
|
||||
import io.calamares.ui 1.0
|
||||
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15
|
||||
import QtQuick.Layouts 1.3
|
||||
|
||||
Item {
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
color: "#f2f2f2"
|
||||
|
||||
ButtonGroup {
|
||||
id: switchGroup
|
||||
}
|
||||
|
||||
Column {
|
||||
id: column
|
||||
anchors.centerIn: parent
|
||||
spacing: 5
|
||||
|
||||
Rectangle {
|
||||
//id: rectangle
|
||||
width: 700
|
||||
height: 150
|
||||
color: "#ffffff"
|
||||
radius: 10
|
||||
border.width: 0
|
||||
Text {
|
||||
width: 450
|
||||
height: 104
|
||||
anchors.centerIn: parent
|
||||
text: qsTr("OpenRC base system.<br/>
|
||||
Default option.")
|
||||
font.pointSize: 10
|
||||
anchors.verticalCenterOffset: -10
|
||||
anchors.horizontalCenterOffset: 100
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
|
||||
Switch {
|
||||
id: element1
|
||||
x: 500
|
||||
y: 110
|
||||
width: 187
|
||||
height: 14
|
||||
text: qsTr("OpenRC")
|
||||
checked: true
|
||||
hoverEnabled: true
|
||||
ButtonGroup.group: switchGroup
|
||||
|
||||
indicator: Rectangle {
|
||||
implicitWidth: 40
|
||||
implicitHeight: 14
|
||||
radius: 10
|
||||
color: element1.checked ? "#3498db" : "#B9B9B9"
|
||||
border.color: element1.checked ? "#3498db" : "#cccccc"
|
||||
|
||||
Rectangle {
|
||||
x: element1.checked ? parent.width - width : 0
|
||||
y: (parent.height - height) / 2
|
||||
width: 20
|
||||
height: 20
|
||||
radius: 10
|
||||
color: element1.down ? "#cccccc" : "#ffffff"
|
||||
border.color: element1.checked ? (element1.down ? "#3498db" : "#3498db") : "#999999"
|
||||
}
|
||||
}
|
||||
|
||||
onCheckedChanged: {
|
||||
if ( checked ) {
|
||||
config.packageChoice = "openrc"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Image {
|
||||
id: image1
|
||||
x: 8
|
||||
y: 25
|
||||
height: 100
|
||||
fillMode: Image.PreserveAspectFit
|
||||
source: "images/if.png"
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: 700
|
||||
height: 150
|
||||
radius: 10
|
||||
border.width: 0
|
||||
Text {
|
||||
width: 450
|
||||
height: 104
|
||||
anchors.centerIn: parent
|
||||
text: qsTr("Dinit base system.")
|
||||
font.pointSize: 10
|
||||
anchors.verticalCenterOffset: -10
|
||||
anchors.horizontalCenterOffset: 100
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
|
||||
Switch {
|
||||
id: element2
|
||||
x: 500
|
||||
y: 110
|
||||
width: 187
|
||||
height: 14
|
||||
text: qsTr("Dinit")
|
||||
checked: false
|
||||
hoverEnabled: true
|
||||
ButtonGroup.group: switchGroup
|
||||
|
||||
indicator: Rectangle {
|
||||
implicitWidth: 40
|
||||
implicitHeight: 14
|
||||
radius: 10
|
||||
color: element2.checked ? "#3498db" : "#B9B9B9"
|
||||
border.color: element2.checked ? "#3498db" : "#cccccc"
|
||||
|
||||
Rectangle {
|
||||
x: element2.checked ? parent.width - width : 0
|
||||
y: (parent.height - height) / 2
|
||||
width: 20
|
||||
height: 20
|
||||
radius: 10
|
||||
color: element2.down ? "#cccccc" : "#ffffff"
|
||||
border.color: element2.checked ? (element2.down ? "#3498db" : "#3498db") : "#999999"
|
||||
}
|
||||
}
|
||||
|
||||
onCheckedChanged: {
|
||||
if ( checked ) {
|
||||
config.packageChoice = "dinit"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Image {
|
||||
id: image2
|
||||
x: 8
|
||||
y: 25
|
||||
height: 100
|
||||
fillMode: Image.PreserveAspectFit
|
||||
source: "images/if.png"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: 700
|
||||
height: 150
|
||||
color: "#ffffff"
|
||||
radius: 10
|
||||
border.width: 0
|
||||
Text {
|
||||
width: 450
|
||||
height: 104
|
||||
anchors.centerIn: parent
|
||||
text: qsTr("Runit base system.")
|
||||
font.pointSize: 10
|
||||
anchors.verticalCenterOffset: -10
|
||||
anchors.horizontalCenterOffset: 100
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
|
||||
Switch {
|
||||
id: element3
|
||||
x: 500
|
||||
y: 110
|
||||
width: 187
|
||||
height: 14
|
||||
text: qsTr("Runit")
|
||||
checked: false
|
||||
hoverEnabled: true
|
||||
ButtonGroup.group: switchGroup
|
||||
|
||||
indicator: Rectangle {
|
||||
implicitWidth: 40
|
||||
implicitHeight: 14
|
||||
radius: 10
|
||||
color: element3.checked ? "#3498db" : "#B9B9B9"
|
||||
border.color: element3.checked ? "#3498db" : "#cccccc"
|
||||
|
||||
Rectangle {
|
||||
x: element3.checked ? parent.width - width : 0
|
||||
y: (parent.height - height) / 2
|
||||
width: 20
|
||||
height: 20
|
||||
radius: 10
|
||||
color: element3.down ? "#cccccc" : "#ffffff"
|
||||
border.color: element3.checked ? (element3.down ? "#3498db" : "#3498db") : "#999999"
|
||||
}
|
||||
}
|
||||
|
||||
onCheckedChanged: {
|
||||
if ( checked ) {
|
||||
config.packageChoice = "runit"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Image {
|
||||
id: image3
|
||||
x: 8
|
||||
y: 25
|
||||
height: 100
|
||||
fillMode: Image.PreserveAspectFit
|
||||
source: "images/if.png"
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: 700
|
||||
height: 150
|
||||
color: "#ffffff"
|
||||
radius: 10
|
||||
border.width: 0
|
||||
Text {
|
||||
width: 450
|
||||
height: 104
|
||||
anchors.centerIn: parent
|
||||
text: qsTr("S6 base system.")
|
||||
font.pointSize: 10
|
||||
anchors.verticalCenterOffset: -10
|
||||
anchors.horizontalCenterOffset: 100
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
|
||||
Switch {
|
||||
id: element4
|
||||
x: 500
|
||||
y: 110
|
||||
width: 187
|
||||
height: 14
|
||||
text: qsTr("S6")
|
||||
checked: false
|
||||
hoverEnabled: true
|
||||
ButtonGroup.group: switchGroup
|
||||
|
||||
indicator: Rectangle {
|
||||
implicitWidth: 40
|
||||
implicitHeight: 14
|
||||
radius: 10
|
||||
color: element4.checked ? "#3498db" : "#B9B9B9"
|
||||
border.color: element4.checked ? "#3498db" : "#cccccc"
|
||||
|
||||
Rectangle {
|
||||
x: element4.checked ? parent.width - width : 0
|
||||
y: (parent.height - height) / 2
|
||||
width: 20
|
||||
height: 20
|
||||
radius: 10
|
||||
color: element4.down ? "#cccccc" : "#ffffff"
|
||||
border.color: element4.checked ? (element4.down ? "#3498db" : "#3498db") : "#999999"
|
||||
}
|
||||
}
|
||||
|
||||
onCheckedChanged: {
|
||||
if ( checked ) {
|
||||
config.packageChoice = "s6"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Image {
|
||||
id: image4
|
||||
x: 8
|
||||
y: 25
|
||||
height: 100
|
||||
fillMode: Image.PreserveAspectFit
|
||||
source: "images/if.png"
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
width: 700
|
||||
height: 25
|
||||
color: "#f2f2f2"
|
||||
border.width: 0
|
||||
Text {
|
||||
height: 25
|
||||
anchors.centerIn: parent
|
||||
text: qsTr("Please select an option for your install, or use the default: OpenRC.")
|
||||
font.pointSize: 10
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
<RCC>
|
||||
<qresource>
|
||||
<file>packagechooserq.qml</file>
|
||||
<file>images/if.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
@@ -27,54 +27,191 @@ import libcalamares
|
||||
from libcalamares.utils import target_env_call
|
||||
|
||||
|
||||
class ConfigController:
|
||||
"""Configuration controller
|
||||
import gettext
|
||||
_ = gettext.translation("calamares-python",
|
||||
localedir=libcalamares.utils.gettext_path(),
|
||||
languages=libcalamares.utils.gettext_languages(),
|
||||
fallback=True).gettext
|
||||
|
||||
|
||||
def pretty_name():
|
||||
return _("Configure user services")
|
||||
|
||||
|
||||
def terminate(proc):
|
||||
"""Send SIGKILL to the given proccess
|
||||
"""
|
||||
target_env_call(['killall', '-9', proc])
|
||||
|
||||
def sedFile(pattern, file):
|
||||
"""Sed the given file with the given pattern
|
||||
"""
|
||||
target_env_call(["sed", "-e", pattern, "-i", file])
|
||||
|
||||
def configure(initsys):
|
||||
"""Configure the services
|
||||
"""
|
||||
if initsys == "openrc":
|
||||
exp = 's|^.*keymap=.*|keymap="{}"|'.format(
|
||||
libcalamares.globalstorage.value("keyboardLayout")
|
||||
)
|
||||
sedFile(exp, "/etc/conf.d/keymaps")
|
||||
|
||||
def fix_btrfs_boot(root):
|
||||
if exists(join(root, "usr/bin/dd")):
|
||||
|
||||
ec = target_env_call(["sh", "-c", 'mkdir -p /tmp/vmlinuz-hack && mv /boot/vmlinuz-* /tmp/vmlinuz-hack/ && find /tmp/vmlinuz-hack/ -maxdepth 1 -type f -exec sh -c \'dd if="$1" of="/boot/$(basename "$1")"\' sh {} \;'])
|
||||
|
||||
if ec != 0:
|
||||
libcalamares.utils.warning(
|
||||
"dd {} call in chroot returned error code {}".format("/boot", ec)
|
||||
)
|
||||
|
||||
if exists(join(root, "boot/intel-ucode.img")):
|
||||
ec = target_env_call(["sh", "-c", 'mkdir -p /tmp/intel-hack && mv /boot/intel-ucode.img /tmp/intel-hack/ && find /tmp/intel-hack/ -maxdepth 1 -type f -exec sh -c \'dd if="$1" of="/boot/$(basename "$1")"\' sh {} \;'])
|
||||
|
||||
if ec != 0:
|
||||
libcalamares.utils.warning(
|
||||
"dd {} call in chroot returned error code {}".format("/boot", ec)
|
||||
)
|
||||
|
||||
if exists(join(root, "boot/amd-ucode.img")):
|
||||
ec = target_env_call(["sh", "-c", 'mkdir -p /tmp/amd-hack && mv /boot/amd-ucode.img /tmp/amd-hack/ && find /tmp/amd-hack/ -maxdepth 1 -type f -exec sh -c \'dd if="$1" of="/boot/$(basename "$1")"\' sh {} \;'])
|
||||
|
||||
if ec != 0:
|
||||
libcalamares.utils.warning(
|
||||
"dd {} call in chroot returned error code {}".format("/boot", ec)
|
||||
)
|
||||
|
||||
|
||||
def manage_services(services, initsys, root):
|
||||
"""
|
||||
For each entry in @p services, run "<command> <action> <name>",
|
||||
where each service is a mapping of service name, action, and a flag.
|
||||
|
||||
Returns a failure message, or None if this was successful.
|
||||
"""
|
||||
|
||||
def __init__(self):
|
||||
self.root = libcalamares.globalstorage.value("rootMountPoint")
|
||||
username = libcalamares.globalstorage.value("username")
|
||||
|
||||
def terminate(self, proc):
|
||||
"""Send SIGKILL to the given proccess
|
||||
"""
|
||||
target_env_call(['killall', '-9', proc])
|
||||
userhome = "/home/" + username
|
||||
|
||||
def sedFile(self, pattern, file):
|
||||
"""Sed the given file with the given pattern
|
||||
"""
|
||||
target_env_call(["sed", "-e", pattern, "-i", file])
|
||||
owner = username + ":" + username
|
||||
|
||||
def configure(self):
|
||||
"""Configure the services
|
||||
"""
|
||||
if exists(join(self.root, "/etc/conf.d/keymaps")):
|
||||
exp = 's|^.*keymap=.*|keymap="{}"|'.format(
|
||||
libcalamares.globalstorage.value("keyboardLayout")
|
||||
if initsys == "openrc":
|
||||
|
||||
dir_path = userhome + "/.config/rc/runlevels/default"
|
||||
|
||||
ec = target_env_call(["mkdir", "-p", dir_path])
|
||||
|
||||
if ec != 0:
|
||||
libcalamares.utils.warning(
|
||||
"create dir {} call in chroot returned error code {}".format(dir_path, ec)
|
||||
)
|
||||
self.sedFile(exp, "/etc/conf.d/keymaps")
|
||||
|
||||
if exists(join(self.root, "/etc/conf.d/xdm")):
|
||||
for dm in libcalamares.globalstorage.value("displayManagers"):
|
||||
exp = 's|^.*DISPLAYMANAGER=.*|DISPLAYMANAGER="{}"|'.format(dm)
|
||||
self.sedFile(exp, "/etc/conf.d/xdm")
|
||||
elif initsys == "dinit":
|
||||
|
||||
dir_path = userhome + "/.config/dinit.d/boot.d"
|
||||
|
||||
ec = target_env_call(["mkdir", "-p", dir_path])
|
||||
|
||||
if ec != 0:
|
||||
libcalamares.utils.warning(
|
||||
"create dir {} call in chroot returned error code {}".format(dir_path, ec)
|
||||
)
|
||||
|
||||
for sv in services:
|
||||
if isinstance(sv, str):
|
||||
name = sv
|
||||
action = "enable"
|
||||
else:
|
||||
if "name" not in sv:
|
||||
libcalamares.utils.error("The key 'name' is missing from the mapping {_sv!s}. Continuing to the next service.".format(_sv=str(sv)))
|
||||
continue
|
||||
name = sv["name"]
|
||||
action = sv.get("action", "enable")
|
||||
|
||||
if initsys == "openrc":
|
||||
|
||||
svhome = userhome + "/.config/rc"
|
||||
|
||||
src = "/etc/user/init.d/" + name
|
||||
urlvl = svhome + "/runlevels/default/"
|
||||
dest = urlvl + name
|
||||
|
||||
if action == "enable":
|
||||
|
||||
if exists(join(root, src)):
|
||||
|
||||
ec = target_env_call(["ln", "-s", src, dest])
|
||||
|
||||
if ec != 0:
|
||||
libcalamares.utils.warning(
|
||||
"service {} call in chroot returned error code {}".format(action, ec)
|
||||
)
|
||||
|
||||
|
||||
def run(self):
|
||||
"""Run the controller
|
||||
ec = target_env_call(["chown", "-R", owner, svhome ])
|
||||
|
||||
Workaround for pacman-key bug
|
||||
FS#45351 https://bugs.archlinux.org/task/45351
|
||||
We have to kill gpg-agent because if it stays
|
||||
around we can't reliably unmount
|
||||
the target partition.
|
||||
"""
|
||||
self.configure()
|
||||
self.terminate('gpg-agent')
|
||||
if ec != 0:
|
||||
libcalamares.utils.warning(
|
||||
"chown {} call in chroot returned error code {}".format(svhome, ec)
|
||||
)
|
||||
|
||||
elif initsys == "dinit":
|
||||
|
||||
svhome = userhome + "/.config/dinit.d"
|
||||
|
||||
src = "/etc/dinit.d/user/" + name
|
||||
ubdir = svhome + "/boot.d/"
|
||||
dest = ubdir + name
|
||||
|
||||
if action == "enable":
|
||||
|
||||
if exists(join(root, src)):
|
||||
|
||||
ec = target_env_call(["ln", "-s", src, dest])
|
||||
|
||||
if ec != 0:
|
||||
libcalamares.utils.warning(
|
||||
"service {} call in chroot returned error code {}".format(action, ec)
|
||||
)
|
||||
|
||||
ec = target_env_call(["chown", "-R", owner, svhome])
|
||||
|
||||
if ec != 0:
|
||||
libcalamares.utils.warning(
|
||||
"chown {} call in chroot returned error code {}".format(svhome, ec)
|
||||
)
|
||||
|
||||
|
||||
def run():
|
||||
""" Misc postinstall configurations """
|
||||
"""
|
||||
Misc postinstall configurations
|
||||
"""
|
||||
|
||||
config = ConfigController()
|
||||
install_root = libcalamares.globalstorage.value("rootMountPoint")
|
||||
|
||||
return config.run()
|
||||
initsys = libcalamares.job.configuration["initsys"]
|
||||
|
||||
userservices = libcalamares.job.configuration.get("user-services", [])
|
||||
|
||||
partitions = libcalamares.globalstorage.value("partitions")
|
||||
|
||||
configure(initsys)
|
||||
|
||||
has_btrfs = False
|
||||
|
||||
for partition in partitions:
|
||||
if partition["fs"] == "btrfs":
|
||||
has_btrfs = True
|
||||
|
||||
if has_btrfs:
|
||||
fix_btrfs_boot(install_root)
|
||||
|
||||
# terminate('gpg-agent')
|
||||
|
||||
r = manage_services(userservices, initsys, install_root)
|
||||
|
||||
if r is not None:
|
||||
return r
|
||||
|
||||
@@ -4,4 +4,4 @@ type: "job"
|
||||
name: "postcfg"
|
||||
interface: "python"
|
||||
script: "main.py" #assumed relative to the current directory
|
||||
noconfig: true
|
||||
noconfig: false
|
||||
|
||||
11
modules/postcfg/postcfg.conf
Normal file
@@ -0,0 +1,11 @@
|
||||
---
|
||||
initsys: openrc
|
||||
user-services:
|
||||
- name: dbus
|
||||
action: enable
|
||||
- name: pipewire
|
||||
action: enable
|
||||
- name: pipewire-pulse
|
||||
action: enable
|
||||
- name: wireplumber
|
||||
action: enable
|
||||
19
scripts/calamares-config-switcher
Normal file
@@ -0,0 +1,19 @@
|
||||
#!/bin/bash
|
||||
|
||||
readonly conf=/etc/calamares-config-switcher.conf
|
||||
|
||||
if [[ -f "${conf}" ]]; then
|
||||
# shellcheck source=/etc/calamares-config-switcher.conf
|
||||
. "${conf}"
|
||||
fi
|
||||
|
||||
title=${title:-"Switcher"}
|
||||
text=${text:-"Select:"}
|
||||
if [[ -z "${configs[*]}" ]]; then
|
||||
configs=(offline online)
|
||||
fi
|
||||
|
||||
select=$(kdialog --title "${title}" --combobox "${text}" "${configs[@]}" --default "${configs[0]}") || exit 1
|
||||
|
||||
pkexec ln -snf /etc/calamares-"$select" /etc/calamares
|
||||
pkexec calamares "$@"
|
||||
8
scripts/calamares-config-switcher.conf
Normal file
@@ -0,0 +1,8 @@
|
||||
#!/hint/bash
|
||||
# calamares config switcher configuration
|
||||
|
||||
title="Switcher"
|
||||
|
||||
text="Select calamares configuration:<br><br>Online is experimental, go with offline.<br>"
|
||||
|
||||
configs=(offline online)
|
||||
243
scripts/calamares-config-switcher.desktop
Normal file
@@ -0,0 +1,243 @@
|
||||
[Desktop Entry]
|
||||
Type=Application
|
||||
Version=1.0
|
||||
Name=Install Artix
|
||||
GenericName=System Installer
|
||||
Keywords=calamares;system;installer;
|
||||
TryExec=calamares-config-switcher
|
||||
Exec=calamares-config-switcher
|
||||
Comment=Calamares — System Installer
|
||||
Icon=artixlinux-logo
|
||||
Terminal=false
|
||||
StartupNotify=true
|
||||
Categories=Qt;System;
|
||||
X-AppStream-Ignore=true
|
||||
|
||||
Name[ar]=تثبيت النظام
|
||||
Icon[ar]=كالامارس
|
||||
GenericName[ar]=مثبت النظام
|
||||
Comment[ar]=كالامارس - مثبت النظام
|
||||
Name[as]=চিছটেম ইনস্তল কৰক
|
||||
Icon[as]=কেলামাৰেচ
|
||||
GenericName[as]=চিছটেম ইনস্তলাৰ
|
||||
Comment[as]=কেলামাৰেচ — চিছটেম ইনস্তলাৰ
|
||||
Name[ast]=Instalar el sistema
|
||||
Icon[ast]=calamares
|
||||
GenericName[ast]=Instalador del sistema
|
||||
Comment[ast]=Calamares — Instalador del sistema
|
||||
Name[az]=Sistemi Quraşdırmaq
|
||||
Icon[az]=calamares
|
||||
GenericName[az]=Sistem Quraşdırıcısı
|
||||
Comment[az]=Calamares Sistem Quraşdırıcısı
|
||||
Name[az_AZ]=Sistemi quraşdırmaq
|
||||
Icon[az_AZ]=calamares
|
||||
GenericName[az_AZ]=Sistem quraşdırcısı
|
||||
Comment[az_AZ]=Calamares — Sistem Quraşdırıcısı
|
||||
Name[be]=Усталяваць сістэму
|
||||
Icon[be]=calamares
|
||||
GenericName[be]=Усталёўшчык сістэмы
|
||||
Comment[be]=Calamares — усталёўшчык сістэмы
|
||||
Name[bg]=Инсталирай системата
|
||||
Icon[bg]=calamares
|
||||
GenericName[bg]=Системен инсталатор
|
||||
Comment[bg]=„Calamares“ – Системен инсталатор
|
||||
Name[bn]=সিস্টেম ইনস্টল করুন
|
||||
Icon[bn]=ক্যালামারেস
|
||||
GenericName[bn]=সিস্টেম ইনস্টলার
|
||||
Comment[bn]=ক্যালামারেস - সিস্টেম ইনস্টলার
|
||||
Name[ca]=Instal·la el sistema
|
||||
Icon[ca]=calamares
|
||||
GenericName[ca]=Instal·lador de sistema
|
||||
Comment[ca]=Calamares — Instal·lador de sistema
|
||||
Name[cs_CZ]=Nainstalovat systém
|
||||
Icon[cs_CZ]=calamares
|
||||
GenericName[cs_CZ]=Instalátor systému
|
||||
Comment[cs_CZ]=Calamares – instalátor operačních systémů
|
||||
Name[da]=Installér system
|
||||
Icon[da]=calamares
|
||||
GenericName[da]=Systeminstallationsprogram
|
||||
Comment[da]=Calamares — Systeminstallationsprogram
|
||||
Name[de]=System installieren
|
||||
Icon[de]=calamares
|
||||
GenericName[de]=Installation des Betriebssystems
|
||||
Comment[de]=Calamares - Installation des Betriebssystems
|
||||
Name[el]=Εγκατάσταση συστήματος
|
||||
Icon[el]=calamares
|
||||
GenericName[el]=Εγκατάσταση συστήματος
|
||||
Comment[el]=Calamares — Εγκατάσταση συστήματος
|
||||
Name[en_GB]=Install System
|
||||
Icon[en_GB]=calamares
|
||||
GenericName[en_GB]=System Installer
|
||||
Comment[en_GB]=Calamares — System Installer
|
||||
Name[eo]=Instali Sistemo
|
||||
Icon[eo]=calamares
|
||||
GenericName[eo]=Sistema Instalilo
|
||||
Comment[eo]=Calamares — Sistema Instalilo
|
||||
Name[es]=Instalar el sistema
|
||||
Icon[es]=calamares
|
||||
GenericName[es]=Instalador del sistema
|
||||
Comment[es]=Calamares — Instalador del sistema
|
||||
Name[es_MX]=Instalar el Sistema
|
||||
Icon[es_MX]=calamares
|
||||
GenericName[es_MX]=Instalador del sistema
|
||||
Comment[es_MX]=Calamares - Instalador del sistema
|
||||
Name[es_PR]=Instalar el sistema
|
||||
Name[et]=Paigalda süsteem
|
||||
Icon[et]=calamares
|
||||
GenericName[et]=Süsteemipaigaldaja
|
||||
Comment[et]=Calamares — süsteemipaigaldaja
|
||||
Name[eu]=Sistema instalatu
|
||||
Icon[eu]=calamares
|
||||
GenericName[eu]=Sistema instalatzailea
|
||||
Comment[eu]=Calamares - sistema instalatzailea
|
||||
Name[fa]=نصب سامانه
|
||||
Icon[fa]=کالامارس
|
||||
GenericName[fa]=نصبکننده سامانه
|
||||
Comment[fa]=کالامارس — نصبکننده سامانه
|
||||
Name[fi_FI]=Asenna järjestelmä
|
||||
Icon[fi_FI]=calamares
|
||||
GenericName[fi_FI]=Järjestelmän asennusohjelma
|
||||
Comment[fi_FI]=Calamares — Järjestelmän asentaja
|
||||
Name[fr]=Installer le système
|
||||
Icon[fr]=calamares
|
||||
GenericName[fr]=Installateur système
|
||||
Comment[fr]=Calamares - Installateur système
|
||||
Name[fur]=Instale il sisteme
|
||||
Icon[fur]=calamares
|
||||
GenericName[fur]=Program di instalazion dal sisteme
|
||||
Comment[fur]=Calamares — Program di instalazion dal sisteme
|
||||
Name[gl]=Instalación do Sistema
|
||||
Icon[gl]=calamares
|
||||
GenericName[gl]=Instalador de sistemas
|
||||
Comment[gl]=Calamares — Instalador de sistemas
|
||||
Name[he]=התקנת מערכת
|
||||
Icon[he]=calamares
|
||||
GenericName[he]=אשף התקנה
|
||||
Comment[he]=Calamares - אשף התקנה
|
||||
Name[hi]=सिस्टम इंस्टॉल करें
|
||||
Icon[hi]=calamares
|
||||
GenericName[hi]=सिस्टम इंस्टॉलर
|
||||
Comment[hi]=Calamares — सिस्टम इंस्टॉलर
|
||||
Name[hr]=Instaliraj sustav
|
||||
Icon[hr]=calamares
|
||||
GenericName[hr]=Instalacija sustava
|
||||
Comment[hr]=Calamares — Instalacija sustava
|
||||
Name[hu]=Rendszer telepítése
|
||||
Icon[hu]=calamares
|
||||
GenericName[hu]=Rendszertelepítő
|
||||
Comment[hu]=Calamares – Rendszertelepítő
|
||||
Name[id]=Instal Sistem
|
||||
Icon[id]=calamares
|
||||
GenericName[id]=Pemasang
|
||||
Comment[id]=Calamares — Pemasang Sistem
|
||||
Name[ie]=Installar li sistema
|
||||
Icon[ie]=calamares
|
||||
GenericName[ie]=Installator del sistema
|
||||
Comment[ie]=Calamares — Installator del sistema
|
||||
Name[is]=Setja upp kerfið
|
||||
Icon[is]=calamares
|
||||
GenericName[is]=Kerfis uppsetning
|
||||
Comment[is]=Calamares — Kerfis uppsetning
|
||||
Name[it_IT]=Installa il sistema
|
||||
Icon[it_IT]=calamares
|
||||
GenericName[it_IT]=Programma d'installazione del sistema
|
||||
Comment[it_IT]=Calamares — Programma d'installazione del sistema
|
||||
Name[ja]=システムをインストール
|
||||
Icon[ja]=calamares
|
||||
GenericName[ja]=システムインストーラー
|
||||
Comment[ja]=Calamares — システムインストーラー
|
||||
Name[ko]=시스템 설치
|
||||
Icon[ko]=깔라마레스
|
||||
GenericName[ko]=시스템 설치 관리자
|
||||
Comment[ko]=깔라마레스 — 시스템 설치 관리자
|
||||
Name[lt]=Įdiegti Sistemą
|
||||
Icon[lt]=calamares
|
||||
GenericName[lt]=Sistemos diegimas į kompiuterį
|
||||
Comment[lt]=Calamares — Sistemos diegimo programa
|
||||
Name[mk]=Инсталирај го системот
|
||||
Icon[mk]=calamares
|
||||
GenericName[mk]=Системен Инсталер
|
||||
Comment[mk]=Calamares - Системен Инсталер
|
||||
Name[ml]=സിസ്റ്റം ഇൻസ്റ്റാൾ ചെയ്യുക
|
||||
Icon[ml]=കലാമാരേസ്
|
||||
GenericName[ml]=സിസ്റ്റം ഇൻസ്റ്റാളർ
|
||||
Comment[ml]=കലാമാരേസ് - സിസ്റ്റം ഇൻസ്റ്റാളർ
|
||||
Name[nb]=Installer System
|
||||
Icon[nb]=calamares
|
||||
GenericName[nb]=Systeminstallatør
|
||||
Comment[nb]=Calamares-systeminstallatør
|
||||
Name[ne_NP]= सिस्टम इन्स्टल गर्नुहोस्
|
||||
Icon[ne_NP]=Calamares
|
||||
GenericName[ne_NP]=सिस्टम इन्स्टलर
|
||||
Comment[ne_NP]=Calamares - सिस्टम इन्स्टलर
|
||||
Name[nl]=Installeer systeem
|
||||
Icon[nl]=calamares
|
||||
GenericName[nl]=Installatieprogramma
|
||||
Comment[nl]=Calamares — Installatieprogramma
|
||||
Name[pl]=Zainstaluj system
|
||||
Icon[pl]=calamares
|
||||
GenericName[pl]=Instalator systemu
|
||||
Comment[pl]=Calamares — Instalator systemu
|
||||
Name[pt_BR]=Sistema de Instalação
|
||||
Icon[pt_BR]=calamares
|
||||
GenericName[pt_BR]=Instalador de Sistema
|
||||
Comment[pt_BR]=Calamares — Instalador de Sistema
|
||||
Name[pt_PT]=Instalar Sistema
|
||||
Icon[pt_PT]=calamares
|
||||
GenericName[pt_PT]=Instalador de Sistema
|
||||
Comment[pt_PT]=Instalador de Sistema - Calamares
|
||||
Name[ro]=Instalează sistemul
|
||||
Icon[ro]=calamares
|
||||
GenericName[ro]=Instalator de sistem
|
||||
Comment[ro]=Calamares — Instalator de sistem
|
||||
Name[ru]=Установить систему
|
||||
Icon[ru]=calamares
|
||||
GenericName[ru]=Установщик системы
|
||||
Comment[ru]=Calamares - Установщик системы
|
||||
Name[si]=පද්ධතිය ස්ථාපනය කරන්න
|
||||
Icon[si]=කැලමරේස්
|
||||
GenericName[si]=පද්ධති ස්ථාපකය
|
||||
Comment[si]=Calamares - පද්ධති ස්ථාපකය
|
||||
Name[sk]=Inštalovať systém
|
||||
Icon[sk]=calamares
|
||||
GenericName[sk]=Inštalátor systému
|
||||
Comment[sk]=Calamares — Inštalátor systému
|
||||
Name[sl]=Namesti sistem
|
||||
Name[sq]=Instalo Sistemin
|
||||
Icon[sq]=calamares
|
||||
GenericName[sq]=Instalues Sistemi
|
||||
Comment[sq]=Calamares — Instalues Sistemi
|
||||
Name[sr]=Инсталирај систем
|
||||
Icon[sr]=calamares
|
||||
GenericName[sr]=Инсталатер система
|
||||
Comment[sr]=Каламарес — инсталатер система
|
||||
Name[sr@latin]=Instaliraj sistem
|
||||
Name[sv]=Installera system
|
||||
Icon[sv]=calamares
|
||||
GenericName[sv]=Systeminstallerare
|
||||
Comment[sv]=Calamares — Systeminstallerare
|
||||
Name[tg]=Насбкунии низом
|
||||
Icon[tg]=calamares
|
||||
GenericName[tg]=Насбкунандаи низомӣ
|
||||
Comment[tg]=Calamares — Насбкунандаи низомӣ
|
||||
Name[th]=ติดตั้งระบบ
|
||||
Name[tr_TR]=Sistemi Yükle
|
||||
Icon[tr_TR]=calamares
|
||||
GenericName[tr_TR]=Sistem Yükleyici
|
||||
Comment[tr_TR]=Calamares — Sistem Yükleyici
|
||||
Name[uk]=Встановити Систему
|
||||
Icon[uk]=calamares
|
||||
GenericName[uk]=Встановлювач системи
|
||||
Comment[uk]=Calamares - Встановлювач системи
|
||||
Name[vi]=Cài đặt hệ thống
|
||||
Icon[vi]=calamares
|
||||
GenericName[vi]=Bộ cài đặt hệ thống
|
||||
Comment[vi]=Calamares — Bộ cài đặt hệ thống
|
||||
Name[zh_CN]=安装系统
|
||||
Icon[zh_CN]=calamares
|
||||
GenericName[zh_CN]=系统安装程序
|
||||
Comment[zh_CN]=Calamares — 系统安装程序
|
||||
Name[zh_TW]=安裝系統
|
||||
Icon[zh_TW]=calamares
|
||||
GenericName[zh_TW]=系統安裝程式
|
||||
Comment[zh_TW]=Calamares ── 系統安裝程式
|
||||