[merge] with upstream
This commit is contained in:
commit
7333a925b4
@ -11,3 +11,8 @@ trim_trailing_whitespace = true
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
insert_final_newline = true
|
||||
|
||||
[*.sh]
|
||||
indent_style = tab
|
||||
insert_final_newline = true
|
||||
|
||||
|
@ -1,5 +1,18 @@
|
||||
#! /bin/sh
|
||||
|
||||
### LICENSE
|
||||
# === This file is part of Calamares - <https://github.com/calamares> ===
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-2-Clause
|
||||
# SPDX-FileCopyrightText: 2019-2020 Adriaan de Groot <groot@kde.org>
|
||||
#
|
||||
# This file is Free Software: you can redistribute it and/or modify
|
||||
# it under the terms of the 2-clause BSD License.
|
||||
#
|
||||
### END LICENSE
|
||||
|
||||
### USAGE
|
||||
#
|
||||
# Does the translation tag (from a previous txpush) exist?
|
||||
# This assumes that the release host has also locally done
|
||||
# a translations push, which works for the current development
|
||||
@ -7,6 +20,13 @@
|
||||
# the typical txpush log messages instead of the tag.
|
||||
#
|
||||
# Use --cleanup as an argument to clean things up.
|
||||
#
|
||||
# Normal use:
|
||||
# $ sh ci/txcheck.sh
|
||||
# If there are differences, fix them and then clean up:
|
||||
# $ sh ci/txcheck.sh --cleanup
|
||||
#
|
||||
### END USAGE
|
||||
|
||||
# The files that are translated; should match the contents of .tx/config
|
||||
TX_FILE_LIST="lang/calamares_en.ts lang/python.pot src/modules/dummypythonqt/lang/dummypythonqt.pot calamares.desktop"
|
||||
@ -27,6 +47,9 @@ if test "x$1" = "x--cleanup" ; then
|
||||
tx_cleanup
|
||||
exit 0
|
||||
fi
|
||||
if test "x$1" = "x--help" ; then
|
||||
sed -e '1,/USAGE/d' -e '/END.USAGE/,$d' < "$0"
|
||||
fi
|
||||
test -z "$1" || { echo "! Usage: txcheck.sh [--cleanup]" ; exit 1 ; }
|
||||
|
||||
|
||||
@ -67,6 +90,8 @@ fi
|
||||
if test `git describe` = `git describe --dirty` ; then
|
||||
:
|
||||
else
|
||||
# Don't want any local changes, since those won't be
|
||||
# reflected in the worktrees and we might miss a string change.
|
||||
echo "! There are local changes."
|
||||
exit 1
|
||||
fi
|
||||
@ -75,13 +100,20 @@ DATE_PREV=$( git log -1 translation --date=unix | sed -e '/^Date:/s+.*:++p' -e d
|
||||
DATE_HEAD=$( last_week )
|
||||
test "$DATE_PREV" -le "$DATE_HEAD" || { echo "! Translation tag has not aged enough." ; git log -1 translation ; exit 1 ; }
|
||||
|
||||
# Tag is good, do real work of checking strings: collect names of relevant files
|
||||
# Tag is good, check that necessary files exist. The list of
|
||||
# files is hard-coded, but should match what is in the Transifex config.
|
||||
test -f ".tx/config" || { echo "! No Transifex configuration is present." ; exit 1 ; }
|
||||
for f in $TX_FILE_LIST ; do
|
||||
test -f $f || { echo "! Translation file '$f' does not exist." ; exit 1 ; }
|
||||
done
|
||||
|
||||
# The state of translations
|
||||
### COMPARE TRANSLATIONS
|
||||
#
|
||||
#
|
||||
|
||||
# The state of translations; assume that sha256 is enough
|
||||
# to distinguish changed translations when we cat all the
|
||||
# string sources together.
|
||||
tx_sum()
|
||||
{
|
||||
CURDIR=`pwd`
|
||||
|
16
ci/txpull.sh
16
ci/txpull.sh
@ -1,4 +1,18 @@
|
||||
#!/bin/sh
|
||||
|
||||
### LICENSE
|
||||
# === This file is part of Calamares - <https://github.com/calamares> ===
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-2-Clause
|
||||
# SPDX-FileCopyrightText: 2017-2020 Adriaan de Groot <groot@kde.org>
|
||||
# SPDX-FileCopyrightText: 2015-2016 Teo Mrnjavac <teo@kde.org>
|
||||
#
|
||||
# This file is Free Software: you can redistribute it and/or modify
|
||||
# it under the terms of the 2-clause BSD License.
|
||||
#
|
||||
### END LICENSE
|
||||
|
||||
### USAGE
|
||||
#
|
||||
# Fetch the Transifex translations for Calamares and incorporate them
|
||||
# into the source tree, adding commits of the different files.
|
||||
@ -6,6 +20,8 @@
|
||||
# Run this (occasionally) at the top-level directory to get
|
||||
# new translations. See also CMakeLists.txt and ci/txstats.py
|
||||
# for update instructions.
|
||||
#
|
||||
### END USAGE
|
||||
|
||||
### INITIAL SETUP
|
||||
#
|
||||
|
22
ci/txpush.sh
22
ci/txpush.sh
@ -1,13 +1,33 @@
|
||||
#!/bin/sh
|
||||
|
||||
### LICENSE
|
||||
# === This file is part of Calamares - <https://github.com/calamares> ===
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-2-Clause
|
||||
# SPDX-FileCopyrightText: 2017-2020 Adriaan de Groot <groot@kde.org>
|
||||
# SPDX-FileCopyrightText: 2015-2016 Teo Mrnjavac <teo@kde.org>
|
||||
#
|
||||
# This file is Free Software: you can redistribute it and/or modify
|
||||
# it under the terms of the 2-clause BSD License.
|
||||
#
|
||||
### END LICENSE
|
||||
|
||||
### USAGE
|
||||
#
|
||||
# Extract translations from Calamares source and send them
|
||||
# to Transifex.
|
||||
# to Transifex. Also (forcibly) updates the git "translation"
|
||||
# tag to document that source texts were updated and sent;
|
||||
# this is used by txcheck.sh to ensure that there's enough
|
||||
# time between updates and releases, and that strings don't
|
||||
# change between updates and releases.
|
||||
#
|
||||
# Run this at the top-level.
|
||||
#
|
||||
# Use the --no-tx option to do the extraction, but not the
|
||||
# pushing-to-Transifex part. This can be useful to check for
|
||||
# new strings or when testing the tools themselves.
|
||||
#
|
||||
### END USAGE
|
||||
|
||||
### INITIAL SETUP
|
||||
#
|
||||
|
@ -69,11 +69,11 @@ windowPlacement: center
|
||||
strings:
|
||||
productName: "@{NAME}"
|
||||
shortProductName: Generic
|
||||
version: 2017.8 LTS
|
||||
shortVersion: 2017.8
|
||||
versionedName: Generic GNU/Linux 2017.8 LTS "Soapy Sousaphone"
|
||||
shortVersionedName: Generic 2017.8
|
||||
bootloaderEntryName: Generic
|
||||
version: 2020.2 LTS
|
||||
shortVersion: 2020.2
|
||||
versionedName: Fancy GNU/Linux 2020.2 LTS "Turgid Tuba"
|
||||
shortVersionedName: FancyGL 2020.2
|
||||
bootloaderEntryName: FancyGL
|
||||
productUrl: https://calamares.io/
|
||||
supportUrl: https://github.com/calamares/calamares/issues
|
||||
knownIssuesUrl: https://calamares.io/about/
|
||||
|
@ -42,12 +42,17 @@
|
||||
#include <QScreen>
|
||||
#include <QTimer>
|
||||
|
||||
/// @brief Convenience for "are the settings in debug mode"
|
||||
static bool
|
||||
isDebug()
|
||||
{
|
||||
return Calamares::Settings::instance() && Calamares::Settings::instance()->debugMode();
|
||||
}
|
||||
|
||||
CalamaresApplication::CalamaresApplication( int& argc, char* argv[] )
|
||||
: QApplication( argc, argv )
|
||||
, m_mainwindow( nullptr )
|
||||
, m_moduleManager( nullptr )
|
||||
, m_debugMode( false )
|
||||
{
|
||||
// Setting the organization name makes the default cache
|
||||
// directory -- where Calamares stores logs, for instance --
|
||||
@ -59,8 +64,6 @@ CalamaresApplication::CalamaresApplication( int& argc, char* argv[] )
|
||||
setApplicationName( QStringLiteral( CALAMARES_APPLICATION_NAME ) );
|
||||
setApplicationVersion( QStringLiteral( CALAMARES_VERSION ) );
|
||||
|
||||
CalamaresUtils::installTranslator( QLocale::system(), QString(), this );
|
||||
|
||||
QFont f = font();
|
||||
CalamaresUtils::setDefaultFontSize( f.pointSize() );
|
||||
}
|
||||
@ -73,15 +76,20 @@ CalamaresApplication::init()
|
||||
cDebug() << "Calamares version:" << CALAMARES_VERSION;
|
||||
cDebug() << " languages:" << QString( CALAMARES_TRANSLATION_LANGUAGES ).replace( ";", ", " );
|
||||
|
||||
setQuitOnLastWindowClosed( false );
|
||||
|
||||
if ( !Calamares::Settings::instance() )
|
||||
{
|
||||
cError() << "Must create Calamares::Settings before the application.";
|
||||
::exit( 1 );
|
||||
}
|
||||
initQmlPath();
|
||||
initSettings();
|
||||
initBranding();
|
||||
|
||||
CalamaresUtils::installTranslator( QLocale::system(), QString(), this );
|
||||
|
||||
setQuitOnLastWindowClosed( false );
|
||||
setWindowIcon( QIcon( Calamares::Branding::instance()->imagePath( Calamares::Branding::ProductIcon ) ) );
|
||||
|
||||
cDebug() << "STARTUP: initQmlPath, initSettings, initBranding done";
|
||||
cDebug() << "STARTUP: initSettings, initQmlPath, initBranding done";
|
||||
|
||||
initModuleManager(); //also shows main window
|
||||
|
||||
@ -103,20 +111,6 @@ CalamaresApplication::instance()
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CalamaresApplication::setDebug( bool enabled )
|
||||
{
|
||||
m_debugMode = enabled;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
CalamaresApplication::isDebug()
|
||||
{
|
||||
return m_debugMode;
|
||||
}
|
||||
|
||||
|
||||
CalamaresWindow*
|
||||
CalamaresApplication::mainWindow()
|
||||
{
|
||||
@ -152,35 +146,6 @@ qmlDirCandidates( bool assumeBuilddir )
|
||||
}
|
||||
|
||||
|
||||
static QStringList
|
||||
settingsFileCandidates( bool assumeBuilddir )
|
||||
{
|
||||
static const char settings[] = "settings.conf";
|
||||
|
||||
QStringList settingsPaths;
|
||||
if ( CalamaresUtils::isAppDataDirOverridden() )
|
||||
{
|
||||
settingsPaths << CalamaresUtils::appDataDir().absoluteFilePath( settings );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( assumeBuilddir )
|
||||
{
|
||||
settingsPaths << QDir::current().absoluteFilePath( settings );
|
||||
}
|
||||
if ( CalamaresUtils::haveExtraDirs() )
|
||||
for ( auto s : CalamaresUtils::extraConfigDirs() )
|
||||
{
|
||||
settingsPaths << ( s + settings );
|
||||
}
|
||||
settingsPaths << CMAKE_INSTALL_FULL_SYSCONFDIR "/calamares/settings.conf"; // String concat
|
||||
settingsPaths << CalamaresUtils::appDataDir().absoluteFilePath( settings );
|
||||
}
|
||||
|
||||
return settingsPaths;
|
||||
}
|
||||
|
||||
|
||||
static QStringList
|
||||
brandingFileCandidates( bool assumeBuilddir, const QString& brandingFilename )
|
||||
{
|
||||
@ -246,49 +211,6 @@ CalamaresApplication::initQmlPath()
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CalamaresApplication::initSettings()
|
||||
{
|
||||
QStringList settingsFileCandidatesByPriority = settingsFileCandidates( isDebug() );
|
||||
|
||||
QFileInfo settingsFile;
|
||||
bool found = false;
|
||||
|
||||
foreach ( const QString& path, settingsFileCandidatesByPriority )
|
||||
{
|
||||
QFileInfo pathFi( path );
|
||||
if ( pathFi.exists() && pathFi.isReadable() )
|
||||
{
|
||||
settingsFile = pathFi;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !found || !settingsFile.exists() || !settingsFile.isReadable() )
|
||||
{
|
||||
cError() << "Cowardly refusing to continue startup without settings."
|
||||
<< Logger::DebugList( settingsFileCandidatesByPriority );
|
||||
if ( CalamaresUtils::isAppDataDirOverridden() )
|
||||
{
|
||||
cError() << "FATAL: explicitly configured application data directory is missing settings.conf";
|
||||
}
|
||||
else
|
||||
{
|
||||
cError() << "FATAL: none of the expected configuration file paths exist.";
|
||||
}
|
||||
::exit( EXIT_FAILURE );
|
||||
}
|
||||
|
||||
auto* settings = new Calamares::Settings( settingsFile.absoluteFilePath(), isDebug(), this ); // Creates singleton
|
||||
if ( settings->modulesSequence().count() < 1 )
|
||||
{
|
||||
cError() << "FATAL: no sequence set.";
|
||||
::exit( EXIT_FAILURE );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CalamaresApplication::initBranding()
|
||||
{
|
||||
|
@ -49,16 +49,6 @@ public:
|
||||
void init();
|
||||
static CalamaresApplication* instance();
|
||||
|
||||
/**
|
||||
* @brief setDebug controls whether debug mode is enabled
|
||||
*/
|
||||
void setDebug( bool enabled );
|
||||
|
||||
/**
|
||||
* @brief isDebug returns true if running in debug mode, otherwise false.
|
||||
*/
|
||||
bool isDebug();
|
||||
|
||||
/**
|
||||
* @brief mainWindow returns the Calamares application main window.
|
||||
*/
|
||||
@ -70,16 +60,14 @@ private slots:
|
||||
void initFailed( const QStringList& l );
|
||||
|
||||
private:
|
||||
// Initialization steps happen in this order
|
||||
void initQmlPath();
|
||||
void initSettings();
|
||||
void initBranding();
|
||||
void initModuleManager();
|
||||
void initJobQueue();
|
||||
|
||||
CalamaresWindow* m_mainwindow;
|
||||
Calamares::ModuleManager* m_moduleManager;
|
||||
|
||||
bool m_debugMode;
|
||||
};
|
||||
|
||||
#endif // CALAMARESAPPLICATION_H
|
||||
|
@ -20,9 +20,10 @@
|
||||
|
||||
#include "CalamaresApplication.h"
|
||||
|
||||
#include "CalamaresConfig.h"
|
||||
#include "Settings.h"
|
||||
#include "utils/Dirs.h"
|
||||
#include "utils/Logger.h"
|
||||
#include "utils/Retranslator.h"
|
||||
|
||||
#include "3rdparty/kdsingleapplicationguard/kdsingleapplicationguard.h"
|
||||
|
||||
@ -35,6 +36,21 @@
|
||||
#include <QDebug>
|
||||
#include <QDir>
|
||||
|
||||
static unsigned int
|
||||
debug_level( QCommandLineParser& parser, QCommandLineOption& levelOption )
|
||||
{
|
||||
bool ok = true;
|
||||
int l = parser.value( levelOption ).toInt( &ok );
|
||||
if ( !ok || ( l < 0 ) )
|
||||
{
|
||||
return Logger::LOGVERBOSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return static_cast< unsigned int >( l ); // l >= 0
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
handle_args( CalamaresApplication& a )
|
||||
{
|
||||
@ -42,6 +58,9 @@ handle_args( CalamaresApplication& a )
|
||||
"Also look in current directory for configuration. Implies -D8." );
|
||||
QCommandLineOption debugLevelOption(
|
||||
QStringLiteral( "D" ), "Verbose output for debugging purposes (0-8).", "level" );
|
||||
QCommandLineOption debugTxOption( QStringList { "T", "debug-translation" },
|
||||
"Also look in the current directory for translation." );
|
||||
|
||||
QCommandLineOption configOption(
|
||||
QStringList { "c", "config" }, "Configuration directory to use, for testing purposes.", "config" );
|
||||
QCommandLineOption xdgOption( QStringList { "X", "xdg-config" }, "Use XDG_{CONFIG,DATA}_DIRS as well." );
|
||||
@ -55,29 +74,11 @@ handle_args( CalamaresApplication& a )
|
||||
parser.addOption( debugLevelOption );
|
||||
parser.addOption( configOption );
|
||||
parser.addOption( xdgOption );
|
||||
parser.addOption( debugTxOption );
|
||||
|
||||
parser.process( a );
|
||||
|
||||
a.setDebug( parser.isSet( debugOption ) );
|
||||
if ( parser.isSet( debugOption ) )
|
||||
{
|
||||
Logger::setupLogLevel( Logger::LOGVERBOSE );
|
||||
}
|
||||
else if ( parser.isSet( debugLevelOption ) )
|
||||
{
|
||||
bool ok = true;
|
||||
int l = parser.value( debugLevelOption ).toInt( &ok );
|
||||
unsigned int dlevel = 0;
|
||||
if ( !ok || ( l < 0 ) )
|
||||
{
|
||||
dlevel = Logger::LOGVERBOSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
dlevel = static_cast< unsigned int >( l ); // l >= 0
|
||||
}
|
||||
Logger::setupLogLevel( dlevel );
|
||||
}
|
||||
Logger::setupLogLevel( parser.isSet( debugOption ) ? Logger::LOGVERBOSE : debug_level( parser, debugLevelOption ) );
|
||||
if ( parser.isSet( configOption ) )
|
||||
{
|
||||
CalamaresUtils::setAppDataDir( QDir( parser.value( configOption ) ) );
|
||||
@ -86,6 +87,9 @@ handle_args( CalamaresApplication& a )
|
||||
{
|
||||
CalamaresUtils::setXdgDirs();
|
||||
}
|
||||
CalamaresUtils::setAllowLocalTranslation( parser.isSet( debugOption ) || parser.isSet( debugTxOption ) );
|
||||
Calamares::Settings::init( parser.isSet( debugOption ) );
|
||||
a.init();
|
||||
}
|
||||
|
||||
int
|
||||
@ -113,14 +117,11 @@ main( int argc, char* argv[] )
|
||||
// TODO: umount anything in /tmp/calamares-... as an emergency save function
|
||||
#endif
|
||||
|
||||
handle_args( a );
|
||||
KDSingleApplicationGuard guard( KDSingleApplicationGuard::AutoKillOtherInstances );
|
||||
|
||||
int returnCode = 0;
|
||||
if ( guard.isPrimaryInstance() )
|
||||
{
|
||||
a.init();
|
||||
returnCode = a.exec();
|
||||
handle_args( a );
|
||||
return a.exec();
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -135,7 +136,6 @@ main( int argc, char* argv[] )
|
||||
{
|
||||
qDebug() << " " << i.isValid() << i.pid() << i.arguments();
|
||||
}
|
||||
return 69; // EX_UNAVAILABLE on FreeBSD
|
||||
}
|
||||
|
||||
return returnCode;
|
||||
}
|
||||
|
@ -225,7 +225,7 @@ main( int argc, char* argv[] )
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::unique_ptr< Calamares::Settings > settings_p( new Calamares::Settings( QString(), true ) );
|
||||
std::unique_ptr< Calamares::Settings > settings_p( Calamares::Settings::init( QString() ) );
|
||||
std::unique_ptr< Calamares::JobQueue > jobqueue_p( new Calamares::JobQueue( nullptr ) );
|
||||
QMainWindow* mw = nullptr;
|
||||
|
||||
|
@ -171,6 +171,18 @@ if ( ECM_FOUND AND BUILD_TESTING )
|
||||
)
|
||||
calamares_automoc( libcalamarestest )
|
||||
|
||||
ecm_add_test(
|
||||
utils/TestPaths.cpp
|
||||
TEST_NAME
|
||||
libcalamarestestpaths
|
||||
LINK_LIBRARIES
|
||||
calamares
|
||||
Qt5::Core
|
||||
Qt5::Test
|
||||
)
|
||||
calamares_automoc( libcalamarestestpaths )
|
||||
|
||||
|
||||
ecm_add_test(
|
||||
geoip/GeoIPTests.cpp
|
||||
${geoip_src}
|
||||
|
@ -21,6 +21,7 @@
|
||||
|
||||
#include "Settings.h"
|
||||
|
||||
#include "CalamaresConfig.h"
|
||||
#include "utils/Dirs.h"
|
||||
#include "utils/Logger.h"
|
||||
#include "utils/Yaml.h"
|
||||
@ -193,8 +194,8 @@ interpretSequence( const YAML::Node& node, Settings::ModuleSequence& moduleSeque
|
||||
}
|
||||
}
|
||||
|
||||
Settings::Settings( const QString& settingsFilePath, bool debugMode, QObject* parent )
|
||||
: QObject( parent )
|
||||
Settings::Settings( const QString& settingsFilePath, bool debugMode )
|
||||
: QObject()
|
||||
, m_debug( debugMode )
|
||||
, m_doChroot( true )
|
||||
, m_promptInstall( false )
|
||||
@ -265,37 +266,93 @@ Settings::brandingComponentName() const
|
||||
return m_brandingComponentName;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Settings::showPromptBeforeExecution() const
|
||||
static QStringList
|
||||
settingsFileCandidates( bool assumeBuilddir )
|
||||
{
|
||||
return m_promptInstall;
|
||||
static const char settings[] = "settings.conf";
|
||||
|
||||
QStringList settingsPaths;
|
||||
if ( CalamaresUtils::isAppDataDirOverridden() )
|
||||
{
|
||||
settingsPaths << CalamaresUtils::appDataDir().absoluteFilePath( settings );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( assumeBuilddir )
|
||||
{
|
||||
settingsPaths << QDir::current().absoluteFilePath( settings );
|
||||
}
|
||||
if ( CalamaresUtils::haveExtraDirs() )
|
||||
for ( auto s : CalamaresUtils::extraConfigDirs() )
|
||||
{
|
||||
settingsPaths << ( s + settings );
|
||||
}
|
||||
settingsPaths << CMAKE_INSTALL_FULL_SYSCONFDIR "/calamares/settings.conf"; // String concat
|
||||
settingsPaths << CalamaresUtils::appDataDir().absoluteFilePath( settings );
|
||||
}
|
||||
|
||||
return settingsPaths;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Settings::debugMode() const
|
||||
Settings*
|
||||
Settings::init( bool debugMode )
|
||||
{
|
||||
return m_debug;
|
||||
if ( s_instance )
|
||||
{
|
||||
cWarning() << "Calamares::Settings already created";
|
||||
return s_instance;
|
||||
}
|
||||
|
||||
QStringList settingsFileCandidatesByPriority = settingsFileCandidates( debugMode );
|
||||
|
||||
QFileInfo settingsFile;
|
||||
bool found = false;
|
||||
|
||||
foreach ( const QString& path, settingsFileCandidatesByPriority )
|
||||
{
|
||||
QFileInfo pathFi( path );
|
||||
if ( pathFi.exists() && pathFi.isReadable() )
|
||||
{
|
||||
settingsFile = pathFi;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !found || !settingsFile.exists() || !settingsFile.isReadable() )
|
||||
{
|
||||
cError() << "Cowardly refusing to continue startup without settings."
|
||||
<< Logger::DebugList( settingsFileCandidatesByPriority );
|
||||
if ( CalamaresUtils::isAppDataDirOverridden() )
|
||||
{
|
||||
cError() << "FATAL: explicitly configured application data directory is missing settings.conf";
|
||||
}
|
||||
else
|
||||
{
|
||||
cError() << "FATAL: none of the expected configuration file paths exist.";
|
||||
}
|
||||
::exit( EXIT_FAILURE );
|
||||
}
|
||||
|
||||
auto* settings = new Calamares::Settings( settingsFile.absoluteFilePath(), debugMode ); // Creates singleton
|
||||
if ( settings->modulesSequence().count() < 1 )
|
||||
{
|
||||
cError() << "FATAL: no sequence set.";
|
||||
::exit( EXIT_FAILURE );
|
||||
}
|
||||
|
||||
return settings;
|
||||
}
|
||||
|
||||
bool
|
||||
Settings::doChroot() const
|
||||
Settings*
|
||||
Settings::init( const QString& path )
|
||||
{
|
||||
return m_doChroot;
|
||||
if ( s_instance )
|
||||
{
|
||||
cWarning() << "Calamares::Settings already created";
|
||||
return s_instance;
|
||||
}
|
||||
return new Calamares::Settings( path, true );
|
||||
}
|
||||
|
||||
bool
|
||||
Settings::disableCancel() const
|
||||
{
|
||||
return m_disableCancel;
|
||||
}
|
||||
|
||||
bool
|
||||
Settings::disableCancelDuringExec() const
|
||||
{
|
||||
return m_disableCancelDuringExec;
|
||||
}
|
||||
|
||||
|
||||
} // namespace Calamares
|
||||
|
@ -35,10 +35,13 @@ namespace Calamares
|
||||
class DLLEXPORT Settings : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
explicit Settings( const QString& settingsFilePath, bool debugMode );
|
||||
public:
|
||||
explicit Settings( const QString& settingsFilePath, bool debugMode, QObject* parent = nullptr );
|
||||
|
||||
static Settings* instance();
|
||||
/// @brief Find a settings.conf, following @p debugMode
|
||||
static Settings* init( bool debugMode );
|
||||
/// @brief Explicif filename, debug is always true (for testing)
|
||||
static Settings* init( const QString& filename );
|
||||
|
||||
QStringList modulesSearchPaths() const;
|
||||
|
||||
@ -51,11 +54,31 @@ public:
|
||||
|
||||
QString brandingComponentName() const;
|
||||
|
||||
bool showPromptBeforeExecution() const;
|
||||
/** @brief Is this a debugging run?
|
||||
*
|
||||
* Returns true if Calamares is in debug mode. In debug mode,
|
||||
* modules and settings are loaded from more locations, to help
|
||||
* development and debugging.
|
||||
*/
|
||||
bool debugMode() const { return m_debug; }
|
||||
|
||||
bool debugMode() const;
|
||||
/** @brief Distinguish "install" from "OEM" modes.
|
||||
*
|
||||
* Returns true in "install" mode, which is where actions happen
|
||||
* in a chroot -- the target system, which exists separately from
|
||||
* the source system. In "OEM" mode, returns false and most actions
|
||||
* apply to the *current* (host) system.
|
||||
*/
|
||||
bool doChroot() const { return m_doChroot; }
|
||||
|
||||
/** @brief Global setting of prompt-before-install.
|
||||
*
|
||||
* Returns true when the configuration is such that the user
|
||||
* should be prompted one-last-time before any action is taken
|
||||
* that really affects the machine.
|
||||
*/
|
||||
bool showPromptBeforeExecution() const { return m_promptInstall; }
|
||||
|
||||
bool doChroot() const;
|
||||
/** @brief Distinguish between "install" and "setup" modes.
|
||||
*
|
||||
* This influences user-visible strings, for instance using the
|
||||
@ -64,9 +87,9 @@ public:
|
||||
bool isSetupMode() const { return m_isSetupMode; }
|
||||
|
||||
/** @brief Global setting of disable-cancel: can't cancel ever. */
|
||||
bool disableCancel() const;
|
||||
bool disableCancel() const { return m_disableCancel; }
|
||||
/** @brief Temporary setting of disable-cancel: can't cancel during exec. */
|
||||
bool disableCancelDuringExec() const;
|
||||
bool disableCancelDuringExec() const { return m_disableCancelDuringExec; }
|
||||
|
||||
private:
|
||||
static Settings* s_instance;
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "Tests.h"
|
||||
|
||||
#include "Manager.h"
|
||||
#include "utils/Logger.h"
|
||||
|
||||
#include <QtTest/QtTest>
|
||||
|
||||
@ -43,6 +44,9 @@ NetworkTests::testInstance()
|
||||
void
|
||||
NetworkTests::testPing()
|
||||
{
|
||||
auto& nam = CalamaresUtils::Network::Manager::instance();
|
||||
QVERIFY( nam.synchronousPing( QUrl( "https://www.kde.org" ) ) );
|
||||
using namespace CalamaresUtils::Network;
|
||||
Logger::setupLogLevel( Logger::LOGVERBOSE );
|
||||
auto& nam = Manager::instance();
|
||||
auto r = nam.synchronousPing( QUrl( "https://www.kde.org" ), RequestOptions( RequestOptions::FollowRedirect ) );
|
||||
QVERIFY( r );
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* === This file is part of Calamares - <https://github.com/calamares> ===
|
||||
*
|
||||
* Copyright 2014, Teo Mrnjavac <teo@kde.org>
|
||||
* Copyright 2017-2018, Adriaan de Groot <groot@kde.org>
|
||||
* Copyright 2017-2018, 2020, Adriaan de Groot <groot@kde.org>
|
||||
*
|
||||
* Calamares is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -263,11 +263,16 @@ System::runCommand( System::RunLocation location,
|
||||
return ProcessResult( r, output );
|
||||
}
|
||||
|
||||
/// @brief Cheap check if a path is absolute.
|
||||
static inline bool
|
||||
isAbsolutePath( const QString& path )
|
||||
{
|
||||
return path.startsWith( '/' );
|
||||
}
|
||||
|
||||
QString
|
||||
System::targetPath( const QString& path ) const
|
||||
{
|
||||
QString completePath;
|
||||
|
||||
if ( doChroot() )
|
||||
{
|
||||
Calamares::GlobalStorage* gs
|
||||
@ -275,18 +280,17 @@ System::targetPath( const QString& path ) const
|
||||
|
||||
if ( !gs || !gs->contains( "rootMountPoint" ) )
|
||||
{
|
||||
cWarning() << "No rootMountPoint in global storage, cannot create target file" << path;
|
||||
cWarning() << "No rootMountPoint in global storage, cannot name target file" << path;
|
||||
return QString();
|
||||
}
|
||||
|
||||
completePath = gs->value( "rootMountPoint" ).toString() + '/' + path;
|
||||
QString root = gs->value( "rootMountPoint" ).toString();
|
||||
return isAbsolutePath( path ) ? ( root + path ) : ( root + '/' + path );
|
||||
}
|
||||
else
|
||||
{
|
||||
completePath = QStringLiteral( "/" ) + path;
|
||||
return isAbsolutePath( path ) ? path : ( QStringLiteral( "/" ) + path );
|
||||
}
|
||||
|
||||
return completePath;
|
||||
}
|
||||
|
||||
QString
|
||||
@ -327,6 +331,59 @@ System::createTargetFile( const QString& path, const QByteArray& contents ) cons
|
||||
return QFileInfo( f ).canonicalFilePath();
|
||||
}
|
||||
|
||||
void
|
||||
System::removeTargetFile( const QString& path ) const
|
||||
{
|
||||
if ( !isAbsolutePath( path ) )
|
||||
{
|
||||
cWarning() << "Will not remove non-absolute path" << path;
|
||||
return;
|
||||
}
|
||||
QString target = targetPath( path );
|
||||
if ( !target.isEmpty() )
|
||||
{
|
||||
QFile::remove( target );
|
||||
}
|
||||
// If it was empty, a warning was already printed
|
||||
}
|
||||
|
||||
bool
|
||||
System::createTargetDirs( const QString& path ) const
|
||||
{
|
||||
if ( !isAbsolutePath( path ) )
|
||||
{
|
||||
cWarning() << "Will not create basedirs for non-absolute path" << path;
|
||||
return false;
|
||||
}
|
||||
|
||||
QString target = targetPath( path );
|
||||
if ( target.isEmpty() )
|
||||
{
|
||||
// If it was empty, a warning was already printed
|
||||
return false;
|
||||
}
|
||||
|
||||
QString root = Calamares::JobQueue::instance()->globalStorage()->value( "rootMountPoint" ).toString();
|
||||
if ( root.isEmpty() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
QDir d( root );
|
||||
if ( !d.exists() )
|
||||
{
|
||||
cWarning() << "Root mountpoint" << root << "does not exist.";
|
||||
return false;
|
||||
}
|
||||
return d.mkpath( target ); // This re-does everything starting from the **host** /
|
||||
}
|
||||
|
||||
bool
|
||||
System::createTargetParentDirs( const QString& filePath ) const
|
||||
{
|
||||
return createTargetDirs( QFileInfo( filePath ).dir().path() );
|
||||
}
|
||||
|
||||
|
||||
QPair< quint64, float >
|
||||
System::getTotalMemoryB() const
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* === This file is part of Calamares - <https://github.com/calamares> ===
|
||||
*
|
||||
* Copyright 2014, Teo Mrnjavac <teo@kde.org>
|
||||
* Copyright 2017-2018, Adriaan de Groot <groot@kde.org>
|
||||
* Copyright 2017-2018, 2020, Adriaan de Groot <groot@kde.org>
|
||||
*
|
||||
* Calamares is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -246,6 +246,33 @@ public:
|
||||
*/
|
||||
DLLEXPORT QString createTargetFile( const QString& path, const QByteArray& contents ) const;
|
||||
|
||||
/** @brief Remove a file from the target system.
|
||||
*
|
||||
* @param path Path to the file; this is interpreted from the root
|
||||
* of the target system (@see targetPath()).
|
||||
*
|
||||
* Does no error checking to see if the target file was really removed.
|
||||
*/
|
||||
DLLEXPORT void removeTargetFile( const QString& path ) const;
|
||||
|
||||
/** @brief Ensure that the directory @p path exists
|
||||
*
|
||||
* @param path a full pathname to a desired directory.
|
||||
*
|
||||
* All the directory components including the last path component are
|
||||
* created, as needed. Returns true on success.
|
||||
*
|
||||
* @see QDir::mkpath
|
||||
*/
|
||||
DLLEXPORT bool createTargetDirs( const QString& path ) const;
|
||||
|
||||
/** @brief Convenience to create parent directories of a file path.
|
||||
*
|
||||
* Creates all the parent directories until the last
|
||||
* component of @p filePath . @see createTargetDirs()
|
||||
*/
|
||||
DLLEXPORT bool createTargetParentDirs( const QString& filePath ) const;
|
||||
|
||||
/**
|
||||
* @brief getTotalMemoryB returns the total main memory, in bytes.
|
||||
*
|
||||
|
@ -27,6 +27,8 @@
|
||||
#include <QEvent>
|
||||
#include <QTranslator>
|
||||
|
||||
static bool s_allowLocalTranslations = false;
|
||||
|
||||
/** @brief Helper class for loading translations
|
||||
*
|
||||
* This is used by the loadSingletonTranslator() function to hand off
|
||||
@ -131,7 +133,7 @@ static bool
|
||||
tryLoad( QTranslator* translator, const QString& prefix, const QString& localeName )
|
||||
{
|
||||
// In debug-mode, try loading from the current directory
|
||||
if ( Calamares::Settings::instance() && Calamares::Settings::instance()->debugMode() && translator->load( prefix + localeName ) )
|
||||
if ( s_allowLocalTranslations && translator->load( prefix + localeName ) )
|
||||
{
|
||||
cDebug() << Logger::SubEntry << "Loaded local translation" << prefix << localeName;
|
||||
return true;
|
||||
@ -139,14 +141,15 @@ tryLoad( QTranslator* translator, const QString& prefix, const QString& localeNa
|
||||
|
||||
// Or load from appDataDir -- often /usr/share/calamares -- subdirectory land/
|
||||
QDir localeData( CalamaresUtils::appDataDir() );
|
||||
if ( localeData.exists() && translator->load( localeData.absolutePath() + QStringLiteral("/lang/") + prefix + localeName) )
|
||||
if ( localeData.exists()
|
||||
&& translator->load( localeData.absolutePath() + QStringLiteral( "/lang/" ) + prefix + localeName ) )
|
||||
{
|
||||
cDebug() << Logger::SubEntry << "Loaded appdata translation" << prefix << localeName;
|
||||
return true;
|
||||
}
|
||||
|
||||
// Or from QRC (most common)
|
||||
if ( translator->load( QStringLiteral( ":/lang/") + prefix + localeName ) )
|
||||
if ( translator->load( QStringLiteral( ":/lang/" ) + prefix + localeName ) )
|
||||
{
|
||||
cDebug() << Logger::SubEntry << "Loaded QRC translation" << prefix << localeName;
|
||||
return true;
|
||||
@ -260,5 +263,11 @@ Retranslator::eventFilter( QObject* obj, QEvent* e )
|
||||
return QObject::eventFilter( obj, e );
|
||||
}
|
||||
|
||||
void
|
||||
setAllowLocalTranslation( bool allow )
|
||||
{
|
||||
s_allowLocalTranslations = allow;
|
||||
}
|
||||
|
||||
|
||||
} // namespace CalamaresUtils
|
||||
|
@ -42,6 +42,15 @@ DLLEXPORT void installTranslator( const QLocale& locale, const QString& branding
|
||||
|
||||
DLLEXPORT QString translatorLocaleName();
|
||||
|
||||
/** @brief Set @p allow to true to load translations from current dir.
|
||||
*
|
||||
* If false, (or never called) the translations are loaded only from
|
||||
* system locations (the AppData dir) and from QRC (compiled in).
|
||||
* Enable local translations to test translations stored in the
|
||||
* current directory.
|
||||
*/
|
||||
DLLEXPORT void setAllowLocalTranslation( bool allow );
|
||||
|
||||
class Retranslator : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
165
src/libcalamares/utils/TestPaths.cpp
Normal file
165
src/libcalamares/utils/TestPaths.cpp
Normal file
@ -0,0 +1,165 @@
|
||||
/* === This file is part of Calamares - <https://github.com/calamares> ===
|
||||
*
|
||||
* Copyright 2018, Adriaan de Groot <groot@kde.org>
|
||||
*
|
||||
* Calamares is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Calamares is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "CalamaresUtilsSystem.h"
|
||||
#include "Entropy.h"
|
||||
#include "Logger.h"
|
||||
#include "UMask.h"
|
||||
#include "Yaml.h"
|
||||
|
||||
#include "GlobalStorage.h"
|
||||
#include "JobQueue.h"
|
||||
|
||||
#include <QDir>
|
||||
// #include <QTemporaryFile>
|
||||
|
||||
#include <QtTest/QtTest>
|
||||
|
||||
// #include <fcntl.h>
|
||||
// #include <sys/stat.h>
|
||||
// #include <unistd.h>
|
||||
|
||||
class TestPaths : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
TestPaths() {};
|
||||
virtual ~TestPaths() {};
|
||||
|
||||
private Q_SLOTS:
|
||||
void initTestCase();
|
||||
void init();
|
||||
void cleanupTestCase();
|
||||
|
||||
void testTargetPath();
|
||||
void testCreateTarget();
|
||||
void testCreateTargetBasedirs();
|
||||
|
||||
private:
|
||||
CalamaresUtils::System* m_system = nullptr; // Points to singleton instance, not owned
|
||||
Calamares::GlobalStorage* m_gs = nullptr;
|
||||
};
|
||||
|
||||
static const char testFile[] = "/calamares-testcreate";
|
||||
static const char absFile[] = "/tmp/calamares-testcreate"; // With rootMountPoint prepended
|
||||
|
||||
void
|
||||
TestPaths::initTestCase()
|
||||
{
|
||||
Logger::setupLogLevel( Logger::LOGDEBUG );
|
||||
|
||||
// Ensure we have a system object, expect it to be a "bogus" one
|
||||
CalamaresUtils::System* system = CalamaresUtils::System::instance();
|
||||
QVERIFY( system );
|
||||
QVERIFY( system->doChroot() );
|
||||
|
||||
// Ensure we have a system-wide GlobalStorage with /tmp as root
|
||||
if ( !Calamares::JobQueue::instance() )
|
||||
{
|
||||
cDebug() << "Creating new JobQueue";
|
||||
(void)new Calamares::JobQueue();
|
||||
}
|
||||
Calamares::GlobalStorage* gs
|
||||
= Calamares::JobQueue::instance() ? Calamares::JobQueue::instance()->globalStorage() : nullptr;
|
||||
QVERIFY( gs );
|
||||
|
||||
m_system = system;
|
||||
m_gs = gs;
|
||||
}
|
||||
|
||||
void
|
||||
TestPaths::cleanupTestCase()
|
||||
{
|
||||
QFile::remove( absFile );
|
||||
}
|
||||
|
||||
void
|
||||
TestPaths::init()
|
||||
{
|
||||
cDebug() << "Setting rootMountPoint";
|
||||
m_gs->insert( "rootMountPoint", "/tmp" );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TestPaths::testTargetPath()
|
||||
{
|
||||
// Paths mapped normally
|
||||
QCOMPARE( m_system->targetPath( "/etc/calamares" ), QStringLiteral( "/tmp/etc/calamares" ) );
|
||||
QCOMPARE( m_system->targetPath( "//etc//calamares" ),
|
||||
QStringLiteral( "/tmp//etc//calamares" ) ); // extra / are not cleaned up
|
||||
QCOMPARE( m_system->targetPath( "etc/calamares" ), QStringLiteral( "/tmp/etc/calamares" ) ); // relative to root
|
||||
|
||||
// Weird Paths
|
||||
QCOMPARE( m_system->targetPath( QString() ), QStringLiteral( "/tmp/" ) );
|
||||
|
||||
// Now break GS
|
||||
m_gs->remove( "rootMountPoint" );
|
||||
QCOMPARE( m_system->targetPath( QString() ), QString() ); // Without root, no path
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TestPaths::testCreateTarget()
|
||||
{
|
||||
QCOMPARE( m_system->createTargetFile( testFile, "Hello" ), QString( absFile ) ); // Success
|
||||
|
||||
QFileInfo fi( absFile );
|
||||
QVERIFY( fi.exists() );
|
||||
QCOMPARE( fi.size(), 5 );
|
||||
|
||||
m_system->removeTargetFile( testFile );
|
||||
QFileInfo fi2( absFile ); // fi caches information
|
||||
QVERIFY( !fi2.exists() );
|
||||
}
|
||||
|
||||
struct DirRemover
|
||||
{
|
||||
DirRemover( const QString& base, const QString& dir )
|
||||
: m_base( base )
|
||||
, m_dir( dir )
|
||||
{
|
||||
}
|
||||
~DirRemover() { QDir( m_base ).rmpath( m_dir ); }
|
||||
|
||||
bool exists() const { return QDir( m_base ).exists( m_dir ); }
|
||||
|
||||
QString m_base, m_dir;
|
||||
};
|
||||
|
||||
void
|
||||
TestPaths::testCreateTargetBasedirs()
|
||||
{
|
||||
{
|
||||
DirRemover dirrm( "/tmp", "var/lib/dbus" );
|
||||
QVERIFY( m_system->createTargetDirs( "/" ) );
|
||||
QVERIFY( m_system->createTargetDirs( "/var/lib/dbus" ) );
|
||||
QVERIFY( QFile( "/tmp/var/lib/dbus" ).exists() );
|
||||
QVERIFY( dirrm.exists() );
|
||||
}
|
||||
QVERIFY( !QFile( "/tmp/var/lib/dbus" ).exists() );
|
||||
|
||||
// QFileInfo.dir() behaves even when things don't exist
|
||||
QCOMPARE( QFileInfo( "/tmp/var/lib/dbus/bogus" ).dir().path(), QStringLiteral( "/tmp/var/lib/dbus" ) );
|
||||
}
|
||||
|
||||
QTEST_GUILESS_MAIN( TestPaths )
|
||||
|
||||
#include "utils/moc-warnings.h"
|
||||
|
||||
#include "TestPaths.moc"
|
@ -24,6 +24,9 @@
|
||||
#include "UMask.h"
|
||||
#include "Yaml.h"
|
||||
|
||||
#include "GlobalStorage.h"
|
||||
#include "JobQueue.h"
|
||||
|
||||
#include <QTemporaryFile>
|
||||
|
||||
#include <QtTest/QtTest>
|
||||
|
@ -18,6 +18,8 @@ set( calamaresui_SOURCES
|
||||
utils/Paste.cpp
|
||||
|
||||
viewpages/BlankViewStep.cpp
|
||||
viewpages/ExecutionViewStep.cpp
|
||||
viewpages/QmlViewStep.cpp
|
||||
viewpages/ViewStep.cpp
|
||||
|
||||
widgets/ClickableLabel.cpp
|
||||
@ -25,7 +27,6 @@ set( calamaresui_SOURCES
|
||||
widgets/WaitingWidget.cpp
|
||||
${CMAKE_SOURCE_DIR}/3rdparty/waitingspinnerwidget.cpp
|
||||
|
||||
ExecutionViewStep.cpp
|
||||
Branding.cpp
|
||||
ViewManager.cpp
|
||||
)
|
||||
|
@ -21,17 +21,16 @@
|
||||
|
||||
#include "ViewManager.h"
|
||||
|
||||
#include "viewpages/BlankViewStep.h"
|
||||
#include "viewpages/ViewStep.h"
|
||||
|
||||
#include "Branding.h"
|
||||
#include "ExecutionViewStep.h"
|
||||
#include "JobQueue.h"
|
||||
#include "Settings.h"
|
||||
|
||||
#include "utils/Logger.h"
|
||||
#include "utils/Paste.h"
|
||||
#include "utils/Retranslator.h"
|
||||
#include "viewpages/BlankViewStep.h"
|
||||
#include "viewpages/ViewStep.h"
|
||||
#include "viewpages/ExecutionViewStep.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QBoxLayout>
|
||||
@ -159,13 +158,6 @@ void
|
||||
ViewManager::insertViewStep( int before, ViewStep* step )
|
||||
{
|
||||
m_steps.insert( before, step );
|
||||
QLayout* layout = step->widget()->layout();
|
||||
if ( layout )
|
||||
{
|
||||
layout->setContentsMargins( 0, 0, 0, 0 );
|
||||
}
|
||||
m_stack->insertWidget( before, step->widget() );
|
||||
|
||||
connect( step, &ViewStep::enlarge, this, &ViewManager::enlarge );
|
||||
connect( step, &ViewStep::nextStatusChanged, this, [this]( bool status ) {
|
||||
ViewStep* vs = qobject_cast< ViewStep* >( sender() );
|
||||
@ -178,6 +170,17 @@ ViewManager::insertViewStep( int before, ViewStep* step )
|
||||
}
|
||||
} );
|
||||
|
||||
if ( !step->widget() )
|
||||
{
|
||||
cError() << "ViewStep" << step->moduleInstanceKey() << "has no widget.";
|
||||
}
|
||||
|
||||
QLayout* layout = step->widget()->layout();
|
||||
if ( layout )
|
||||
{
|
||||
layout->setContentsMargins( 0, 0, 0, 0 );
|
||||
}
|
||||
m_stack->insertWidget( before, step->widget() );
|
||||
m_stack->setCurrentIndex( 0 );
|
||||
step->widget()->setFocus();
|
||||
}
|
||||
|
@ -19,7 +19,6 @@
|
||||
|
||||
#include "ModuleManager.h"
|
||||
|
||||
#include "ExecutionViewStep.h"
|
||||
#include "Module.h"
|
||||
#include "RequirementsChecker.h"
|
||||
#include "Settings.h"
|
||||
@ -27,6 +26,7 @@
|
||||
|
||||
#include "utils/Logger.h"
|
||||
#include "utils/Yaml.h"
|
||||
#include "viewpages/ExecutionViewStep.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QDir>
|
||||
@ -129,7 +129,8 @@ ModuleManager::doInit()
|
||||
}
|
||||
// At this point m_availableDescriptorsByModuleName is filled with
|
||||
// the modules that were found in the search paths.
|
||||
cDebug() << "Found" << m_availableDescriptorsByModuleName.count() << "modules"
|
||||
cDebug() << "Found"
|
||||
<< m_availableDescriptorsByModuleName.count() << "modules"
|
||||
<< m_moduleDirectoriesByModuleName.count() << "names";
|
||||
emit initDone();
|
||||
}
|
||||
|
@ -19,12 +19,7 @@
|
||||
#ifndef BLANKVIEWSTEP_H
|
||||
#define BLANKVIEWSTEP_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include <utils/PluginFactory.h>
|
||||
#include <viewpages/ViewStep.h>
|
||||
|
||||
class QWidget;
|
||||
#include "viewpages/ViewStep.h"
|
||||
|
||||
namespace Calamares
|
||||
{
|
||||
|
@ -18,16 +18,16 @@
|
||||
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <ExecutionViewStep.h>
|
||||
#include "ExecutionViewStep.h"
|
||||
|
||||
#include "Branding.h"
|
||||
#include "Job.h"
|
||||
#include "JobQueue.h"
|
||||
#include "Settings.h"
|
||||
#include "ViewManager.h"
|
||||
|
||||
#include "modulesystem/Module.h"
|
||||
#include "modulesystem/ModuleManager.h"
|
||||
|
||||
#include "utils/CalamaresUtilsGui.h"
|
||||
#include "utils/Dirs.h"
|
||||
#include "utils/Logger.h"
|
277
src/libcalamaresui/viewpages/QmlViewStep.cpp
Normal file
277
src/libcalamaresui/viewpages/QmlViewStep.cpp
Normal file
@ -0,0 +1,277 @@
|
||||
/* === This file is part of Calamares - <https://github.com/calamares> ===
|
||||
*
|
||||
* Copyright 2020, Adriaan de Groot <groot@kde.org>
|
||||
*
|
||||
* Calamares is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Calamares is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "QmlViewStep.h"
|
||||
|
||||
#include "Branding.h"
|
||||
|
||||
#include "utils/Dirs.h"
|
||||
#include "utils/Logger.h"
|
||||
#include "utils/NamedEnum.h"
|
||||
#include "utils/Variant.h"
|
||||
#include "widgets/WaitingWidget.h"
|
||||
|
||||
#include <QQmlComponent>
|
||||
#include <QQmlEngine>
|
||||
#include <QQuickItem>
|
||||
#include <QQuickWidget>
|
||||
#include <QVBoxLayout>
|
||||
#include <QWidget>
|
||||
|
||||
static const NamedEnumTable< Calamares::QmlViewStep::QmlSearch >&
|
||||
searchNames()
|
||||
{
|
||||
using Search = Calamares::QmlViewStep::QmlSearch;
|
||||
// *INDENT-OFF*
|
||||
// clang-format off
|
||||
static NamedEnumTable< Search > names {
|
||||
{ QStringLiteral( "both" ), Search::Both },
|
||||
{ QStringLiteral( "qrc" ), Search::QrcOnly },
|
||||
{ QStringLiteral( "branding" ), Search::BrandingOnly }
|
||||
};
|
||||
// *INDENT-ON*
|
||||
// clang-format on
|
||||
|
||||
return names;
|
||||
}
|
||||
|
||||
namespace Calamares
|
||||
{
|
||||
|
||||
QmlViewStep::QmlViewStep( const QString& name, QObject* parent )
|
||||
: ViewStep( parent )
|
||||
, m_name( name )
|
||||
, m_widget( new QWidget )
|
||||
, m_spinner( new WaitingWidget( tr( "Loading ..." ) ) )
|
||||
, m_qmlWidget( new QQuickWidget )
|
||||
{
|
||||
QVBoxLayout* layout = new QVBoxLayout( m_widget );
|
||||
layout->addWidget( m_spinner );
|
||||
|
||||
m_qmlWidget->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding );
|
||||
m_qmlWidget->setResizeMode( QQuickWidget::SizeRootObjectToView );
|
||||
m_qmlWidget->engine()->addImportPath( CalamaresUtils::qmlModulesDir().absolutePath() );
|
||||
|
||||
// QML Loading starts when the configuration for the module is set.
|
||||
}
|
||||
|
||||
QmlViewStep::~QmlViewStep() {}
|
||||
|
||||
QString
|
||||
QmlViewStep::prettyName() const
|
||||
{
|
||||
// TODO: query the QML itself
|
||||
return tr( "QML Step <i>%1</i>." ).arg( m_name );
|
||||
}
|
||||
|
||||
|
||||
} // namespace Calamares
|
||||
|
||||
bool
|
||||
Calamares::QmlViewStep::isAtBeginning() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
Calamares::QmlViewStep::isAtEnd() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
bool
|
||||
Calamares::QmlViewStep::isBackEnabled() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
Calamares::QmlViewStep::isNextEnabled() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
Calamares::JobList
|
||||
Calamares::QmlViewStep::jobs() const
|
||||
{
|
||||
return JobList();
|
||||
}
|
||||
|
||||
void
|
||||
Calamares::QmlViewStep::onActivate()
|
||||
{
|
||||
// TODO: call into QML
|
||||
}
|
||||
|
||||
void
|
||||
Calamares::QmlViewStep::onLeave()
|
||||
{
|
||||
// TODO: call into QML
|
||||
}
|
||||
|
||||
QWidget*
|
||||
Calamares::QmlViewStep::widget()
|
||||
{
|
||||
return m_widget;
|
||||
}
|
||||
|
||||
void
|
||||
Calamares::QmlViewStep::loadComplete()
|
||||
{
|
||||
cDebug() << "QML component" << m_qmlFileName << m_qmlComponent->status();
|
||||
if ( m_qmlComponent->status() == QQmlComponent::Error )
|
||||
{
|
||||
showFailedQml();
|
||||
}
|
||||
if ( m_qmlComponent->isReady() && !m_qmlObject )
|
||||
{
|
||||
cDebug() << "QML component complete" << m_qmlFileName;
|
||||
// Don't do this again
|
||||
disconnect( m_qmlComponent, &QQmlComponent::statusChanged, this, &QmlViewStep::loadComplete );
|
||||
|
||||
QObject* o = m_qmlComponent->create();
|
||||
m_qmlObject = qobject_cast< QQuickItem* >( o );
|
||||
if ( !m_qmlObject )
|
||||
{
|
||||
cError() << Logger::SubEntry << "Could not create QML from" << m_qmlFileName;
|
||||
delete o;
|
||||
}
|
||||
else
|
||||
{
|
||||
// setContent() is public API, but not documented publicly.
|
||||
// It is marked \internal in the Qt sources, but does exactly
|
||||
// what is needed: sets up visual parent by replacing the root
|
||||
// item, and handling resizes.
|
||||
m_qmlWidget->setContent( QUrl( m_qmlFileName ), m_qmlComponent, m_qmlObject );
|
||||
showQml();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Calamares::QmlViewStep::showQml()
|
||||
{
|
||||
if ( !m_qmlWidget || !m_qmlObject )
|
||||
{
|
||||
cDebug() << "showQml() called but no QML object";
|
||||
return;
|
||||
}
|
||||
if ( m_spinner )
|
||||
{
|
||||
m_widget->layout()->removeWidget( m_spinner );
|
||||
m_widget->layout()->addWidget( m_qmlWidget );
|
||||
delete m_spinner;
|
||||
m_spinner = nullptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
cDebug() << "showQml() called twice";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** @brief Find a suitable QML file, given the search method and name hints
|
||||
*
|
||||
* Returns QString() if nothing is found (which would mean the module
|
||||
* is badly configured).
|
||||
*/
|
||||
QString
|
||||
searchQmlFile( Calamares::QmlViewStep::QmlSearch method, const QString& configuredName, const QString& moduleName )
|
||||
{
|
||||
using QmlSearch = Calamares::QmlViewStep::QmlSearch;
|
||||
|
||||
cDebug() << "Looking for QML for" << moduleName;
|
||||
QStringList candidates;
|
||||
if ( configuredName.startsWith( '/' ) )
|
||||
{
|
||||
candidates << configuredName;
|
||||
}
|
||||
if ( ( method == QmlSearch::Both ) || ( method == QmlSearch::BrandingOnly ) )
|
||||
{
|
||||
QString brandDir = Calamares::Branding::instance()->componentDirectory();
|
||||
candidates << ( configuredName.isEmpty() ? QString()
|
||||
: QStringLiteral( "%1/%2.qml" ).arg( brandDir, configuredName ) )
|
||||
<< ( moduleName.isEmpty() ? QString() : QStringLiteral( "%1/%2.qml" ).arg( brandDir, moduleName ) );
|
||||
}
|
||||
if ( ( method == QmlSearch::Both ) || ( method == QmlSearch::QrcOnly ) )
|
||||
{
|
||||
candidates << ( configuredName.isEmpty() ? QString() : QStringLiteral( ":/%1.qml" ).arg( configuredName ) )
|
||||
<< ( moduleName.isEmpty() ? QString() : QStringLiteral( ":/%1.qml" ).arg( moduleName ) );
|
||||
}
|
||||
for ( const QString& candidate : candidates )
|
||||
{
|
||||
if ( candidate.isEmpty() )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
cDebug() << Logger::SubEntry << "Looking at QML file" << candidate;
|
||||
if ( QFile::exists( candidate ) )
|
||||
{
|
||||
if ( candidate.startsWith( ':' ) )
|
||||
{
|
||||
// Inconsistency: QFile only sees the file with :,
|
||||
// but QML needs an explicit scheme (of qrc:)
|
||||
return QStringLiteral( "qrc" ) + candidate;
|
||||
}
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
cDebug() << Logger::SubEntry << "None found.";
|
||||
return QString();
|
||||
}
|
||||
|
||||
void
|
||||
Calamares::QmlViewStep::setConfigurationMap( const QVariantMap& configurationMap )
|
||||
{
|
||||
bool ok = false;
|
||||
m_searchMethod = searchNames().find( CalamaresUtils::getString( configurationMap, "search" ), ok );
|
||||
if ( !ok )
|
||||
{
|
||||
cDebug() << "Bad QML search mode.";
|
||||
}
|
||||
|
||||
QString qmlFile = CalamaresUtils::getString( configurationMap, "filename" );
|
||||
if ( qmlFile.isEmpty() )
|
||||
{
|
||||
// TODO use the module instance
|
||||
}
|
||||
|
||||
if ( !m_qmlComponent )
|
||||
{
|
||||
m_qmlFileName = searchQmlFile( m_searchMethod, qmlFile, m_name );
|
||||
|
||||
cDebug() << "QmlViewStep" << moduleInstanceKey() << "loading" << m_qmlFileName;
|
||||
m_qmlComponent = new QQmlComponent(
|
||||
m_qmlWidget->engine(), QUrl( m_qmlFileName ), QQmlComponent::CompilationMode::Asynchronous );
|
||||
connect( m_qmlComponent, &QQmlComponent::statusChanged, this, &QmlViewStep::loadComplete );
|
||||
if ( m_qmlComponent->status() == QQmlComponent::Error )
|
||||
{
|
||||
showFailedQml();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cWarning() << "QML configuration set after component has loaded.";
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Calamares::QmlViewStep::showFailedQml()
|
||||
{
|
||||
cWarning() << "QmlViewStep" << moduleInstanceKey() << "loading failed.";
|
||||
m_spinner->setText( prettyName() + ' ' + tr( "Loading failed." ) );
|
||||
}
|
102
src/libcalamaresui/viewpages/QmlViewStep.h
Normal file
102
src/libcalamaresui/viewpages/QmlViewStep.h
Normal file
@ -0,0 +1,102 @@
|
||||
/* === This file is part of Calamares - <https://github.com/calamares> ===
|
||||
*
|
||||
* Copyright 2020, Adriaan de Groot <groot@kde.org>
|
||||
*
|
||||
* Calamares is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Calamares is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef QMLVIEWSTEP_H
|
||||
#define QMLVIEWSTEP_H
|
||||
|
||||
#include "viewpages/ViewStep.h"
|
||||
|
||||
class QQmlComponent;
|
||||
class QQuickItem;
|
||||
class QQuickWidget;
|
||||
class WaitingWidget;
|
||||
|
||||
namespace Calamares
|
||||
{
|
||||
|
||||
/** @brief A viewstep that uses QML for the UI
|
||||
*
|
||||
* This is generally a **base** class for other view steps, but
|
||||
* it can be used stand-alone for viewsteps that don't really have
|
||||
* any functionality.
|
||||
*/
|
||||
class QmlViewStep : public Calamares::ViewStep
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
enum class QmlSearch
|
||||
{
|
||||
QrcOnly,
|
||||
BrandingOnly,
|
||||
Both
|
||||
};
|
||||
|
||||
/** @brief Creates a QML view step
|
||||
*
|
||||
* The name should not have an extension or schema or anything;
|
||||
* just the plain name, which will be searched as "/<name>.qml" in
|
||||
* QRC files, or "<name>.qml" in suitable branding paths.
|
||||
* The search behavior depends on a QmlSearch value.
|
||||
*/
|
||||
QmlViewStep( const QString& name, QObject* parent = nullptr );
|
||||
virtual ~QmlViewStep() override;
|
||||
|
||||
virtual QString prettyName() const override;
|
||||
|
||||
virtual QWidget* widget() override;
|
||||
|
||||
virtual bool isNextEnabled() const override;
|
||||
virtual bool isBackEnabled() const override;
|
||||
|
||||
virtual bool isAtBeginning() const override;
|
||||
virtual bool isAtEnd() const override;
|
||||
|
||||
virtual void onActivate() override;
|
||||
virtual void onLeave() override;
|
||||
|
||||
/// @brief QML widgets don't produce jobs by default
|
||||
virtual JobList jobs() const override;
|
||||
|
||||
/// @brief Configure search paths; subclasses should call this as well
|
||||
virtual void setConfigurationMap( const QVariantMap& configurationMap ) override;
|
||||
|
||||
private Q_SLOTS:
|
||||
void loadComplete();
|
||||
|
||||
private:
|
||||
/// @brief Swap out the spinner for the QQuickWidget
|
||||
void showQml();
|
||||
/// @brief Show error message in spinner.
|
||||
void showFailedQml();
|
||||
|
||||
/// @brief Controls where m_name is searched
|
||||
QmlSearch m_searchMethod;
|
||||
|
||||
QString m_name;
|
||||
QString m_qmlFileName;
|
||||
|
||||
QWidget* m_widget = nullptr;
|
||||
WaitingWidget* m_spinner = nullptr;
|
||||
QQuickWidget* m_qmlWidget = nullptr;
|
||||
QQmlComponent* m_qmlComponent = nullptr;
|
||||
QQuickItem* m_qmlObject = nullptr;
|
||||
};
|
||||
|
||||
} // namespace Calamares
|
||||
#endif
|
11
src/modules/dummyqml/CMakeLists.txt
Normal file
11
src/modules/dummyqml/CMakeLists.txt
Normal file
@ -0,0 +1,11 @@
|
||||
calamares_add_plugin( dummyqml
|
||||
TYPE viewmodule
|
||||
EXPORT_MACRO PLUGINDLLEXPORT_PRO
|
||||
SOURCES
|
||||
DummyQmlViewStep.cpp
|
||||
RESOURCES
|
||||
dummyqml.qrc
|
||||
LINK_PRIVATE_LIBRARIES
|
||||
calamaresui
|
||||
SHARED_LIB
|
||||
)
|
52
src/modules/dummyqml/DummyQmlViewStep.cpp
Normal file
52
src/modules/dummyqml/DummyQmlViewStep.cpp
Normal file
@ -0,0 +1,52 @@
|
||||
/* === This file is part of Calamares - <https://github.com/calamares> ===
|
||||
*
|
||||
* Copyright 2020, Adriaan de Groot <groot@kde.org>
|
||||
* Copyright 2020, Anke Boersma <demm@kaosx.us>
|
||||
*
|
||||
* Calamares is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Calamares is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "DummyQmlViewStep.h"
|
||||
|
||||
#include <QVariant>
|
||||
|
||||
DummyQmlViewStep::DummyQmlViewStep( QObject* parent )
|
||||
: Calamares::QmlViewStep( "dummyqml", parent )
|
||||
{
|
||||
}
|
||||
|
||||
DummyQmlViewStep::~DummyQmlViewStep() {}
|
||||
|
||||
QString
|
||||
DummyQmlViewStep::prettyName() const
|
||||
{
|
||||
return m_notesName ? m_notesName->get() : tr( "Notes" );
|
||||
}
|
||||
|
||||
void
|
||||
DummyQmlViewStep::setConfigurationMap( const QVariantMap& configurationMap )
|
||||
{
|
||||
Calamares::QmlViewStep::setConfigurationMap( configurationMap ); // call parent implementation
|
||||
|
||||
bool qmlLabel_ok = false;
|
||||
auto qmlLabel = CalamaresUtils::getSubMap( configurationMap, "qmlLabel", qmlLabel_ok );
|
||||
|
||||
if ( qmlLabel.contains( "notes" ) )
|
||||
{
|
||||
m_notesName = new CalamaresUtils::Locale::TranslatedString( qmlLabel, "notes" );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
CALAMARES_PLUGIN_FACTORY_DEFINITION( DummyQmlViewStepFactory, registerPlugin< DummyQmlViewStep >(); )
|
48
src/modules/dummyqml/DummyQmlViewStep.h
Normal file
48
src/modules/dummyqml/DummyQmlViewStep.h
Normal file
@ -0,0 +1,48 @@
|
||||
/* === This file is part of Calamares - <https://github.com/calamares> ===
|
||||
*
|
||||
* Copyright 2020, Adriaan de Groot <groot@kde.org>
|
||||
* Copyright 2020, Anke Boersma <demm@kaosx.us>
|
||||
*
|
||||
* Calamares is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Calamares is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef DUMMYQMLVIEWSTEP_H
|
||||
#define DUMMYQMLVIEWSTEP_H
|
||||
|
||||
#include "PluginDllMacro.h"
|
||||
#include "locale/TranslatableConfiguration.h"
|
||||
#include "utils/CalamaresUtilsSystem.h"
|
||||
#include "utils/Variant.h"
|
||||
#include "utils/PluginFactory.h"
|
||||
#include "viewpages/QmlViewStep.h"
|
||||
|
||||
class PLUGINDLLEXPORT DummyQmlViewStep : public Calamares::QmlViewStep
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
DummyQmlViewStep( QObject* parent = nullptr );
|
||||
virtual ~DummyQmlViewStep() override;
|
||||
|
||||
QString prettyName() const override;
|
||||
|
||||
void setConfigurationMap( const QVariantMap& configurationMap ) override;
|
||||
|
||||
private:
|
||||
CalamaresUtils::Locale::TranslatedString* m_notesName; // As it appears in the sidebar
|
||||
};
|
||||
|
||||
CALAMARES_PLUGIN_FACTORY_DECLARATION( DummyQmlViewStepFactory )
|
||||
|
||||
#endif
|
29
src/modules/dummyqml/dummyqml.conf
Normal file
29
src/modules/dummyqml/dummyqml.conf
Normal file
@ -0,0 +1,29 @@
|
||||
# The dummy QML module just displays a QML page. It doesn't
|
||||
# have much in the way of own configuration, only where
|
||||
# the QML file is searched.
|
||||
#
|
||||
# QML modules can search for the QML inside the Qt resources
|
||||
# (QRC) which are compiled into the module, or in the branding
|
||||
# setup for Calamares, (or both of them, with branding taking
|
||||
# precedence). This allows the module to ship a default UI and
|
||||
# branding to optionally introduce a replacement file.
|
||||
#
|
||||
# Generally, leave the search method set to "both" because if
|
||||
# you don't want to brand the UI, just don't ship a branding
|
||||
# QML file for it.
|
||||
#
|
||||
# To support instanced QML modules, searches in the branding
|
||||
# directory look for the full module@instanceid name as well.
|
||||
---
|
||||
# Search mode. Valid values are "both", "qrc" and "branding"
|
||||
search: both
|
||||
|
||||
# Name of the QML file. If not set, uses the name of the instance
|
||||
# of the module (e.g. if you list this module in `settings.conf`
|
||||
# in the *instances* section, you get *id*, otherwise it would
|
||||
# normally be "dummyqml").
|
||||
# filename: dummyqml
|
||||
|
||||
qmlLabel:
|
||||
notes: "Release Notes"
|
||||
notes[nl]: "Opmerkingen"
|
73
src/modules/dummyqml/dummyqml.qml
Normal file
73
src/modules/dummyqml/dummyqml.qml
Normal file
@ -0,0 +1,73 @@
|
||||
/* === This file is part of Calamares - <https://github.com/calamares> ===
|
||||
*
|
||||
* Copyright 2020, Anke Boersma <demm@kaosx.us>
|
||||
*
|
||||
* Calamares is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Calamares is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import QtQuick 2.7
|
||||
import QtQuick.Controls 2.2
|
||||
import QtQuick.Window 2.2
|
||||
import QtQuick.Layouts 1.3
|
||||
import QtQuick.Controls.Material 2.1
|
||||
|
||||
Item {
|
||||
width: 740
|
||||
height: 420
|
||||
|
||||
Flickable {
|
||||
id: flick
|
||||
anchors.fill: parent
|
||||
contentHeight: 800
|
||||
|
||||
ScrollBar.vertical: ScrollBar {
|
||||
width: 10
|
||||
policy: ScrollBar.AlwaysOn
|
||||
}
|
||||
|
||||
TextArea {
|
||||
id: intro
|
||||
x: 1
|
||||
y: 0
|
||||
width: 720
|
||||
font.pointSize: 14
|
||||
textFormat: Text.RichText
|
||||
antialiasing: true
|
||||
activeFocusOnPress: false
|
||||
wrapMode: Text.WordWrap
|
||||
|
||||
text: qsTr("<h3>Generic GNU/Linux 2017.8 LTS <quote>Soapy Sousaphone</quote></h3>
|
||||
<p>This an example QML file, showing options in RichText with Flickable content.</p>
|
||||
|
||||
<p>QML with RichText can use HTML tags, Flickable content is useful for touchscreens.</p>
|
||||
|
||||
<p><b>This is bold text</b></p>
|
||||
<p><i>This is italic text</i></p>
|
||||
<p><u>This is underlined text</u></p>
|
||||
<p><strike>This is strikethrough</strike></p>
|
||||
|
||||
<p>Code example:
|
||||
<code>ls -l /home</code></p>
|
||||
|
||||
<p><b>Lists:</b></p>
|
||||
<ul>
|
||||
<li>Intel CPU systems</li>
|
||||
<li>AMD CPU systems</li>
|
||||
</ul>
|
||||
|
||||
<p>The vertical scrollbar is adjustable, current width set to 10.</p>")
|
||||
|
||||
}
|
||||
}
|
||||
}
|
5
src/modules/dummyqml/dummyqml.qrc
Normal file
5
src/modules/dummyqml/dummyqml.qrc
Normal file
@ -0,0 +1,5 @@
|
||||
<!DOCTYPE RCC><RCC version="1.0">
|
||||
<qresource>
|
||||
<file alias="dummyqml.qml">dummyqml.qml</file>
|
||||
</qresource>
|
||||
</RCC>
|
@ -12,6 +12,7 @@ calamares_add_plugin( machineid
|
||||
if ( ECM_FOUND AND BUILD_TESTING )
|
||||
ecm_add_test(
|
||||
Tests.cpp
|
||||
MachineIdJob.cpp
|
||||
Workers.cpp
|
||||
TEST_NAME
|
||||
machineidtest
|
||||
|
@ -3,7 +3,7 @@
|
||||
* Copyright 2014, Kevin Kofler <kevin.kofler@chello.at>
|
||||
* Copyright 2016, Philip Müller <philm@manjaro.org>
|
||||
* Copyright 2017, Alf Gaida <agaida@siduction.org>
|
||||
* Copyright 2019, Adriaan de Groot <groot@kde.org>
|
||||
* Copyright 2019-2020, Adriaan de Groot <groot@kde.org>
|
||||
*
|
||||
* Calamares is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@ -68,18 +68,20 @@ MachineIdJob::exec()
|
||||
QString target_dbus_machineid_file = QStringLiteral( "/var/lib/dbus/machine-id" );
|
||||
QString target_entropy_file = QStringLiteral( "/var/lib/urandom/random-seed" );
|
||||
|
||||
const CalamaresUtils::System* system = CalamaresUtils::System::instance();
|
||||
|
||||
// Clear existing files
|
||||
if ( m_entropy )
|
||||
{
|
||||
MachineId::removeFile( root, target_entropy_file );
|
||||
system->removeTargetFile( target_entropy_file );
|
||||
}
|
||||
if ( m_dbus )
|
||||
{
|
||||
MachineId::removeFile( root, target_dbus_machineid_file );
|
||||
system->removeTargetFile( target_dbus_machineid_file );
|
||||
}
|
||||
if ( m_systemd )
|
||||
{
|
||||
MachineId::removeFile( root, target_systemd_machineid_file );
|
||||
system->removeTargetFile( target_systemd_machineid_file );
|
||||
}
|
||||
|
||||
//Create new files
|
||||
@ -104,6 +106,10 @@ MachineIdJob::exec()
|
||||
}
|
||||
if ( m_dbus )
|
||||
{
|
||||
if ( !system->createTargetParentDirs( target_dbus_machineid_file ) )
|
||||
{
|
||||
cWarning() << "Could not create DBus data-directory.";
|
||||
}
|
||||
if ( m_dbus_symlink && QFile::exists( root + target_systemd_machineid_file ) )
|
||||
{
|
||||
auto r = MachineId::createDBusLink( root, target_dbus_machineid_file, target_systemd_machineid_file );
|
||||
|
@ -16,11 +16,14 @@
|
||||
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "MachineIdJob.h"
|
||||
#include "Workers.h"
|
||||
|
||||
#include "GlobalStorage.h"
|
||||
#include "JobQueue.h"
|
||||
#include "utils/CalamaresUtilsSystem.h"
|
||||
#include "utils/Logger.h"
|
||||
|
||||
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QtTest/QtTest>
|
||||
@ -35,10 +38,11 @@ public:
|
||||
private Q_SLOTS:
|
||||
void initTestCase();
|
||||
|
||||
void testRemoveFile();
|
||||
void testCopyFile();
|
||||
|
||||
void testPoolSize();
|
||||
|
||||
void testJob();
|
||||
};
|
||||
|
||||
void
|
||||
@ -84,11 +88,6 @@ MachineIdTests::testCopyFile()
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MachineIdTests::testRemoveFile()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
MachineIdTests::testPoolSize()
|
||||
{
|
||||
@ -101,6 +100,62 @@ MachineIdTests::testPoolSize()
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
MachineIdTests::testJob()
|
||||
{
|
||||
Logger::setupLogLevel( Logger::LOGDEBUG );
|
||||
|
||||
// Ensure we have a system object, expect it to be a "bogus" one
|
||||
CalamaresUtils::System* system = CalamaresUtils::System::instance();
|
||||
QVERIFY( system );
|
||||
QVERIFY( system->doChroot() );
|
||||
|
||||
// Ensure we have a system-wide GlobalStorage with /tmp as root
|
||||
if ( !Calamares::JobQueue::instance() )
|
||||
{
|
||||
cDebug() << "Creating new JobQueue";
|
||||
(void)new Calamares::JobQueue();
|
||||
}
|
||||
Calamares::GlobalStorage* gs
|
||||
= Calamares::JobQueue::instance() ? Calamares::JobQueue::instance()->globalStorage() : nullptr;
|
||||
QVERIFY( gs );
|
||||
gs->insert( "rootMountPoint", "/tmp" );
|
||||
|
||||
// Prepare part of the target filesystem
|
||||
QVERIFY( system->createTargetDirs("/etc") );
|
||||
QVERIFY( !(system->createTargetFile( "/etc/machine-id", "Hello" ).isEmpty() ) );
|
||||
|
||||
MachineIdJob job( nullptr );
|
||||
QVERIFY( !job.prettyName().isEmpty() );
|
||||
|
||||
QVariantMap config;
|
||||
config.insert( "dbus", true );
|
||||
job.setConfigurationMap( config );
|
||||
|
||||
{
|
||||
auto r = job.exec();
|
||||
QVERIFY( !r ); // It's supposed to fail, because no dbus-uuidgen executable exists
|
||||
QVERIFY( QFile::exists( "/tmp/var/lib/dbus" ) ); // but the target dir exists
|
||||
}
|
||||
|
||||
config.insert( "dbus-symlink", true );
|
||||
job.setConfigurationMap( config );
|
||||
{
|
||||
auto r = job.exec();
|
||||
QVERIFY( !r ); // It's supposed to fail, because no dbus-uuidgen executable exists
|
||||
QVERIFY( QFile::exists( "/tmp/var/lib/dbus" ) ); // but the target dir exists
|
||||
|
||||
// These all (would) fail, because the chroot isn't viable
|
||||
#if 0
|
||||
QVERIFY( QFile::exists( "/tmp/var/lib/dbus/machine-id" ) );
|
||||
|
||||
QFileInfo fi( "/tmp/var/lib/dbus/machine-id" );
|
||||
QVERIFY( fi.exists() );
|
||||
QVERIFY( fi.isSymLink() );
|
||||
QCOMPARE( fi.size(), 5);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
QTEST_GUILESS_MAIN( MachineIdTests )
|
||||
|
||||
|
@ -36,17 +36,6 @@ isAbsolutePath( const QString& fileName )
|
||||
return fileName.startsWith( '/' );
|
||||
}
|
||||
|
||||
// might need to use a helper to remove the file
|
||||
void
|
||||
removeFile( const QString& rootMountPoint, const QString& fileName )
|
||||
{
|
||||
if ( isAbsolutePath( fileName ) )
|
||||
{
|
||||
QFile::remove( rootMountPoint + fileName );
|
||||
}
|
||||
// Otherwise, do nothing
|
||||
}
|
||||
|
||||
Calamares::JobResult
|
||||
copyFile( const QString& rootMountPoint, const QString& fileName )
|
||||
{
|
||||
@ -192,7 +181,7 @@ Calamares::JobResult
|
||||
createDBusLink( const QString& rootMountPoint, const QString& fileName, const QString& systemdFileName )
|
||||
{
|
||||
Q_UNUSED( rootMountPoint )
|
||||
return runCmd( QStringList { QStringLiteral( "ln" ), QStringLiteral( "-s" ), systemdFileName, fileName } );
|
||||
return runCmd( QStringList { QStringLiteral( "ln" ), QStringLiteral( "-sf" ), systemdFileName, fileName } );
|
||||
}
|
||||
|
||||
} // namespace MachineId
|
||||
|
@ -30,9 +30,6 @@ namespace MachineId
|
||||
* for moving files around in the target system.
|
||||
*/
|
||||
|
||||
/// @brief Remove @p fileName from the target system at @p rootMountPoint
|
||||
void removeFile( const QString& rootMountPoint, const QString& fileName );
|
||||
|
||||
/// @brief Copy @p fileName from host into target system at @p rootMountPoint
|
||||
Calamares::JobResult copyFile( const QString& rootMountPoint, const QString& fileName );
|
||||
|
||||
|
@ -1,73 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# === This file is part of Calamares - <https://github.com/calamares> ===
|
||||
#
|
||||
# Copyright 2014, Kevin Kofler <kevin.kofler@chello.at>
|
||||
# Copyright 2019, Philip Müller <philm@manjaro.org>
|
||||
# Copyright 2017, Alf Gaida <agaida@siduction.org>
|
||||
# Copyright 2019, Adriaan de Groot <groot@kde.org>
|
||||
#
|
||||
# Calamares is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# Calamares is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Calamares. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import libcalamares
|
||||
import os
|
||||
from libcalamares.utils import check_target_env_call, debug
|
||||
|
||||
import gettext
|
||||
_ = gettext.translation("calamares-python",
|
||||
localedir=libcalamares.utils.gettext_path(),
|
||||
languages=libcalamares.utils.gettext_languages(),
|
||||
fallback=True).gettext
|
||||
|
||||
|
||||
def pretty_name():
|
||||
return _("Generate machine-id.")
|
||||
|
||||
|
||||
def run():
|
||||
"""
|
||||
Generate machine-id using dbus and systemd.
|
||||
|
||||
:return:
|
||||
"""
|
||||
root_mount_point = libcalamares.globalstorage.value("rootMountPoint")
|
||||
|
||||
if root_mount_point is None:
|
||||
libcalamares.utils.warning("rootMountPoint is empty, {!s}".format(root_mount_point))
|
||||
return (_("Configuration Error"),
|
||||
_("No root mount point is given for <pre>{!s}</pre> to use." ).format("machineid"))
|
||||
|
||||
enable_systemd = libcalamares.job.configuration["systemd"]
|
||||
enable_dbus = libcalamares.job.configuration["dbus"]
|
||||
enable_symlink = libcalamares.job.configuration["symlink"]
|
||||
target_systemd_machineid_file = root_mount_point + "/etc/machine-id"
|
||||
target_dbus_machineid_file = root_mount_point + "/var/lib/dbus/machine-id"
|
||||
|
||||
if os.path.exists(target_dbus_machineid_file):
|
||||
os.remove(target_dbus_machineid_file)
|
||||
|
||||
if enable_systemd:
|
||||
if os.path.exists(target_systemd_machineid_file):
|
||||
os.remove(target_systemd_machineid_file)
|
||||
check_target_env_call("systemd-machine-id-setup")
|
||||
|
||||
if enable_dbus:
|
||||
if enable_symlink and os.path.exists(target_systemd_machineid_file):
|
||||
check_target_env_call(["ln", "-sf", "/etc/machine-id",
|
||||
"/var/lib/dbus/machine-id"])
|
||||
else:
|
||||
check_target_env_call(["dbus-uuidgen", "--ensure"])
|
||||
|
||||
return None
|
@ -176,7 +176,7 @@ script:
|
||||
if ( !Calamares::JobQueue::instance() )
|
||||
(void)new Calamares::JobQueue( nullptr );
|
||||
if ( !Calamares::Settings::instance() )
|
||||
(void)new Calamares::Settings( QString(), true );
|
||||
(void)Calamares::Settings::init( QString() );
|
||||
|
||||
Calamares::GlobalStorage* gs = Calamares::JobQueue::instance()->globalStorage();
|
||||
QVERIFY( gs != nullptr );
|
||||
|
@ -23,13 +23,13 @@
|
||||
#include "SummaryViewStep.h"
|
||||
|
||||
#include "Branding.h"
|
||||
#include "ExecutionViewStep.h"
|
||||
#include "Settings.h"
|
||||
#include "ViewManager.h"
|
||||
|
||||
#include "utils/CalamaresUtilsGui.h"
|
||||
#include "utils/Logger.h"
|
||||
#include "utils/Retranslator.h"
|
||||
#include "viewpages/ExecutionViewStep.h"
|
||||
|
||||
#include <QBoxLayout>
|
||||
#include <QLabel>
|
||||
|
@ -40,3 +40,13 @@ calamares_add_plugin( welcome
|
||||
Qt5::Network
|
||||
SHARED_LIB
|
||||
)
|
||||
|
||||
add_executable( welcomeqmltest qmlmain.cpp Config.cpp )
|
||||
target_link_libraries( welcomeqmltest PRIVATE calamaresui Qt5::Core )
|
||||
set_target_properties( welcomeqmltest
|
||||
PROPERTIES
|
||||
ENABLE_EXPORTS TRUE
|
||||
RUNTIME_OUTPUT_NAME welcomeqmltest
|
||||
)
|
||||
calamares_automoc( welcomeqmltest )
|
||||
calamares_autouic( welcomeqmltest )
|
||||
|
28
src/modules/welcome/Config.cpp
Normal file
28
src/modules/welcome/Config.cpp
Normal file
@ -0,0 +1,28 @@
|
||||
/* === This file is part of Calamares - <https://github.com/calamares> ===
|
||||
*
|
||||
* Copyright 2019, Adriaan de Groot <groot@kde.org>
|
||||
*
|
||||
* Calamares is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Calamares is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "Config.h"
|
||||
|
||||
Config::Config()
|
||||
: m_helpUrl( "https://www.kde.org/" )
|
||||
{
|
||||
}
|
||||
|
||||
Config::~Config()
|
||||
{
|
||||
}
|
40
src/modules/welcome/Config.h
Normal file
40
src/modules/welcome/Config.h
Normal file
@ -0,0 +1,40 @@
|
||||
/* === This file is part of Calamares - <https://github.com/calamares> ===
|
||||
*
|
||||
* Copyright 2019, Adriaan de Groot <groot@kde.org>
|
||||
*
|
||||
* Calamares is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Calamares is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef WELCOME_CONFIG_H
|
||||
#define WELCOME_CONFIG_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QUrl>
|
||||
|
||||
class Config : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY( QUrl helpUrl READ helpUrl WRITE setHelpUrl CONSTANT )
|
||||
public:
|
||||
Config();
|
||||
virtual ~Config();
|
||||
|
||||
QUrl helpUrl() const { return m_helpUrl; }
|
||||
void setHelpUrl( const QUrl& url ) { m_helpUrl = url; }
|
||||
|
||||
private:
|
||||
QUrl m_helpUrl;
|
||||
};
|
||||
|
||||
#endif
|
84
src/modules/welcome/qmlmain.cpp
Normal file
84
src/modules/welcome/qmlmain.cpp
Normal file
@ -0,0 +1,84 @@
|
||||
/* Example executable showing a QML page and using the
|
||||
* models from libcalamares for displaying a welcome.
|
||||
*/
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <QApplication>
|
||||
#include <QLabel>
|
||||
#include <QMainWindow>
|
||||
#include <QQmlEngine>
|
||||
#include <QQuickWidget>
|
||||
#include <QString>
|
||||
#include <QTimer>
|
||||
#include <QUrl>
|
||||
#include <QVBoxLayout>
|
||||
#include <QWidget>
|
||||
|
||||
#include <KAboutData>
|
||||
|
||||
#include "Branding.h"
|
||||
#include "JobQueue.h"
|
||||
#include "Settings.h"
|
||||
#include "locale/LabelModel.h"
|
||||
#include "utils/Logger.h"
|
||||
|
||||
#include "Config.h"
|
||||
|
||||
static Config* theConfig()
|
||||
{
|
||||
static Config* cnf = new Config();
|
||||
return cnf;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
QApplication a( argc, argv );
|
||||
|
||||
KAboutData aboutData( "calamares",
|
||||
"Calamares",
|
||||
"0.1",
|
||||
"Calamares QML Test Application",
|
||||
KAboutLicense::GPL_V3,
|
||||
QString(),
|
||||
QString(),
|
||||
"https://calamares.io",
|
||||
"https://github.com/calamares/calamares/issues" );
|
||||
KAboutData::setApplicationData( aboutData );
|
||||
a.setApplicationDisplayName( QString() ); // To avoid putting an extra "Calamares/" into the log-file
|
||||
|
||||
Logger::setupLogLevel( Logger::LOGVERBOSE );
|
||||
|
||||
std::unique_ptr< Calamares::Settings > settings_p( Calamares::Settings::init( QString() ) );
|
||||
std::unique_ptr< Calamares::JobQueue > jobqueue_p( new Calamares::JobQueue( nullptr ) );
|
||||
|
||||
Calamares::Branding defaultBrand( "src/branding/default/branding.desc" );
|
||||
cDebug() << "Branding @" << (void *)Calamares::Branding::instance();
|
||||
|
||||
QMainWindow mw;
|
||||
QWidget background;
|
||||
QVBoxLayout vl;
|
||||
QLabel l( "Hello, world", &mw );
|
||||
QQuickWidget qqw( &mw );
|
||||
vl.addWidget( &qqw );
|
||||
vl.addWidget( &l );
|
||||
background.setLayout( &vl );
|
||||
mw.setCentralWidget( &background );
|
||||
mw.resize( QSize( 400, 400 ) );
|
||||
mw.show();
|
||||
|
||||
Config cnf;
|
||||
if ( argc > 1 )
|
||||
{
|
||||
cnf.setHelpUrl( QUrl( argv[1] ) );
|
||||
}
|
||||
|
||||
// TODO: this should put the one config object in the context, rather than adding a factory function to share it everywhere
|
||||
qmlRegisterSingletonType< Config >( "io.calamares.modules.welcome", 1, 0, "PotatoConfig", [](QQmlEngine*, QJSEngine*) -> QObject* { return theConfig(); });
|
||||
|
||||
qmlRegisterSingletonType< CalamaresUtils::Locale::LabelModel >( "io.calamares.locale", 1, 0, "LocaleModel", [](QQmlEngine*, QJSEngine*) -> QObject* { return CalamaresUtils::Locale::availableTranslations(); } );
|
||||
|
||||
qqw.setSource( QUrl::fromLocalFile("../src/modules/welcome/welcome.qml") );
|
||||
|
||||
return a.exec();
|
||||
}
|
29
src/modules/welcome/welcome.qml
Normal file
29
src/modules/welcome/welcome.qml
Normal file
@ -0,0 +1,29 @@
|
||||
import QtQuick 2.0;
|
||||
import QtQuick.Controls 2.3;
|
||||
import io.calamares.modules.welcome 1.0;
|
||||
import io.calamares.locale 1.0;
|
||||
|
||||
Rectangle {
|
||||
width: 200;
|
||||
height: 200;
|
||||
color: "pink";
|
||||
|
||||
Label {
|
||||
id: label;
|
||||
anchors.centerIn: parent;
|
||||
text: "Welcome to Calamares";
|
||||
}
|
||||
|
||||
Button {
|
||||
id: thebutton;
|
||||
anchors.top: label.bottom;
|
||||
text: PotatoConfig.helpUrl;
|
||||
|
||||
}
|
||||
|
||||
ListView {
|
||||
anchors.fill: parent;
|
||||
model: LocaleModel;
|
||||
delegate: Label { text: display }
|
||||
}
|
||||
}
|
44
src/modules/welcomeq/CMakeLists.txt
Normal file
44
src/modules/welcomeq/CMakeLists.txt
Normal file
@ -0,0 +1,44 @@
|
||||
# This is a re-write of the welcome module using QML view steps
|
||||
# instead of widgets.
|
||||
|
||||
set( _welcome ${CMAKE_CURRENT_SOURCE_DIR}/../welcome )
|
||||
|
||||
include_directories( ${PROJECT_BINARY_DIR}/src/libcalamaresui ${_welcome} )
|
||||
|
||||
# DUPLICATED WITH WELCOME MODULE
|
||||
find_package( Qt5 ${QT_VERSION} CONFIG REQUIRED DBus Network )
|
||||
|
||||
find_package( LIBPARTED )
|
||||
if ( LIBPARTED_FOUND )
|
||||
set( PARTMAN_SRC ${_welcome}/checker/partman_devices.c )
|
||||
set( CHECKER_LINK_LIBRARIES ${LIBPARTED_LIBRARY} )
|
||||
else()
|
||||
set( PARTMAN_SRC )
|
||||
set( CHECKER_LINK_LIBRARIES )
|
||||
add_definitions( -DWITHOUT_LIBPARTED )
|
||||
endif()
|
||||
|
||||
set( CHECKER_SOURCES
|
||||
${_welcome}/checker/CheckerContainer.cpp
|
||||
${_welcome}/checker/GeneralRequirements.cpp
|
||||
${_welcome}/checker/ResultWidget.cpp
|
||||
${_welcome}/checker/ResultsListWidget.cpp
|
||||
${PARTMAN_SRC}
|
||||
)
|
||||
|
||||
calamares_add_plugin( welcomeq
|
||||
TYPE viewmodule
|
||||
EXPORT_MACRO PLUGINDLLEXPORT_PRO
|
||||
SOURCES
|
||||
${CHECKER_SOURCES}
|
||||
WelcomeQmlViewStep.cpp
|
||||
Config.cpp
|
||||
RESOURCES
|
||||
welcomeq.qrc
|
||||
LINK_PRIVATE_LIBRARIES
|
||||
calamaresui
|
||||
${CHECKER_LINK_LIBRARIES}
|
||||
Qt5::DBus
|
||||
Qt5::Network
|
||||
SHARED_LIB
|
||||
)
|
28
src/modules/welcomeq/Config.cpp
Normal file
28
src/modules/welcomeq/Config.cpp
Normal file
@ -0,0 +1,28 @@
|
||||
/* === This file is part of Calamares - <https://github.com/calamares> ===
|
||||
*
|
||||
* Copyright 2019-2020, Adriaan de Groot <groot@kde.org>
|
||||
*
|
||||
* Calamares is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Calamares is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "Config.h"
|
||||
|
||||
Config::Config()
|
||||
: m_helpUrl( "https://www.kde.org/" )
|
||||
{
|
||||
}
|
||||
|
||||
Config::~Config()
|
||||
{
|
||||
}
|
40
src/modules/welcomeq/Config.h
Normal file
40
src/modules/welcomeq/Config.h
Normal file
@ -0,0 +1,40 @@
|
||||
/* === This file is part of Calamares - <https://github.com/calamares> ===
|
||||
*
|
||||
* Copyright 2019-2020, Adriaan de Groot <groot@kde.org>
|
||||
*
|
||||
* Calamares is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Calamares is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef WELCOME_CONFIG_H
|
||||
#define WELCOME_CONFIG_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QUrl>
|
||||
|
||||
class Config : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY( QUrl helpUrl READ helpUrl WRITE setHelpUrl CONSTANT )
|
||||
public:
|
||||
Config();
|
||||
virtual ~Config();
|
||||
|
||||
QUrl helpUrl() const { return m_helpUrl; }
|
||||
void setHelpUrl( const QUrl& url ) { m_helpUrl = url; }
|
||||
|
||||
private:
|
||||
QUrl m_helpUrl;
|
||||
};
|
||||
|
||||
#endif
|
243
src/modules/welcomeq/WelcomeQmlViewStep.cpp
Normal file
243
src/modules/welcomeq/WelcomeQmlViewStep.cpp
Normal file
@ -0,0 +1,243 @@
|
||||
/* === This file is part of Calamares - <https://github.com/calamares> ===
|
||||
*
|
||||
* Copyright 2014-2015, Teo Mrnjavac <teo@kde.org>
|
||||
* Copyright 2018,2020 Adriaan de Groot <groot@kde.org>
|
||||
*
|
||||
* Calamares is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Calamares is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "WelcomeQmlViewStep.h"
|
||||
|
||||
#include "checker/GeneralRequirements.h"
|
||||
|
||||
#include "geoip/Handler.h"
|
||||
#include "locale/LabelModel.h"
|
||||
#include "locale/Lookup.h"
|
||||
#include "utils/Logger.h"
|
||||
#include "utils/Variant.h"
|
||||
|
||||
#include "Branding.h"
|
||||
#include "modulesystem/ModuleManager.h"
|
||||
|
||||
#include <QFutureWatcher>
|
||||
#include <QPixmap>
|
||||
#include <QVariant>
|
||||
|
||||
CALAMARES_PLUGIN_FACTORY_DEFINITION( WelcomeQmlViewStepFactory, registerPlugin< WelcomeQmlViewStep >(); )
|
||||
|
||||
WelcomeQmlViewStep::WelcomeQmlViewStep( QObject* parent )
|
||||
: Calamares::ViewStep( parent )
|
||||
, m_requirementsChecker( new GeneralRequirements( this ) )
|
||||
{
|
||||
connect( Calamares::ModuleManager::instance(),
|
||||
&Calamares::ModuleManager::requirementsComplete,
|
||||
this,
|
||||
&WelcomeQmlViewStep::nextStatusChanged );
|
||||
}
|
||||
|
||||
|
||||
WelcomeQmlViewStep::~WelcomeQmlViewStep()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
QString
|
||||
WelcomeQmlViewStep::prettyName() const
|
||||
{
|
||||
return tr( "Welcome" );
|
||||
}
|
||||
|
||||
|
||||
QWidget*
|
||||
WelcomeQmlViewStep::widget()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
WelcomeQmlViewStep::isNextEnabled() const
|
||||
{
|
||||
// TODO: should return true
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
WelcomeQmlViewStep::isBackEnabled() const
|
||||
{
|
||||
// TODO: should return true (it's weird that you are not allowed to have welcome *after* anything
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
WelcomeQmlViewStep::isAtBeginning() const
|
||||
{
|
||||
// TODO: adjust to "pages" in the QML
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
WelcomeQmlViewStep::isAtEnd() const
|
||||
{
|
||||
// TODO: adjust to "pages" in the QML
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Calamares::JobList
|
||||
WelcomeQmlViewStep::jobs() const
|
||||
{
|
||||
return Calamares::JobList();
|
||||
}
|
||||
|
||||
|
||||
/** @brief Look up a URL for a button
|
||||
*
|
||||
* Looks up @p key in @p map; if it is a *boolean* value, then
|
||||
* assume an old-style configuration, and fetch the string from
|
||||
* the branding settings @p e. If it is a string, not a boolean,
|
||||
* use it as-is. If not found, or a weird type, returns empty.
|
||||
*
|
||||
* This allows switching the showKnownIssuesUrl and similar settings
|
||||
* in welcome.conf from a boolean (deferring to branding) to an
|
||||
* actual string for immediate use. Empty strings, as well as
|
||||
* "false" as a setting, will hide the buttons as before.
|
||||
*/
|
||||
static QString
|
||||
jobOrBrandingSetting( Calamares::Branding::StringEntry e, const QVariantMap& map, const QString& key )
|
||||
{
|
||||
if ( !map.contains( key ) )
|
||||
{
|
||||
return QString();
|
||||
}
|
||||
auto v = map.value( key );
|
||||
if ( v.type() == QVariant::Bool )
|
||||
{
|
||||
return v.toBool() ? ( *e ) : QString();
|
||||
}
|
||||
if ( v.type() == QVariant::String )
|
||||
{
|
||||
return v.toString();
|
||||
}
|
||||
|
||||
return QString();
|
||||
}
|
||||
|
||||
void
|
||||
WelcomeQmlViewStep::setConfigurationMap( const QVariantMap& configurationMap )
|
||||
{
|
||||
using Calamares::Branding;
|
||||
|
||||
m_config.setHelpUrl( jobOrBrandingSetting( Branding::SupportUrl, configurationMap, "showSupportUrl" ) );
|
||||
// TODO: expand Config class and set the remaining fields
|
||||
|
||||
// TODO: figure out how the requirements (held by ModuleManager) should be accessible
|
||||
// to QML as a odel.
|
||||
if ( configurationMap.contains( "requirements" )
|
||||
&& configurationMap.value( "requirements" ).type() == QVariant::Map )
|
||||
{
|
||||
m_requirementsChecker->setConfigurationMap( configurationMap.value( "requirements" ).toMap() );
|
||||
}
|
||||
else
|
||||
cWarning() << "no valid requirements map found in welcome "
|
||||
"module configuration.";
|
||||
|
||||
bool ok = false;
|
||||
QVariantMap geoip = CalamaresUtils::getSubMap( configurationMap, "geoip", ok );
|
||||
if ( ok )
|
||||
{
|
||||
using FWString = QFutureWatcher< QString >;
|
||||
|
||||
auto* handler = new CalamaresUtils::GeoIP::Handler( CalamaresUtils::getString( geoip, "style" ),
|
||||
CalamaresUtils::getString( geoip, "url" ),
|
||||
CalamaresUtils::getString( geoip, "selector" ) );
|
||||
if ( handler->type() != CalamaresUtils::GeoIP::Handler::Type::None )
|
||||
{
|
||||
auto* future = new FWString();
|
||||
connect( future, &FWString::finished, [view = this, f = future, h = handler]() {
|
||||
QString countryResult = f->future().result();
|
||||
cDebug() << "GeoIP result for welcome=" << countryResult;
|
||||
view->setCountry( countryResult, h );
|
||||
f->deleteLater();
|
||||
delete h;
|
||||
} );
|
||||
future->setFuture( handler->queryRaw() );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Would not produce useful country code anyway.
|
||||
delete handler;
|
||||
}
|
||||
}
|
||||
|
||||
QString language = CalamaresUtils::getString( configurationMap, "languageIcon" );
|
||||
if ( !language.isEmpty() )
|
||||
{
|
||||
auto icon = Calamares::Branding::instance()->image( language, QSize( 48, 48 ) );
|
||||
if ( !icon.isNull() )
|
||||
{
|
||||
// TODO: figure out where to set this: Config?
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Calamares::RequirementsList
|
||||
WelcomeQmlViewStep::checkRequirements()
|
||||
{
|
||||
return m_requirementsChecker->checkRequirements();
|
||||
}
|
||||
|
||||
static inline void
|
||||
logGeoIPHandler( CalamaresUtils::GeoIP::Handler* handler )
|
||||
{
|
||||
if ( handler )
|
||||
{
|
||||
cDebug() << Logger::SubEntry << "Obtained from" << handler->url() << " ("
|
||||
<< static_cast< int >( handler->type() ) << handler->selector() << ')';
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WelcomeQmlViewStep::setCountry( const QString& countryCode, CalamaresUtils::GeoIP::Handler* handler )
|
||||
{
|
||||
if ( countryCode.length() != 2 )
|
||||
{
|
||||
cDebug() << "Unusable country code" << countryCode;
|
||||
logGeoIPHandler( handler );
|
||||
return;
|
||||
}
|
||||
|
||||
auto c_l = CalamaresUtils::Locale::countryData( countryCode );
|
||||
if ( c_l.first == QLocale::Country::AnyCountry )
|
||||
{
|
||||
cDebug() << "Unusable country code" << countryCode;
|
||||
logGeoIPHandler( handler );
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
int r = CalamaresUtils::Locale::availableTranslations()->find( countryCode );
|
||||
if ( r < 0 )
|
||||
{
|
||||
cDebug() << "Unusable country code" << countryCode << "(no suitable translation)";
|
||||
}
|
||||
if ( ( r >= 0 ) )
|
||||
{
|
||||
// TODO: update Config to point to selected language
|
||||
}
|
||||
}
|
||||
}
|
95
src/modules/welcomeq/WelcomeQmlViewStep.h
Normal file
95
src/modules/welcomeq/WelcomeQmlViewStep.h
Normal file
@ -0,0 +1,95 @@
|
||||
/* === This file is part of Calamares - <https://github.com/calamares> ===
|
||||
*
|
||||
* Copyright 2019-2020 Adriaan de Groot <groot@kde.org>
|
||||
*
|
||||
* Calamares is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Calamares is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef WELCOME_QMLVIEWSTEP_H
|
||||
#define WELCOME_QMLVIEWSTEP_H
|
||||
|
||||
#include "Config.h"
|
||||
|
||||
#include "modulesystem/Requirement.h"
|
||||
#include "utils/PluginFactory.h"
|
||||
#include "viewpages/ViewStep.h"
|
||||
|
||||
#include <PluginDllMacro.h>
|
||||
|
||||
#include <QObject>
|
||||
#include <QVariantMap>
|
||||
|
||||
namespace CalamaresUtils
|
||||
{
|
||||
namespace GeoIP
|
||||
{
|
||||
class Handler;
|
||||
}
|
||||
} // namespace CalamaresUtils
|
||||
|
||||
class GeneralRequirements;
|
||||
|
||||
class QQmlComponent;
|
||||
class QQuickItem;
|
||||
class QQuickWidget;
|
||||
|
||||
// TODO: Needs a generic Calamares::QmlViewStep as base class
|
||||
// TODO: refactor and move what makes sense to base class
|
||||
class PLUGINDLLEXPORT WelcomeQmlViewStep : public Calamares::ViewStep
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit WelcomeQmlViewStep( QObject* parent = nullptr );
|
||||
virtual ~WelcomeQmlViewStep() override;
|
||||
|
||||
QString prettyName() const override;
|
||||
|
||||
QWidget* widget() override;
|
||||
|
||||
bool isNextEnabled() const override;
|
||||
bool isBackEnabled() const override;
|
||||
|
||||
bool isAtBeginning() const override;
|
||||
bool isAtEnd() const override;
|
||||
|
||||
Calamares::JobList jobs() const override;
|
||||
|
||||
void setConfigurationMap( const QVariantMap& configurationMap ) override;
|
||||
|
||||
/** @brief Sets the country that Calamares is running in.
|
||||
*
|
||||
* This (ideally) sets up language and locale settings that are right for
|
||||
* the given 2-letter country code. Uses the handler's information (if
|
||||
* given) for error reporting.
|
||||
*/
|
||||
void setCountry( const QString&, CalamaresUtils::GeoIP::Handler* handler );
|
||||
|
||||
Calamares::RequirementsList checkRequirements() override;
|
||||
|
||||
private:
|
||||
// TODO: a generic QML viewstep should return a config object from a method
|
||||
Config m_config;
|
||||
GeneralRequirements* m_requirementsChecker;
|
||||
|
||||
// TODO: these need to be in the base class (also a base class of ExecutionViewStep)
|
||||
QQuickWidget* m_qmlWidget;
|
||||
QQmlComponent* m_qmlComponent;
|
||||
QQuickItem* m_qmlItem;
|
||||
|
||||
};
|
||||
|
||||
CALAMARES_PLUGIN_FACTORY_DECLARATION( WelcomeQmlViewStepFactory )
|
||||
|
||||
#endif // WELCOME_QMLVIEWSTEP_H
|
Loading…
Reference in New Issue
Block a user