Merge branch 'master' of https://github.com/calamares/calamares into development
This commit is contained in:
commit
49c17942d0
@ -32,6 +32,9 @@
|
||||
#include "utils/CalamaresUtilsSystem.h"
|
||||
#include "utils/Dirs.h"
|
||||
#include "utils/Logger.h"
|
||||
#ifdef WITH_QML
|
||||
#include "utils/Qml.h"
|
||||
#endif
|
||||
#include "utils/Retranslator.h"
|
||||
#include "viewpages/ViewStep.h"
|
||||
|
||||
@ -117,34 +120,6 @@ CalamaresApplication::mainWindow()
|
||||
}
|
||||
|
||||
|
||||
static QStringList
|
||||
qmlDirCandidates( bool assumeBuilddir )
|
||||
{
|
||||
static const char QML[] = "qml";
|
||||
|
||||
QStringList qmlDirs;
|
||||
if ( CalamaresUtils::isAppDataDirOverridden() )
|
||||
{
|
||||
qmlDirs << CalamaresUtils::appDataDir().absoluteFilePath( QML );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( assumeBuilddir )
|
||||
{
|
||||
qmlDirs << QDir::current().absoluteFilePath( "src/qml" ); // In build-dir
|
||||
}
|
||||
if ( CalamaresUtils::haveExtraDirs() )
|
||||
for ( auto s : CalamaresUtils::extraDataDirs() )
|
||||
{
|
||||
qmlDirs << ( s + QML );
|
||||
}
|
||||
qmlDirs << CalamaresUtils::appDataDir().absoluteFilePath( QML );
|
||||
}
|
||||
|
||||
return qmlDirs;
|
||||
}
|
||||
|
||||
|
||||
static QStringList
|
||||
brandingFileCandidates( bool assumeBuilddir, const QString& brandingFilename )
|
||||
{
|
||||
@ -175,38 +150,12 @@ brandingFileCandidates( bool assumeBuilddir, const QString& brandingFilename )
|
||||
void
|
||||
CalamaresApplication::initQmlPath()
|
||||
{
|
||||
QDir importPath; // Right now, current-dir
|
||||
QStringList qmlDirCandidatesByPriority = qmlDirCandidates( isDebug() );
|
||||
bool found = false;
|
||||
|
||||
foreach ( const QString& path, qmlDirCandidatesByPriority )
|
||||
#ifdef WITH_QML
|
||||
if ( !CalamaresUtils::initQmlModulesDir() )
|
||||
{
|
||||
QDir dir( path );
|
||||
if ( dir.exists() && dir.isReadable() )
|
||||
{
|
||||
importPath = dir;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !found || !importPath.exists() || !importPath.isReadable() )
|
||||
{
|
||||
cError() << "Cowardly refusing to continue startup without a QML directory."
|
||||
<< Logger::DebugList( qmlDirCandidatesByPriority );
|
||||
if ( CalamaresUtils::isAppDataDirOverridden() )
|
||||
{
|
||||
cError() << "FATAL: explicitly configured application data directory is missing qml/";
|
||||
}
|
||||
else
|
||||
{
|
||||
cError() << "FATAL: none of the expected QML paths exist.";
|
||||
}
|
||||
::exit( EXIT_FAILURE );
|
||||
}
|
||||
|
||||
cDebug() << "Using Calamares QML directory" << importPath.absolutePath();
|
||||
CalamaresUtils::setQmlModulesDir( importPath );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -208,7 +208,7 @@ CalamaresWindow::getWidgetNavigation( QWidget* parent )
|
||||
QWidget*
|
||||
CalamaresWindow::getQmlSidebar( QWidget* parent, int )
|
||||
{
|
||||
CalamaresUtils::registerCalamaresModels();
|
||||
CalamaresUtils::registerQmlModels();
|
||||
QQuickWidget* w = new QQuickWidget( parent );
|
||||
w->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding );
|
||||
w->setResizeMode( QQuickWidget::SizeRootObjectToView );
|
||||
@ -220,7 +220,7 @@ CalamaresWindow::getQmlSidebar( QWidget* parent, int )
|
||||
QWidget*
|
||||
CalamaresWindow::getQmlNavigation( QWidget* parent )
|
||||
{
|
||||
CalamaresUtils::registerCalamaresModels();
|
||||
CalamaresUtils::registerQmlModels();
|
||||
QQuickWidget* w = new QQuickWidget( parent );
|
||||
w->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding );
|
||||
w->setResizeMode( QQuickWidget::SizeRootObjectToView );
|
||||
|
@ -22,18 +22,22 @@
|
||||
* bindings.
|
||||
*/
|
||||
|
||||
#include "modulesystem/Module.h"
|
||||
#include "utils/Logger.h"
|
||||
#include "utils/Yaml.h"
|
||||
|
||||
#include "Branding.h"
|
||||
#include "CppJob.h"
|
||||
#include "GlobalStorage.h"
|
||||
#include "Job.h"
|
||||
#include "JobQueue.h"
|
||||
#include "Settings.h"
|
||||
#include "ViewManager.h"
|
||||
|
||||
#include "modulesystem/Module.h"
|
||||
#include "modulesystem/ModuleManager.h"
|
||||
#include "modulesystem/ViewModule.h"
|
||||
#include "utils/Logger.h"
|
||||
#ifdef WITH_QML
|
||||
#include "utils/Qml.h"
|
||||
#endif
|
||||
#include "utils/Yaml.h"
|
||||
#include "viewpages/ExecutionViewStep.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QCommandLineOption>
|
||||
@ -42,6 +46,7 @@
|
||||
#include <QFileInfo>
|
||||
#include <QLabel>
|
||||
#include <QMainWindow>
|
||||
#include <QThread>
|
||||
|
||||
#include <memory>
|
||||
|
||||
@ -80,6 +85,8 @@ handle_args( QCoreApplication& a )
|
||||
"src/branding/default/branding.desc" );
|
||||
QCommandLineOption uiOption( QStringList() << QStringLiteral( "U" ) << QStringLiteral( "ui" ),
|
||||
QStringLiteral( "Enable UI" ) );
|
||||
QCommandLineOption slideshowOption( QStringList() << QStringLiteral( "s" ) << QStringLiteral( "slideshow" ),
|
||||
QStringLiteral( "Run slideshow module" ) );
|
||||
|
||||
QCommandLineParser parser;
|
||||
parser.setApplicationDescription( "Calamares module tester" );
|
||||
@ -92,13 +99,14 @@ handle_args( QCoreApplication& a )
|
||||
parser.addOption( langOption );
|
||||
parser.addOption( brandOption );
|
||||
parser.addOption( uiOption );
|
||||
parser.addOption( slideshowOption );
|
||||
parser.addPositionalArgument( "module", "Path or name of module to run." );
|
||||
parser.addPositionalArgument( "job.yaml", "Path of job settings document to use.", "[job.yaml]" );
|
||||
|
||||
parser.process( a );
|
||||
|
||||
const QStringList args = parser.positionalArguments();
|
||||
if ( args.isEmpty() )
|
||||
if ( args.isEmpty() && !parser.isSet( slideshowOption ) )
|
||||
{
|
||||
cError() << "Missing <module> path.\n";
|
||||
parser.showHelp();
|
||||
@ -116,20 +124,161 @@ handle_args( QCoreApplication& a )
|
||||
jobSettings = args.at( 1 );
|
||||
}
|
||||
|
||||
return ModuleConfig { args.first(),
|
||||
return ModuleConfig { parser.isSet( slideshowOption ) ? QStringLiteral( "-" ) : args.first(),
|
||||
jobSettings,
|
||||
parser.value( globalOption ),
|
||||
parser.value( langOption ),
|
||||
parser.value( brandOption ),
|
||||
parser.isSet( uiOption ) };
|
||||
parser.isSet( slideshowOption ) || parser.isSet( uiOption ) };
|
||||
}
|
||||
}
|
||||
|
||||
/** @brief Bogus Job for --slideshow option
|
||||
*
|
||||
* Generally one would use DummyCppJob for this kind of dummy
|
||||
* job, but that class lives in a module so isn't available
|
||||
* in this test application.
|
||||
*
|
||||
* This bogus job just sleeps for 3.
|
||||
*/
|
||||
class ExecViewJob : public Calamares::CppJob
|
||||
{
|
||||
public:
|
||||
explicit ExecViewJob( const QString& name, unsigned long t = 3 )
|
||||
: m_name( name )
|
||||
, m_delay( t )
|
||||
{
|
||||
}
|
||||
virtual ~ExecViewJob() override;
|
||||
|
||||
QString prettyName() const override { return m_name; }
|
||||
|
||||
Calamares::JobResult exec() override
|
||||
{
|
||||
QThread::sleep( m_delay );
|
||||
return Calamares::JobResult::ok();
|
||||
}
|
||||
|
||||
void setConfigurationMap( const QVariantMap& ) override {}
|
||||
|
||||
private:
|
||||
QString m_name;
|
||||
unsigned long m_delay;
|
||||
};
|
||||
|
||||
ExecViewJob::~ExecViewJob() {}
|
||||
|
||||
/** @brief Bogus module for --slideshow option
|
||||
*
|
||||
* Normally the slideshow -- displayed by ExecutionViewStep -- is not
|
||||
* associated with any particular module in the Calamares configuration.
|
||||
* It is added internally by the module manager. For the module-loader
|
||||
* testing application, we need something that pretends to be the
|
||||
* module for the ExecutionViewStep.
|
||||
*/
|
||||
class ExecViewModule : public Calamares::Module
|
||||
{
|
||||
public:
|
||||
ExecViewModule();
|
||||
~ExecViewModule() override;
|
||||
|
||||
void loadSelf() override;
|
||||
|
||||
virtual Type type() const override;
|
||||
virtual Interface interface() const override;
|
||||
|
||||
virtual Calamares::JobList jobs() const override;
|
||||
|
||||
protected:
|
||||
void initFrom( const QVariantMap& ) override;
|
||||
};
|
||||
|
||||
ExecViewModule::ExecViewModule()
|
||||
: Calamares::Module()
|
||||
{
|
||||
// Normally the module-loader gives the module an instance key
|
||||
// (out of the settings file, or the descriptor of the module).
|
||||
// We don't have one, so build one -- this gives us "x@x".
|
||||
QVariantMap m;
|
||||
m.insert( "name", "x" );
|
||||
Calamares::Module::initFrom( m, "x" );
|
||||
}
|
||||
|
||||
ExecViewModule::~ExecViewModule() {}
|
||||
|
||||
void
|
||||
ExecViewModule::initFrom( const QVariantMap& )
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
ExecViewModule::loadSelf()
|
||||
{
|
||||
auto* viewStep = new Calamares::ExecutionViewStep();
|
||||
viewStep->setModuleInstanceKey( instanceKey() );
|
||||
viewStep->setConfigurationMap( m_configurationMap );
|
||||
viewStep->appendJobModuleInstanceKey( instanceKey().toString() );
|
||||
Calamares::ViewManager::instance()->addViewStep( viewStep );
|
||||
m_loaded = true;
|
||||
}
|
||||
|
||||
Calamares::Module::Type
|
||||
ExecViewModule::type() const
|
||||
{
|
||||
return Module::Type::View;
|
||||
}
|
||||
|
||||
|
||||
Calamares::Module::Interface
|
||||
ExecViewModule::interface() const
|
||||
{
|
||||
return Module::Interface::QtPlugin;
|
||||
}
|
||||
|
||||
Calamares::JobList
|
||||
ExecViewModule::jobs() const
|
||||
{
|
||||
Calamares::JobList l;
|
||||
const auto* gs = Calamares::JobQueue::instance()->globalStorage();
|
||||
if ( gs && gs->contains( "jobs" ) )
|
||||
{
|
||||
QVariantList joblist = gs->value( "jobs" ).toList();
|
||||
for ( const auto& jd : joblist )
|
||||
{
|
||||
QVariantMap jobdescription = jd.toMap();
|
||||
if ( jobdescription.contains( "name" ) && jobdescription.contains( "delay" ) )
|
||||
{
|
||||
l.append( Calamares::job_ptr( new ExecViewJob( jobdescription.value( "name" ).toString(),
|
||||
jobdescription.value( "delay" ).toULongLong() ) ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( l.count() > 0 )
|
||||
{
|
||||
return l;
|
||||
}
|
||||
|
||||
l.append( Calamares::job_ptr( new ExecViewJob( QStringLiteral( "step 1" ) ) ) );
|
||||
l.append( Calamares::job_ptr( new ExecViewJob( QStringLiteral( "step two" ) ) ) );
|
||||
l.append( Calamares::job_ptr( new ExecViewJob( QStringLiteral( "locking mutexes" ), 20 ) ) );
|
||||
l.append( Calamares::job_ptr( new ExecViewJob( QStringLiteral( "unlocking mutexes" ), 1 ) ) );
|
||||
for ( const QString& s : QStringList { "Harder", "Better", "Faster", "Stronger" } )
|
||||
{
|
||||
l.append( Calamares::job_ptr( new ExecViewJob( s, 0 ) ) );
|
||||
}
|
||||
l.append( Calamares::job_ptr( new ExecViewJob( QStringLiteral( "cleaning up" ), 20 ) ) );
|
||||
return l;
|
||||
}
|
||||
|
||||
static Calamares::Module*
|
||||
load_module( const ModuleConfig& moduleConfig )
|
||||
{
|
||||
QString moduleName = moduleConfig.moduleName();
|
||||
if ( moduleName == "-" )
|
||||
{
|
||||
return new ExecViewModule;
|
||||
}
|
||||
|
||||
QFileInfo fi;
|
||||
|
||||
bool ok = false;
|
||||
@ -188,6 +337,18 @@ load_module( const ModuleConfig& moduleConfig )
|
||||
return module;
|
||||
}
|
||||
|
||||
static bool
|
||||
is_ui_option( const char* s )
|
||||
{
|
||||
return !qstrcmp( s, "--ui" ) || !qstrcmp( s, "-U" );
|
||||
}
|
||||
|
||||
static bool
|
||||
is_slideshow_option( const char* s )
|
||||
{
|
||||
return !qstrcmp( s, "--slideshow" ) || !qstrcmp( s, "-s" );
|
||||
}
|
||||
|
||||
/** @brief Create the right kind of QApplication
|
||||
*
|
||||
* Does primitive parsing of argv[] to find the --ui option and returns
|
||||
@ -202,7 +363,7 @@ createApplication( int& argc, char* argv[] )
|
||||
{
|
||||
for ( int i = 1; i < argc; ++i )
|
||||
{
|
||||
if ( !qstrcmp( argv[ i ], "--ui" ) || !qstrcmp( argv[ i ], "-U" ) )
|
||||
if ( is_slideshow_option( argv[ i ] ) || is_ui_option( argv[ i ] ) )
|
||||
{
|
||||
auto* aw = new QApplication( argc, argv );
|
||||
aw->setQuitOnLastWindowClosed( true );
|
||||
@ -241,6 +402,10 @@ main( int argc, char* argv[] )
|
||||
gs->insert( "localeConf", vm );
|
||||
}
|
||||
|
||||
#ifdef WITH_QML
|
||||
CalamaresUtils::initQmlModulesDir(); // don't care if failed
|
||||
#endif
|
||||
|
||||
cDebug() << "Calamares module-loader testing" << module.moduleName();
|
||||
Calamares::Module* m = load_module( module );
|
||||
if ( !m )
|
||||
@ -252,7 +417,11 @@ main( int argc, char* argv[] )
|
||||
cDebug() << " .. got" << m->name() << m->typeString() << m->interfaceString();
|
||||
if ( m->type() == Calamares::Module::Type::View )
|
||||
{
|
||||
if ( !qobject_cast< QApplication* >(aw) )
|
||||
// If we forgot the --ui, any ViewModule will core dump as it
|
||||
// tries to create the widget **which won't be used anyway**.
|
||||
//
|
||||
// To avoid that crash, re-create the QApplication, now with GUI
|
||||
if ( !qobject_cast< QApplication* >( aw ) )
|
||||
{
|
||||
auto* replace_app = new QApplication( argc, argv );
|
||||
replace_app->setQuitOnLastWindowClosed( true );
|
||||
@ -261,8 +430,9 @@ main( int argc, char* argv[] )
|
||||
mw = module.m_ui ? new QMainWindow() : nullptr;
|
||||
|
||||
(void)new Calamares::Branding( module.m_branding );
|
||||
(void)new Calamares::ModuleManager( QStringList(), nullptr );
|
||||
auto* modulemanager = new Calamares::ModuleManager( QStringList(), nullptr );
|
||||
(void)Calamares::ViewManager::instance( mw );
|
||||
modulemanager->addModule( m );
|
||||
}
|
||||
|
||||
if ( !m->isLoaded() )
|
||||
|
@ -42,7 +42,6 @@ namespace CalamaresUtils
|
||||
{
|
||||
|
||||
static QDir s_appDataDir( CMAKE_INSTALL_FULL_DATADIR );
|
||||
static QDir s_qmlModulesDir( QString( CMAKE_INSTALL_FULL_DATADIR ) + "/qml" );
|
||||
static bool s_isAppDataDirOverridden = false;
|
||||
|
||||
static bool s_haveExtraDirs = false;
|
||||
@ -79,13 +78,6 @@ isWritableDir( const QDir& dir )
|
||||
}
|
||||
|
||||
|
||||
QDir
|
||||
qmlModulesDir()
|
||||
{
|
||||
return s_qmlModulesDir;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
setAppDataDir( const QDir& dir )
|
||||
{
|
||||
@ -200,11 +192,4 @@ appLogDir()
|
||||
return QDir::temp();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
setQmlModulesDir( const QDir& dir )
|
||||
{
|
||||
s_qmlModulesDir = dir;
|
||||
}
|
||||
|
||||
} // namespace CalamaresUtils
|
||||
|
@ -31,8 +31,6 @@
|
||||
|
||||
namespace CalamaresUtils
|
||||
{
|
||||
DLLEXPORT QDir qmlModulesDir();
|
||||
|
||||
/**
|
||||
* @brief appDataDir returns the directory with common application data.
|
||||
* Defaults to CMAKE_INSTALL_FULL_DATADIR (usually /usr/share/calamares).
|
||||
@ -57,8 +55,6 @@ DLLEXPORT QDir systemLibDir();
|
||||
DLLEXPORT void setAppDataDir( const QDir& dir );
|
||||
DLLEXPORT bool isAppDataDirOverridden();
|
||||
|
||||
DLLEXPORT void setQmlModulesDir( const QDir& dir );
|
||||
|
||||
/** @brief Setup extra config and data dirs from the XDG variables.
|
||||
*/
|
||||
DLLEXPORT void setXdgDirs();
|
||||
|
@ -52,14 +52,14 @@ CppJobModule::loadSelf()
|
||||
CalamaresPluginFactory* pf = qobject_cast< CalamaresPluginFactory* >( m_loader->instance() );
|
||||
if ( !pf )
|
||||
{
|
||||
cDebug() << Q_FUNC_INFO << m_loader->errorString();
|
||||
cDebug() << "Could not load module:" << m_loader->errorString();
|
||||
return;
|
||||
}
|
||||
|
||||
CppJob* cppJob = pf->create< Calamares::CppJob >();
|
||||
if ( !cppJob )
|
||||
{
|
||||
cDebug() << Q_FUNC_INFO << m_loader->errorString();
|
||||
cDebug() << "Could not load module:" << m_loader->errorString();
|
||||
return;
|
||||
}
|
||||
// cDebug() << "CppJobModule loading self for instance" << instanceKey()
|
||||
|
@ -300,22 +300,12 @@ ModuleManager::loadModules()
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( !checkModuleDependencies( *thisModule ) )
|
||||
if ( !addModule( thisModule ) )
|
||||
{
|
||||
// Error message is already printed
|
||||
failedModules.append( instanceKey.toString() );
|
||||
continue;
|
||||
}
|
||||
|
||||
// If it's a ViewModule, it also appends the ViewStep to the ViewManager.
|
||||
thisModule->loadSelf();
|
||||
m_loadedModulesByInstanceKey.insert( instanceKey, thisModule );
|
||||
if ( !thisModule->isLoaded() )
|
||||
{
|
||||
cError() << "Module" << instanceKey.toString() << "loading FAILED.";
|
||||
failedModules.append( instanceKey.toString() );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// At this point we most certainly have a pointer to a loaded module in
|
||||
@ -345,6 +335,40 @@ ModuleManager::loadModules()
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
ModuleManager::addModule( Module *module )
|
||||
{
|
||||
if ( !module )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if ( !module->instanceKey().isValid() )
|
||||
{
|
||||
cWarning() << "Module" << module->location() << '@' << (void*)module << "has invalid instance key.";
|
||||
return false;
|
||||
}
|
||||
if ( !checkModuleDependencies( *module ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( !module->isLoaded() )
|
||||
{
|
||||
module->loadSelf();
|
||||
}
|
||||
|
||||
// Even if the load failed, we keep the module, so that if it tried to
|
||||
// get loaded **again**, we already know.
|
||||
m_loadedModulesByInstanceKey.insert( module->instanceKey(), module );
|
||||
if ( !module->isLoaded() )
|
||||
{
|
||||
cError() << "Module" << module->instanceKey().toString() << "loading FAILED.";
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
ModuleManager::checkRequirements()
|
||||
{
|
||||
@ -414,6 +438,12 @@ ModuleManager::checkDependencies()
|
||||
bool
|
||||
ModuleManager::checkModuleDependencies( const Module& m )
|
||||
{
|
||||
if ( !m_availableDescriptorsByModuleName.contains( m.name() ) )
|
||||
{
|
||||
cWarning() << "Module" << m.name() << "loaded externally, no dependency information.";
|
||||
return true;
|
||||
}
|
||||
|
||||
bool allRequirementsFound = true;
|
||||
QStringList requiredModules
|
||||
= m_availableDescriptorsByModuleName[ m.name() ].value( "requiredModules" ).toStringList();
|
||||
|
@ -85,6 +85,14 @@ public:
|
||||
*/
|
||||
void loadModules();
|
||||
|
||||
/**
|
||||
* @brief Adds a single module (loaded by some other means)
|
||||
*
|
||||
* Returns @c true on success (that is, the module's dependencies
|
||||
* are satisfied, it wasn't already loaded, ...).
|
||||
*/
|
||||
bool addModule( Module* );
|
||||
|
||||
/**
|
||||
* @brief Starts asynchronous requirements checking for each module.
|
||||
* When this is done, the signal requirementsComplete is emitted.
|
||||
|
@ -53,14 +53,14 @@ ViewModule::loadSelf()
|
||||
CalamaresPluginFactory* pf = qobject_cast< CalamaresPluginFactory* >( m_loader->instance() );
|
||||
if ( !pf )
|
||||
{
|
||||
cWarning() << Q_FUNC_INFO << "No factory:" << m_loader->errorString();
|
||||
cWarning() << "No factory:" << m_loader->errorString();
|
||||
return;
|
||||
}
|
||||
|
||||
m_viewStep = pf->create< Calamares::ViewStep >();
|
||||
if ( !m_viewStep )
|
||||
{
|
||||
cWarning() << Q_FUNC_INFO << "create() failed" << m_loader->errorString();
|
||||
cWarning() << "create() failed" << m_loader->errorString();
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -76,7 +76,7 @@ ViewModule::loadSelf()
|
||||
}
|
||||
else
|
||||
{
|
||||
cWarning() << Q_FUNC_INFO << "No view step was created";
|
||||
cWarning() << "No view step was created";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -207,6 +207,10 @@ unmarginLayout( QLayout* layout )
|
||||
int
|
||||
defaultFontSize()
|
||||
{
|
||||
if ( s_defaultFontSize <= 0 )
|
||||
{
|
||||
s_defaultFontSize = QFont().pointSize();
|
||||
}
|
||||
return s_defaultFontSize;
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,9 @@
|
||||
#include "Branding.h"
|
||||
#include "GlobalStorage.h"
|
||||
#include "JobQueue.h"
|
||||
#include "Settings.h"
|
||||
#include "ViewManager.h"
|
||||
#include "utils/Dirs.h"
|
||||
#include "utils/Logger.h"
|
||||
|
||||
#include <QByteArray>
|
||||
@ -30,11 +32,81 @@
|
||||
#include <QString>
|
||||
#include <QVariant>
|
||||
|
||||
static QDir s_qmlModulesDir( QString( CMAKE_INSTALL_FULL_DATADIR ) + "/qml" );
|
||||
|
||||
namespace CalamaresUtils
|
||||
{
|
||||
QDir
|
||||
qmlModulesDir()
|
||||
{
|
||||
return s_qmlModulesDir;
|
||||
}
|
||||
|
||||
void
|
||||
callQMLFunction( QQuickItem* qmlObject, const char* method )
|
||||
setQmlModulesDir( const QDir& dir )
|
||||
{
|
||||
s_qmlModulesDir = dir;
|
||||
}
|
||||
|
||||
static QStringList
|
||||
qmlDirCandidates( bool assumeBuilddir )
|
||||
{
|
||||
static const char QML[] = "qml";
|
||||
|
||||
QStringList qmlDirs;
|
||||
if ( CalamaresUtils::isAppDataDirOverridden() )
|
||||
{
|
||||
qmlDirs << CalamaresUtils::appDataDir().absoluteFilePath( QML );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( assumeBuilddir )
|
||||
{
|
||||
qmlDirs << QDir::current().absoluteFilePath( "src/qml" ); // In build-dir
|
||||
}
|
||||
if ( CalamaresUtils::haveExtraDirs() )
|
||||
for ( auto s : CalamaresUtils::extraDataDirs() )
|
||||
{
|
||||
qmlDirs << ( s + QML );
|
||||
}
|
||||
qmlDirs << CalamaresUtils::appDataDir().absoluteFilePath( QML );
|
||||
}
|
||||
|
||||
return qmlDirs;
|
||||
}
|
||||
|
||||
bool
|
||||
initQmlModulesDir()
|
||||
{
|
||||
QStringList qmlDirCandidatesByPriority
|
||||
= qmlDirCandidates( Calamares::Settings::instance() && Calamares::Settings::instance()->debugMode() );
|
||||
|
||||
for ( const QString& path : qmlDirCandidatesByPriority )
|
||||
{
|
||||
QDir dir( path );
|
||||
if ( dir.exists() && dir.isReadable() )
|
||||
{
|
||||
cDebug() << "Using Calamares QML directory" << dir.absolutePath();
|
||||
CalamaresUtils::setQmlModulesDir( dir );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
cError() << "Cowardly refusing to continue startup without a QML directory."
|
||||
<< Logger::DebugList( qmlDirCandidatesByPriority );
|
||||
if ( CalamaresUtils::isAppDataDirOverridden() )
|
||||
{
|
||||
cError() << "FATAL: explicitly configured application data directory is missing qml/";
|
||||
}
|
||||
else
|
||||
{
|
||||
cError() << "FATAL: none of the expected QML paths exist.";
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
callQmlFunction( QQuickItem* qmlObject, const char* method )
|
||||
{
|
||||
QByteArray methodSignature( method );
|
||||
methodSignature.append( "()" );
|
||||
@ -71,14 +143,14 @@ addExpansions( QmlSearch method, QStringList& candidates, const QStringList& nam
|
||||
std::transform( names.constBegin(),
|
||||
names.constEnd(),
|
||||
std::back_inserter( candidates ),
|
||||
[ & ]( const QString& s ) { return s.isEmpty() ? QString() : bPath.arg( brandDir, s ); } );
|
||||
[&]( const QString& s ) { return s.isEmpty() ? QString() : bPath.arg( brandDir, s ); } );
|
||||
}
|
||||
if ( ( method == QmlSearch::Both ) || ( method == QmlSearch::QrcOnly ) )
|
||||
{
|
||||
std::transform( names.constBegin(),
|
||||
names.constEnd(),
|
||||
std::back_inserter( candidates ),
|
||||
[ & ]( const QString& s ) { return s.isEmpty() ? QString() : qrPath.arg( s ); } );
|
||||
[&]( const QString& s ) { return s.isEmpty() ? QString() : qrPath.arg( s ); } );
|
||||
}
|
||||
}
|
||||
|
||||
@ -149,7 +221,7 @@ qmlSearchNames()
|
||||
}
|
||||
|
||||
void
|
||||
registerCalamaresModels()
|
||||
registerQmlModels()
|
||||
{
|
||||
static bool done = false;
|
||||
if ( !done )
|
||||
|
@ -24,10 +24,25 @@
|
||||
#include "modulesystem/InstanceKey.h"
|
||||
#include "utils/NamedEnum.h"
|
||||
|
||||
#include <QDir>
|
||||
|
||||
class QQuickItem;
|
||||
|
||||
namespace CalamaresUtils
|
||||
{
|
||||
/// @brief the extra directory where Calamares searches for QML files
|
||||
UIDLLEXPORT QDir qmlModulesDir();
|
||||
/// @brief sets specific directory for searching for QML files
|
||||
UIDLLEXPORT void setQmlModulesDir( const QDir& dir );
|
||||
|
||||
/** @brief initialize QML search path with branding directories
|
||||
*
|
||||
* Picks a suitable branding directory (from the build-dir in debug mode,
|
||||
* otherwise based on the branding directory) and adds it to the
|
||||
* QML modules directory; returns @c false if none is found.
|
||||
*/
|
||||
UIDLLEXPORT bool initQmlModulesDir();
|
||||
|
||||
/** @brief Sets up global Calamares models for QML
|
||||
*
|
||||
* This needs to be called at least once to make the global Calamares
|
||||
@ -40,7 +55,7 @@ namespace CalamaresUtils
|
||||
* Additionally, modules based on QmlViewStep have a context
|
||||
* property `config` referring to that module's configuration (if any).
|
||||
*/
|
||||
UIDLLEXPORT void registerCalamaresModels();
|
||||
UIDLLEXPORT void registerQmlModels();
|
||||
|
||||
/** @brief Calls the QML method @p method on @p qmlObject
|
||||
*
|
||||
@ -50,7 +65,7 @@ UIDLLEXPORT void registerCalamaresModels();
|
||||
*
|
||||
* If there is a return value from the QML method, it is logged (but not otherwise used).
|
||||
*/
|
||||
UIDLLEXPORT void callQMLFunction( QQuickItem* qmlObject, const char* method );
|
||||
UIDLLEXPORT void callQmlFunction( QQuickItem* qmlObject, const char* method );
|
||||
|
||||
/** @brief Search modes for loading Qml files.
|
||||
*
|
||||
@ -66,7 +81,7 @@ enum class QmlSearch
|
||||
Both
|
||||
};
|
||||
|
||||
///@brief Names for the search terms (in config files)
|
||||
/// @brief Names for the search terms (in config files)
|
||||
UIDLLEXPORT const NamedEnumTable< QmlSearch >& qmlSearchNames();
|
||||
|
||||
/** @brief Find a suitable QML file, given the search method and name hints
|
||||
|
@ -58,7 +58,7 @@ changeQMLState( QMLAction action, QQuickItem* item )
|
||||
static const char propertyName[] = "activatedInCalamares";
|
||||
|
||||
bool activate = action == QMLAction::Start;
|
||||
CalamaresUtils::callQMLFunction( item, activate ? "onActivate" : "onLeave" );
|
||||
CalamaresUtils::callQmlFunction( item, activate ? "onActivate" : "onLeave" );
|
||||
|
||||
auto property = item->property( propertyName );
|
||||
if ( property.isValid() && ( property.type() == QVariant::Bool ) && ( property.toBool() != activate ) )
|
||||
@ -76,7 +76,7 @@ QmlViewStep::QmlViewStep( QObject* parent )
|
||||
, m_spinner( new WaitingWidget( tr( "Loading ..." ) ) )
|
||||
, m_qmlWidget( new QQuickWidget )
|
||||
{
|
||||
CalamaresUtils::registerCalamaresModels();
|
||||
CalamaresUtils::registerQmlModels();
|
||||
|
||||
QVBoxLayout* layout = new QVBoxLayout( m_widget );
|
||||
layout->addWidget( m_spinner );
|
||||
|
@ -23,7 +23,9 @@
|
||||
#include "Branding.h"
|
||||
#include "utils/Dirs.h"
|
||||
#include "utils/Logger.h"
|
||||
#ifdef WITH_QML
|
||||
#include "utils/Qml.h"
|
||||
#endif
|
||||
#include "utils/Retranslator.h"
|
||||
|
||||
#include <QLabel>
|
||||
@ -50,6 +52,8 @@ SlideshowQML::SlideshowQML( QWidget* parent )
|
||||
, m_qmlComponent( nullptr )
|
||||
, m_qmlObject( nullptr )
|
||||
{
|
||||
CalamaresUtils::registerQmlModels();
|
||||
|
||||
m_qmlShow->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding );
|
||||
m_qmlShow->setResizeMode( QQuickWidget::SizeRootObjectToView );
|
||||
m_qmlShow->engine()->addImportPath( CalamaresUtils::qmlModulesDir().absolutePath() );
|
||||
@ -121,11 +125,30 @@ SlideshowQML::loadQmlV2Complete()
|
||||
if ( isActive() )
|
||||
{
|
||||
// We're alreay visible! Must have been slow QML loading, and we
|
||||
// passed onActivate already.
|
||||
// passed onActivate already. changeSlideShowState() locks
|
||||
// the same mutex: we could set up a workaround to call
|
||||
// changeSlideShowState() later after destruction of l.
|
||||
//
|
||||
l.unlock();
|
||||
changeSlideShowState( Slideshow::Start );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( m_qmlObject )
|
||||
{
|
||||
cWarning() << "QML object already created";
|
||||
}
|
||||
else if ( !m_qmlComponent )
|
||||
{
|
||||
cWarning() << "QML component does not exist";
|
||||
}
|
||||
else if ( m_qmlComponent && !m_qmlComponent->isReady() )
|
||||
{
|
||||
cWarning() << "QML component not ready:" << m_qmlComponent->errors();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -144,7 +167,7 @@ SlideshowQML::changeSlideShowState( Action state )
|
||||
if ( Branding::instance()->slideshowAPI() == 2 )
|
||||
{
|
||||
// The QML was already loaded in the constructor, need to start it
|
||||
CalamaresUtils::callQMLFunction( m_qmlObject, activate ? "onActivate" : "onLeave" );
|
||||
CalamaresUtils::callQmlFunction( m_qmlObject, activate ? "onActivate" : "onLeave" );
|
||||
}
|
||||
else if ( !Calamares::Branding::instance()->slideshowPath().isEmpty() )
|
||||
{
|
||||
|
@ -560,7 +560,7 @@ ChoicePage::doAlongsideSetupSplitter( const QModelIndex& current,
|
||||
Partition* part = modl->partitionForIndex( current );
|
||||
if ( !part )
|
||||
{
|
||||
cDebug() << Q_FUNC_INFO << "Partition not found for index" << current;
|
||||
cDebug() << "Partition not found for index" << current;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -120,10 +120,10 @@ PartitionSplitterWidget::setSplitPartition( const QString& path,
|
||||
qint64 maxSize,
|
||||
qint64 preferredSize )
|
||||
{
|
||||
cDebug() << Q_FUNC_INFO << "path:" << path
|
||||
<< "\nminSize:" << minSize
|
||||
<< "\nmaxSize:" << maxSize
|
||||
<< "\nprfSize:" << preferredSize;
|
||||
cDebug() << "path:" << path
|
||||
<< Logger::Continuation << "minSize:" << minSize
|
||||
<< Logger::Continuation << "maxSize:" << maxSize
|
||||
<< Logger::Continuation << "prfSize:" << preferredSize;
|
||||
|
||||
if ( m_itemToResize && m_itemToResizeNext )
|
||||
{
|
||||
|
@ -96,7 +96,7 @@ class RawFSItem:
|
||||
count = 0
|
||||
|
||||
libcalamares.utils.debug("Copying {} to {}".format(self.source, self.destination))
|
||||
if libcalamares.job.configuration["bogus"]:
|
||||
if libcalamares.job.configuration.get("bogus", False):
|
||||
return
|
||||
|
||||
srcsize, srcblksize = get_device_size(self.source)
|
||||
|
Loading…
Reference in New Issue
Block a user