Commit 61496e72 authored by Philip Müller's avatar Philip Müller

[merge] with upstream

parents 5de9ede7 8465dcbc
......@@ -17,6 +17,7 @@
#include <QSharedMemory>
#include <QSharedData>
#include <QBasicTimer>
#include <QElapsedTimer>
#include <QTime>
#include <algorithm>
......@@ -764,7 +765,7 @@ void KDSingleApplicationGuard::Private::create( const QStringList & arguments )
}
const int maxWaitMSecs = 1000 * 60; // stop waiting after 60 seconds
QTime waitTimer;
QElapsedTimer waitTimer;
waitTimer.start();
// lets wait till the other instance initialized the register
......
......@@ -6,14 +6,28 @@ website will have to do for older versions.
# 3.2.25 (unreleased) #
This release contains contributions from (alphabetically by first name):
- No external contributors yet
- Anke Boersma
- FLVAL
- Gaël PORTAY
## Core ##
- No core changes yet
- The slideshow in `branding.desc` can be configured with QML (recommended,
as it has been for the past umpteen releases) or with a list of
images (new).
- It is possible to turn off all the new QML code -- navigation, slideshow,
QML-based modules -- with a single `-DWITH_QML=OFF` at CMake time.
This removes QML from Calamares' dependency footprint (but only saves
200kB in Calamares itself).
- Tests have been extended and now support a tests/CMakeTests.txt file
for fine-tuning tests for Python modules.
## Modules ##
- No module changes yet
- The QML based *welcomeq* module is now a viable alternative to the
*welcome*(widgets based) module. Using QML files means it no longer
is needed to have pop-up windows for additional information or warnings,
all loads in the Calamares window itself. Additional features include the
option to customize the *About* info and load files like Release Notes
direct into Calamares, QML files added to the branding directory can be used.
# 3.2.24 (2020-05-11) #
......
......@@ -50,11 +50,14 @@ set( CALAMARES_VERSION_RC 1 ) # Set to 0 during release cycle, 1 during develop
option( INSTALL_CONFIG "Install configuration files" OFF )
option( INSTALL_POLKIT "Install Polkit configuration" ON )
option( INSTALL_COMPLETION "Install shell completions" OFF )
option( BUILD_TESTING "Build the testing tree." ON )
option( WITH_PYTHON "Enable Python modules API (requires Boost.Python)." ON )
option( WITH_PYTHONQT "Enable next generation Python modules API (experimental, requires PythonQt)." OFF )
# Options for the calamares executable
option( WITH_KF5Crash "Enable crash reporting with KCrash." ON )
option( WITH_KF5DBus "Use DBus service for unique-application." OFF )
# When adding WITH_* that affects the ABI offered by libcalamares,
# also update libcalamares/CalamaresConfig.h.in
option( WITH_PYTHON "Enable Python modules API (requires Boost.Python)." ON )
option( WITH_PYTHONQT "Enable Python view modules API (deprecated, requires PythonQt)." OFF )
option( WITH_QML "Enable QML UI options." ON )
# Possible debugging flags are:
# - DEBUG_TIMEZONES draws latitude and longitude lines on the timezone
......@@ -159,6 +162,7 @@ if(NOT CMAKE_VERSION VERSION_LESS "3.10.0")
)
endif()
include( CTest )
### C++ SETUP
#
......@@ -250,7 +254,10 @@ include( CMakeColors )
### DEPENDENCIES
#
find_package( Qt5 ${QT_VERSION} CONFIG REQUIRED Concurrent Core Gui Widgets LinguistTools Svg Quick QuickWidgets )
find_package( Qt5 ${QT_VERSION} CONFIG REQUIRED Concurrent Core Gui LinguistTools Network Svg Widgets )
if( WITH_QML )
find_package( Qt5 ${QT_VERSION} CONFIG REQUIRED Quick QuickWidgets )
endif()
if( Qt5_VERSION VERSION_GREATER 5.12.1 )
# At least Qt 5.12.2 seems to support Esperanto in QLocale
if( "eo" IN_LIST _tx_incomplete )
......@@ -312,10 +319,6 @@ if( NOT KF5DBusAddons_FOUND )
set( WITH_KF5DBus OFF )
endif()
if( BUILD_TESTING )
enable_testing()
endif ()
find_package( PythonLibs ${PYTHONLIBS_VERSION} )
set_package_properties(
PythonLibs PROPERTIES
......@@ -496,7 +499,11 @@ if ( CALAMARES_VERSION_RC EQUAL 0 )
endif()
# enforce using constBegin, constEnd for const-iterators
add_definitions( "-DQT_STRICT_ITERATORS" )
add_definitions(
-DQT_STRICT_ITERATORS
-DQT_SHARED
-DQT_SHAREDPOINTER_TRACK_POINTERS
)
# set paths
set( CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}" )
......
......@@ -126,10 +126,10 @@ function( calamares_add_module_subdirectory )
endif()
message( "" )
# We copy over the lang directory, if any
if( IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIRECTORY}/lang" )
if( IS_DIRECTORY "${_mod_dir}/lang" )
install_calamares_gettext_translations(
${SUBDIRECTORY}
SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIRECTORY}/lang"
SOURCE_DIR "${_mod_dir}/lang"
FILENAME ${SUBDIRECTORY}.mo
RENAME calamares-${SUBDIRECTORY}.mo
)
......@@ -162,6 +162,16 @@ function( calamares_add_module_subdirectory )
# may try to do things to the running system. Needs work to make that a
# safe thing to do.
#
# If the module has a tests/ subdirectory with *.global and *.job
# files (YAML files holding global and job-configurations for
# testing purposes) then those files are used to drive additional
# tests. The files must be numbered (starting from 1) for this to work;
# 1.global and 1.job together make the configuration for test 1.
#
# If the module has a tests/CMakeLists.txt while it doesn't have its
# own CMakeLists.txt (e.g. a Python module), then the subdirectory
# for tests/ is added on its own.
#
if ( BUILD_TESTING AND _mod_enabled AND _mod_testing )
add_test(
NAME load-${SUBDIRECTORY}
......@@ -170,7 +180,7 @@ function( calamares_add_module_subdirectory )
)
# Try it with the tests/ configurations shipped with the module
set( _count 1 )
set( _testdir ${CMAKE_CURRENT_SOURCE_DIR}/${SUBDIRECTORY}/tests )
set( _testdir ${_mod_dir}/tests )
while ( EXISTS "${_testdir}/${_count}.global" OR EXISTS "${_testdir}/${_count}.job" )
set( _dash_g "" )
set( _dash_j "" )
......@@ -187,5 +197,8 @@ function( calamares_add_module_subdirectory )
)
math( EXPR _count "${_count} + 1" )
endwhile()
if ( EXISTS ${_testdir}/CMakeTests.txt AND NOT EXISTS ${_mod_dir}/CMakeLists.txt )
include( ${_testdir}/CMakeTests.txt )
endif()
endif()
endfunction()
This diff is collapsed.
......@@ -2558,12 +2558,12 @@ The installer will quit and all changes will be lost.</source>
<message>
<location filename="../src/modules/partition/gui/PartitionViewStep.cpp" line="433"/>
<source>An EFI system partition is necessary to start %1.&lt;br/&gt;&lt;br/&gt;To configure an EFI system partition, go back and select or create a FAT32 filesystem with the &lt;strong&gt;%3&lt;/strong&gt; flag enabled and mount point &lt;strong&gt;%2&lt;/strong&gt;.&lt;br/&gt;&lt;br/&gt;You can continue without setting up an EFI system partition but your system may fail to start.</source>
<translation type="unfinished"/>
<translation>必须有 EFI 系统分区才能启动 %1 。&lt;br/&gt;&lt;br/&gt;要配置 EFI 系统分区,后退一步,然后创建或选中一个 FAT32 分区并为之设置 &lt;strong&gt;%3&lt;/strong&gt; 标记及挂载点 &lt;strong&gt;%2&lt;/strong&gt;。&lt;br/&gt;&lt;br/&gt;你可以不创建 EFI 系统分区并继续安装,但是你的系统可能无法启动。</translation>
</message>
<message>
<location filename="../src/modules/partition/gui/PartitionViewStep.cpp" line="447"/>
<source>An EFI system partition is necessary to start %1.&lt;br/&gt;&lt;br/&gt;A partition was configured with mount point &lt;strong&gt;%2&lt;/strong&gt; but its &lt;strong&gt;%3&lt;/strong&gt; flag is not set.&lt;br/&gt;To set the flag, go back and edit the partition.&lt;br/&gt;&lt;br/&gt;You can continue without setting the flag but your system may fail to start.</source>
<translation type="unfinished"/>
<translation>必须有 EFI 系统分区才能启动 %1 。&lt;br/&gt;&lt;br/&gt;已有挂载点为 &lt;strong&gt;%2&lt;/strong&gt; 的分区,但是未设置 &lt;strong&gt;%3&lt;/strong&gt; 标记。&lt;br/&gt;要设置此标记,后退并编辑分区。&lt;br/&gt;&lt;br/&gt;你可以不创建 EFI 系统分区并继续安装,但是你的系统可能无法启动。</translation>
</message>
<message>
<location filename="../src/modules/partition/gui/PartitionViewStep.cpp" line="446"/>
......@@ -3804,7 +3804,28 @@ Output:
&lt;/ul&gt;
&lt;p&gt;The vertical scrollbar is adjustable, current width set to 10.&lt;/p&gt;</source>
<translation type="unfinished"/>
<translation>&lt;h3&gt;%1&lt;/h3&gt;
&lt;p&gt;这是一个QML 示例文件,显示了具有 Flickable 内容的 RichText 选项。&lt;/p&gt;
&lt;p&gt;带有 RichText QML 可以使用 HTML 标签,
Flickable 内容对于触摸屏很有用。&lt;/p&gt;
&lt;p&gt;&lt;b&gt;这是粗体字&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;&lt;i&gt;这是斜体字&lt;/i&gt;&lt;/p&gt;
&lt;p&gt;&lt;u&gt;这是带下划线的文字&lt;/u&gt;&lt;/p&gt;
&lt;p&gt;&lt;center&gt;此文本将居中对齐。&lt;/center&gt;&lt;/p&gt;
&lt;p&gt;&lt;s&gt;这是删除线&lt;/s&gt;&lt;/p&gt;
&lt;p&gt;代码示例:
&lt;code&gt;ls -l /home&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;列表:&lt;/b&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Intel CPU 系统&lt;/li&gt;
&lt;li&gt;AMD CPU 系统&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;垂直滚动条是可调的,当前宽度设置为10&lt;/p&gt;</translation>
</message>
<message>
<location filename="../src/modules/welcomeq/release_notes.qml" line="85"/>
......@@ -3818,7 +3839,8 @@ Output:
<location filename="../src/modules/welcomeq/welcomeq.qml" line="44"/>
<source>&lt;h3&gt;Welcome to the %1 &lt;quote&gt;%2&lt;/quote&gt; installer&lt;/h3&gt;
&lt;p&gt;This program will ask you some questions and set up %1 on your computer.&lt;/p&gt;</source>
<translation type="unfinished"/>
<translation>&lt;h3&gt;欢迎来到 %1 &lt;quote&gt;%2&lt;/quote&gt; 安装程序&lt;/h3&gt;
&lt;p&gt;这个程序将询问您一些问题并在您的计算机上安装 %1&lt;/p&gt;</translation>
</message>
<message>
<location filename="../src/modules/welcomeq/welcomeq.qml" line="71"/>
......
......@@ -24,7 +24,7 @@ msgstr ""
#: src/modules/packages/main.py:59 src/modules/packages/main.py:68
#: src/modules/packages/main.py:78
msgid "Install packages."
msgstr "Asenna paketteja."
msgstr "Asenna paketit."
#: src/modules/packages/main.py:66
#, python-format
......@@ -108,7 +108,7 @@ msgstr "Kuvan purkaminen epäonnistui \"{}\""
#: src/modules/unpackfs/main.py:399
msgid "No mount point for root partition"
msgstr "Ei liitoskohtaa juuri root-osiolle"
msgstr "Ei liitoskohtaa juuri root osiolle"
#: src/modules/unpackfs/main.py:400
msgid "globalstorage does not contain a \"rootMountPoint\" key, doing nothing"
......
......@@ -141,8 +141,23 @@ images:
# The slideshow is displayed during execution steps (e.g. when the
# installer is actually writing to disk and doing other slow things).
#
# The slideshow can be a QML file (recommended) which can display
# arbitrary things -- text, images, animations, or even play a game --
# during the execution step. The QML **is** abruptly stopped when the
# execution step is done, though, so maybe a game isn't a great idea.
#
# The slideshow can also be a sequence of images (not recommended unless
# you don't want QML at all in your Calamares). The images are displayed
# at a rate of 1 every 2 seconds during the execution step.
#
# To configure a QML file, list a single filename:
# slideshow: "show.qml"
# To configure images, like the filenames (here, as an inline list):
# slideshow: [ "/etc/calamares/slideshow/0.png", "/etc/logo.png" ]
slideshow: "show.qml"
# There are two available APIs for the slideshow:
# There are two available APIs for a QML slideshow:
# - 1 (the default) loads the entire slideshow when the installation-
# slideshow page is shown and starts the QML then. The QML
# is never stopped (after installation is done, times etc.
......@@ -151,6 +166,8 @@ slideshow: "show.qml"
# onLeave() in the root object. After the installation is done,
# the show is stopped (first by calling onLeave(), then destroying
# the QML components).
#
# An image slideshow does not need to have the API defined.
slideshowAPI: 2
......
......@@ -10,6 +10,20 @@ set( calamaresSources
progresstree/ProgressTreeView.cpp
)
if( NOT WITH_KF5DBus )
set( kdsagSources "" )
foreach( _s
kdsingleapplicationguard/kdsingleapplicationguard.cpp
kdsingleapplicationguard/kdsharedmemorylocker.cpp
kdsingleapplicationguard/kdtoolsglobal.cpp
kdsingleapplicationguard/kdlockedsharedmemorypointer.cpp
)
list( APPEND kdsagSources ${CMAKE_SOURCE_DIR}/3rdparty/${_s} )
endforeach()
mark_thirdparty_code( ${kdsagSources} )
list( APPEND calamaresSources ${kdsagSources} )
endif()
include_directories(
${CMAKE_SOURCE_DIR}/src/libcalamares
${CMAKE_SOURCE_DIR}/src/libcalamaresui
......
......@@ -22,6 +22,7 @@
#include "CalamaresWindow.h"
#include "Branding.h"
#include "CalamaresConfig.h"
#include "DebugWindow.h"
#include "Settings.h"
#include "ViewManager.h"
......@@ -38,8 +39,10 @@
#include <QFile>
#include <QFileInfo>
#include <QLabel>
#ifdef WITH_QML
#include <QQuickItem>
#include <QQuickWidget>
#endif
#include <QTreeView>
static inline int
......@@ -132,18 +135,6 @@ CalamaresWindow::getWidgetSidebar( QWidget* parent, int desiredWidth )
return sideBox;
}
QWidget*
CalamaresWindow::getQmlSidebar( QWidget* parent, int )
{
CalamaresUtils::registerCalamaresModels();
QQuickWidget* w = new QQuickWidget( parent );
w->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding );
w->setResizeMode( QQuickWidget::SizeRootObjectToView );
w->setSource( QUrl(
CalamaresUtils::searchQmlFile( CalamaresUtils::QmlSearch::Both, QStringLiteral( "calamares-sidebar" ) ) ) );
return w;
}
/** @brief Get a button-sized icon. */
static inline QPixmap
getButtonIcon( const QString& name )
......@@ -213,6 +204,19 @@ CalamaresWindow::getWidgetNavigation( QWidget* parent )
return navigation;
}
#ifdef WITH_QML
QWidget*
CalamaresWindow::getQmlSidebar( QWidget* parent, int )
{
CalamaresUtils::registerCalamaresModels();
QQuickWidget* w = new QQuickWidget( parent );
w->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding );
w->setResizeMode( QQuickWidget::SizeRootObjectToView );
w->setSource( QUrl(
CalamaresUtils::searchQmlFile( CalamaresUtils::QmlSearch::Both, QStringLiteral( "calamares-sidebar" ) ) ) );
return w;
}
QWidget*
CalamaresWindow::getQmlNavigation( QWidget* parent )
{
......@@ -231,6 +235,19 @@ CalamaresWindow::getQmlNavigation( QWidget* parent )
return w;
}
#else
// Bogus to keep the linker happy
QWidget * CalamaresWindow::getQmlSidebar(QWidget* , int )
{
return nullptr;
}
QWidget * CalamaresWindow::getQmlNavigation(QWidget* )
{
return nullptr;
}
#endif
/**@brief Picks one of two methods to call
*
......@@ -243,16 +260,21 @@ flavoredWidget( Calamares::Branding::PanelFlavor flavor,
CalamaresWindow* w,
QWidget* parent,
widgetMaker widget,
widgetMaker qml,
widgetMaker qml, // Only if WITH_QML is on
args... a )
{
#ifndef WITH_QML
Q_UNUSED( qml )
#endif
// Member-function calling syntax is (object.*member)(args)
switch ( flavor )
{
case Calamares::Branding::PanelFlavor::Widget:
return ( w->*widget )( parent, a... );
#ifdef WITH_QML
case Calamares::Branding::PanelFlavor::Qml:
return ( w->*qml )( parent, a... );
#endif
case Calamares::Branding::PanelFlavor::None:
return nullptr;
}
......
......@@ -252,6 +252,12 @@ main( int argc, char* argv[] )
cDebug() << " .. got" << m->name() << m->typeString() << m->interfaceString();
if ( m->type() == Calamares::Module::Type::View )
{
if ( !qobject_cast< QApplication* >(aw) )
{
auto* replace_app = new QApplication( argc, argv );
replace_app->setQuitOnLastWindowClosed( true );
aw = replace_app;
}
mw = module.m_ui ? new QMainWindow() : nullptr;
(void)new Calamares::Branding( module.m_branding );
......
# libcalamares is the non-GUI part of Calamares, which includes handling
# translations, configurations, logging, utilities, global storage, and (non-GUI) jobs.
add_definitions(
${QT_DEFINITIONS}
-DQT_SHARED
-DQT_SHAREDPOINTER_TRACK_POINTERS
-DDLLEXPORT_PRO
)
add_definitions( -DDLLEXPORT_PRO )
include_directories( ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR} )
configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/CalamaresConfig.h.in
${CMAKE_CURRENT_BINARY_DIR}/CalamaresConfig.h )
......@@ -65,22 +61,6 @@ set( libSources
utils/Variant.cpp
utils/Yaml.cpp
)
set( _kdsagSources
kdsingleapplicationguard/kdsingleapplicationguard.cpp
kdsingleapplicationguard/kdsharedmemorylocker.cpp
kdsingleapplicationguard/kdtoolsglobal.cpp
kdsingleapplicationguard/kdlockedsharedmemorypointer.cpp
)
set( kdsagSources "" )
foreach( _s ${_kdsagSources} )
list( APPEND kdsagSources ${CMAKE_SOURCE_DIR}/3rdparty/${_s} )
endforeach()
mark_thirdparty_code( ${kdsagSources} )
include_directories(
${CMAKE_CURRENT_BINARY_DIR}
${CMAKE_CURRENT_SOURCE_DIR}
)
### OPTIONAL Python support
#
......@@ -156,7 +136,7 @@ endif()
### LIBRARY
#
#
add_library( calamares SHARED ${libSources} ${kdsagSources} )
add_library( calamares SHARED ${libSources} )
set_target_properties( calamares
PROPERTIES
VERSION ${CALAMARES_VERSION_SHORT}
......
......@@ -11,5 +11,6 @@
//cmakedefines for CMake variables (e.g. for optdepends) go here
#cmakedefine WITH_PYTHON
#cmakedefine WITH_PYTHONQT
#cmakedefine WITH_QML
#endif // CALAMARESCONFIG_H
......@@ -20,7 +20,7 @@
#ifndef DLLMACRO_H
#define DLLMACRO_H
#include <QtCore/qglobal.h>
#include <qglobal.h>
/*
* Mark symbols exported from Calamares non-GUI library with DLLEXPORT.
......
......@@ -20,10 +20,10 @@
#ifndef PYTHONJOBAPI_H
#define PYTHONJOBAPI_H
#include "qglobal.h" // For qreal
#include "utils/BoostPython.h"
#include <qglobal.h> // For qreal
namespace Calamares
{
class PythonJob;
......
......@@ -41,6 +41,13 @@
#include <KOSRelease>
#endif
[[noreturn]] static void
bail( const QString& descriptorPath, const QString& message )
{
cError() << "FATAL in" << descriptorPath << Logger::Continuation << Logger::NoQuote {} << message;
::exit( EXIT_FAILURE );
}
namespace Calamares
{
......@@ -153,7 +160,7 @@ Branding::Branding( const QString& brandingFilePath, QObject* parent )
QDir componentDir( componentDirectory() );
if ( !componentDir.exists() )
{
bail( "Bad component directory path." );
bail( m_descriptorPath, "Bad component directory path." );
}
QFile file( brandingFilePath );
......@@ -168,10 +175,12 @@ Branding::Branding( const QString& brandingFilePath, QObject* parent )
m_componentName = QString::fromStdString( doc[ "componentName" ].as< std::string >() );
if ( m_componentName != componentDir.dirName() )
bail( "The branding component name should match the name of the "
bail( m_descriptorPath,
"The branding component name should match the name of the "
"component directory." );
initSimpleSettings( doc );
initSlideshowSettings( doc );
#ifdef WITH_KOSRelease
// Copy the os-release information into a QHash for use by KMacroExpander.
......@@ -194,17 +203,15 @@ Branding::Branding( const QString& brandingFilePath, QObject* parent )
{ QStringLiteral( "VARIANT" ), relInfo.variant() },
{ QStringLiteral( "VARIANT_ID" ), relInfo.variantId() },
{ QStringLiteral( "LOGO" ), relInfo.logo() } } };
auto expand = [ & ]( const QString& s ) -> QString {
auto expand = [&]( const QString& s ) -> QString {
return KMacroExpander::expandMacros( s, relMap, QLatin1Char( '@' ) );
};
#else
auto expand = []( const QString& s ) -> QString { return s; };
#endif
// Massage the strings, images and style sections.
loadStrings( m_strings, doc, "strings", expand );
loadStrings( m_images, doc, "images", [ & ]( const QString& s ) -> QString {
loadStrings( m_images, doc, "images", [&]( const QString& s ) -> QString {
// See also image()
const QString imageName( expand( s ) );
QFileInfo imageFi( componentDir.absoluteFilePath( imageName ) );
......@@ -214,58 +221,19 @@ Branding::Branding( const QString& brandingFilePath, QObject* parent )
// Not found, bail out with the filename used
if ( icon.isNull() )
{
bail( QString( "Image file %1 does not exist." ).arg( imageFi.absoluteFilePath() ) );
bail( m_descriptorPath,
QString( "Image file %1 does not exist." ).arg( imageFi.absoluteFilePath() ) );
}
return imageName; // Not turned into a path
}
return imageFi.absoluteFilePath();
} );
loadStrings( m_style, doc, "style", []( const QString& s ) -> QString { return s; } );
if ( doc[ "slideshow" ].IsSequence() )
{
QStringList slideShowPictures;
doc[ "slideshow" ] >> slideShowPictures;
for ( int i = 0; i < slideShowPictures.count(); ++i )
{
QString pathString = slideShowPictures[ i ];
QFileInfo imageFi( componentDir.absoluteFilePath( pathString ) );
if ( !imageFi.exists() )
{
bail( QString( "Slideshow file %1 does not exist." ).arg( imageFi.absoluteFilePath() ) );
}
slideShowPictures[ i ] = imageFi.absoluteFilePath();
}
//FIXME: implement a GenericSlideShow.qml that uses these slideShowPictures
}
else if ( doc[ "slideshow" ].IsScalar() )
{
QString slideshowPath = QString::fromStdString( doc[ "slideshow" ].as< std::string >() );
QFileInfo slideshowFi( componentDir.absoluteFilePath( slideshowPath ) );
if ( !slideshowFi.exists() || !slideshowFi.fileName().toLower().endsWith( ".qml" ) )
bail( QString( "Slideshow file %1 does not exist or is not a valid QML file." )
.arg( slideshowFi.absoluteFilePath() ) );
m_slideshowPath = slideshowFi.absoluteFilePath();
}
else
{
bail( "Syntax error in slideshow sequence." );
}
int api = doc[ "slideshowAPI" ].IsScalar() ? doc[ "slideshowAPI" ].as< int >() : -1;
if ( ( api < 1 ) || ( api > 2 ) )
{
cWarning() << "Invalid or missing *slideshowAPI* in branding file.";
api = 1;
}
m_slideshowAPI = api;
}
catch ( YAML::Exception& e )
{
CalamaresUtils::explainYamlException( e, ba, file.fileName() );
bail( e.what() );
bail( m_descriptorPath, e.what() );
}
QDir translationsDir( componentDir.filePath( "lang" ) );
......@@ -423,8 +391,11 @@ flavorAndSide( const YAML::Node& doc, const char* key, Branding::PanelFlavor& fl
static const NamedEnumTable< PanelFlavor > sidebarFlavorNames {
{ QStringLiteral( "widget" ), PanelFlavor::Widget },
{ QStringLiteral( "none" ), PanelFlavor::None },
{ QStringLiteral( "hidden" ), PanelFlavor::None },
{ QStringLiteral( "hidden" ), PanelFlavor::None }
#ifdef WITH_QML
,
{ QStringLiteral( "qml" ), PanelFlavor::Qml }
#endif
};
static const NamedEnumTable< PanelSide > panelSideNames {
{ QStringLiteral( "left" ), PanelSide::Left },
......@@ -540,12 +511,62 @@ Branding::initSimpleSettings( const YAML::Node& doc )
}
}
[[noreturn]] void
Branding::bail( const QString& message )
void
Branding::initSlideshowSettings( const YAML::Node& doc )
{
cError() << "FATAL in" << m_descriptorPath << Logger::Continuation << Logger::NoQuote {} << message;
::exit( EXIT_FAILURE );
QDir componentDir( componentDirectory() );
if ( doc[ "slideshow" ].IsSequence() )
{
QStringList slideShowPictures;
doc[ "slideshow" ] >> slideShowPictures;
for ( int i = 0; i < slideShowPictures.count(); ++i )
{
QString pathString = slideShowPictures[ i ];
QFileInfo imageFi( componentDir.absoluteFilePath( pathString ) );
if ( !imageFi.exists() )
{
bail( m_descriptorPath,
QString( "Slideshow file %1 does not exist." ).arg( imageFi.absoluteFilePath() ) );
}
slideShowPictures[ i ] = imageFi.absoluteFilePath();
}
m_slideshowFilenames = slideShowPictures;
m_slideshowAPI = -1;
}
#ifdef WITH_QML
else if ( doc[ "slideshow" ].IsScalar() )
{
QString slideshowPath = QString::fromStdString( doc[ "slideshow" ].as< std::string >() );
QFileInfo slideshowFi( componentDir.absoluteFilePath( slideshowPath ) );
if ( !slideshowFi.exists() || !slideshowFi.fileName().toLower().endsWith( ".qml" ) )
bail( m_descriptorPath,
QString( "Slideshow file %1 does not exist or is not a valid QML file." )
.arg( slideshowFi.absoluteFilePath() ) );
m_slideshowPath = slideshowFi.absoluteFilePath();
// API choice is relevant for QML slideshow
int api = doc[ "slideshowAPI" ].IsScalar() ? doc[ "slideshowAPI" ].as< int >() : -1;
if ( ( api < 1 ) || ( api > 2 ) )
{
cWarning() << "Invalid or missing *slideshowAPI* in branding file.";
api = 1;
}
m_slideshowAPI = api;
}
#else
else if ( doc[ "slideshow" ].IsScalar() )