Merge branch 'requirements-checking'
This commit is contained in:
commit
8cf3c217f7
@ -348,6 +348,7 @@ void
|
||||
CalamaresApplication::initViewSteps()
|
||||
{
|
||||
cDebug() << "STARTUP: loadModules for all modules done";
|
||||
m_moduleManager->checkRequirements();
|
||||
if ( Calamares::Branding::instance()->windowMaximize() )
|
||||
{
|
||||
m_mainwindow->setWindowFlag( Qt::FramelessWindowHint );
|
||||
@ -355,6 +356,7 @@ CalamaresApplication::initViewSteps()
|
||||
}
|
||||
else
|
||||
m_mainwindow->show();
|
||||
|
||||
ProgressTreeModel* m = new ProgressTreeModel( nullptr );
|
||||
ProgressTreeView::instance()->setModel( m );
|
||||
cDebug() << "STARTUP: Window now visible and ProgressTreeView populated";
|
||||
|
@ -5,6 +5,8 @@ set( calamaresui_SOURCES
|
||||
modulesystem/Module.cpp
|
||||
modulesystem/ModuleManager.cpp
|
||||
modulesystem/ProcessJobModule.cpp
|
||||
modulesystem/Requirement.cpp
|
||||
modulesystem/RequirementsChecker.cpp
|
||||
modulesystem/ViewModule.cpp
|
||||
|
||||
utils/CalamaresUtilsGui.cpp
|
||||
|
@ -281,4 +281,10 @@ Module::initFrom( const QVariantMap& moduleDescriptor )
|
||||
m_maybe_emergency = moduleDescriptor[ EMERGENCY ].toBool();
|
||||
}
|
||||
|
||||
RequirementsList
|
||||
Module::checkRequirements()
|
||||
{
|
||||
return RequirementsList();
|
||||
}
|
||||
|
||||
} //ns
|
||||
|
@ -1,6 +1,7 @@
|
||||
/* === This file is part of Calamares - <https://github.com/calamares> ===
|
||||
*
|
||||
* Copyright 2014-2015, Teo Mrnjavac <teo@kde.org>
|
||||
* Copyright 2017, 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
|
||||
@ -19,6 +20,7 @@
|
||||
#ifndef CALAMARES_MODULE_H
|
||||
#define CALAMARES_MODULE_H
|
||||
|
||||
#include "Requirement.h"
|
||||
#include "UiDllMacro.h"
|
||||
|
||||
#include <Typedefs.h>
|
||||
@ -178,6 +180,11 @@ public:
|
||||
*/
|
||||
QVariantMap configurationMap();
|
||||
|
||||
/**
|
||||
* @brief Check the requirements of this module.
|
||||
*/
|
||||
virtual RequirementsList checkRequirements();
|
||||
|
||||
protected:
|
||||
explicit Module();
|
||||
virtual void initFrom( const QVariantMap& moduleDescriptor );
|
||||
|
@ -21,26 +21,23 @@
|
||||
|
||||
#include "ExecutionViewStep.h"
|
||||
#include "Module.h"
|
||||
#include "utils/Logger.h"
|
||||
#include "utils/YamlUtils.h"
|
||||
#include "RequirementsChecker.h"
|
||||
#include "Settings.h"
|
||||
#include "ViewManager.h"
|
||||
|
||||
#include "utils/Logger.h"
|
||||
#include "utils/YamlUtils.h"
|
||||
|
||||
#include <yaml-cpp/yaml.h>
|
||||
|
||||
#include <QApplication>
|
||||
#include <QDir>
|
||||
#include <QTimer>
|
||||
|
||||
#define MODULE_CONFIG_FILENAME "module.desc"
|
||||
|
||||
namespace Calamares
|
||||
{
|
||||
|
||||
|
||||
ModuleManager* ModuleManager::s_instance = nullptr;
|
||||
|
||||
|
||||
ModuleManager*
|
||||
ModuleManager::instance()
|
||||
{
|
||||
@ -94,7 +91,7 @@ ModuleManager::doInit()
|
||||
bool success = currentDir.cd( subdir );
|
||||
if ( success )
|
||||
{
|
||||
QFileInfo descriptorFileInfo( currentDir.absoluteFilePath( MODULE_CONFIG_FILENAME ) );
|
||||
QFileInfo descriptorFileInfo( currentDir.absoluteFilePath( QLatin1Literal( "module.desc") ) );
|
||||
if ( ! ( descriptorFileInfo.exists() && descriptorFileInfo.isReadable() ) )
|
||||
{
|
||||
cDebug() << Q_FUNC_INFO << "unreadable file: "
|
||||
@ -307,6 +304,26 @@ ModuleManager::loadModules()
|
||||
} );
|
||||
}
|
||||
|
||||
void
|
||||
ModuleManager::checkRequirements()
|
||||
{
|
||||
cDebug() << "Checking module requirements ..";
|
||||
|
||||
QVector< Module* > modules( m_loadedModulesByInstanceKey.count() );
|
||||
int count = 0;
|
||||
for (const auto& module : m_loadedModulesByInstanceKey )
|
||||
{
|
||||
modules[count++] = module;
|
||||
}
|
||||
|
||||
RequirementsChecker *rq = new RequirementsChecker( modules, this );
|
||||
connect( rq, &RequirementsChecker::requirementsResult, this, &ModuleManager::requirementsResult );
|
||||
connect( rq, &RequirementsChecker::requirementsComplete, this, &ModuleManager::requirementsComplete );
|
||||
connect( rq, &RequirementsChecker::requirementsProgress, this, &ModuleManager::requirementsProgress );
|
||||
connect( rq, &RequirementsChecker::done, rq, &RequirementsChecker::deleteLater );
|
||||
|
||||
QTimer::singleShot( 0, rq, &RequirementsChecker::run );
|
||||
}
|
||||
|
||||
QStringList
|
||||
ModuleManager::checkDependencies()
|
||||
@ -334,8 +351,6 @@ ModuleManager::checkDependencies()
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( somethingWasRemovedBecauseOfUnmetDependencies )
|
||||
break;
|
||||
}
|
||||
if ( !somethingWasRemovedBecauseOfUnmetDependencies )
|
||||
break;
|
||||
@ -369,4 +384,4 @@ ModuleManager::checkDependencies( const Module& m )
|
||||
return allRequirementsFound;
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace
|
||||
|
@ -20,6 +20,7 @@
|
||||
#ifndef MODULELOADER_H
|
||||
#define MODULELOADER_H
|
||||
|
||||
#include "Requirement.h"
|
||||
#include "Typedefs.h"
|
||||
|
||||
#include <QObject>
|
||||
@ -30,6 +31,7 @@ namespace Calamares
|
||||
{
|
||||
|
||||
class Module;
|
||||
struct RequirementEntry; // from Requirement.h
|
||||
|
||||
/**
|
||||
* @brief The ModuleManager class is a singleton which manages Calamares modules.
|
||||
@ -81,10 +83,20 @@ public:
|
||||
*/
|
||||
void loadModules();
|
||||
|
||||
/**
|
||||
* @brief Starts asynchronous requirements checking for each module.
|
||||
* When this is done, the signal modulesChecked is emitted.
|
||||
*/
|
||||
void checkRequirements();
|
||||
|
||||
signals:
|
||||
void initDone();
|
||||
void modulesLoaded(); /// All of the modules were loaded successfully
|
||||
void modulesFailed( QStringList ); /// .. or not
|
||||
// Below, see RequirementsChecker documentation
|
||||
void requirementsComplete( bool );
|
||||
void requirementsResult( RequirementsList );
|
||||
void requirementsProgress( const QString& );
|
||||
|
||||
private slots:
|
||||
void doInit();
|
||||
|
19
src/libcalamaresui/modulesystem/Requirement.cpp
Normal file
19
src/libcalamaresui/modulesystem/Requirement.cpp
Normal file
@ -0,0 +1,19 @@
|
||||
/* === This file is part of Calamares - <http://github.com/calamares> ===
|
||||
*
|
||||
* Copyright 2017, 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 "Requirement.h"
|
||||
|
64
src/libcalamaresui/modulesystem/Requirement.h
Normal file
64
src/libcalamaresui/modulesystem/Requirement.h
Normal file
@ -0,0 +1,64 @@
|
||||
/* === This file is part of Calamares - <http://github.com/calamares> ===
|
||||
*
|
||||
* Copyright 2017, 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 CALAMARES_REQUIREMENT_H
|
||||
#define CALAMARES_REQUIREMENT_H
|
||||
|
||||
#include <QList>
|
||||
#include <QMetaType>
|
||||
#include <QString>
|
||||
|
||||
#include <functional>
|
||||
|
||||
namespace Calamares
|
||||
{
|
||||
|
||||
/**
|
||||
* An indication of a requirement, which is checked in preparation
|
||||
* for system installation. An entry has a name and some explanation functions
|
||||
* (functions, because they need to respond to translations).
|
||||
*
|
||||
* A requirement can be *satisfied* or not.
|
||||
* A requirement can be optional (i.e. a "good to have") or mandatory.
|
||||
*
|
||||
* Requirements which are not satisfied, and also mandatory, will prevent the
|
||||
* installation from proceeding.
|
||||
*/
|
||||
struct RequirementEntry
|
||||
{
|
||||
using TextFunction = std::function< QString() >;
|
||||
|
||||
/// @brief name of this requirement; not shown to user and used as ID
|
||||
QString name;
|
||||
|
||||
/// @brief Description of this requirement, for use in user-visible lists
|
||||
TextFunction enumerationText;
|
||||
|
||||
/// @brief User-visible string to show that the requirement is not met
|
||||
TextFunction negatedText;
|
||||
|
||||
bool satisfied;
|
||||
bool mandatory;
|
||||
};
|
||||
|
||||
using RequirementsList = QList< RequirementEntry >;
|
||||
|
||||
} // namespace Calamares
|
||||
|
||||
Q_DECLARE_METATYPE(Calamares::RequirementEntry)
|
||||
|
||||
#endif
|
154
src/libcalamaresui/modulesystem/RequirementsChecker.cpp
Normal file
154
src/libcalamaresui/modulesystem/RequirementsChecker.cpp
Normal file
@ -0,0 +1,154 @@
|
||||
/* === This file is part of Calamares - <http://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 "RequirementsChecker.h"
|
||||
|
||||
#include "Module.h"
|
||||
#include "Requirement.h"
|
||||
|
||||
#include "utils/Logger.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <QtConcurrent/QtConcurrent>
|
||||
#include <QFuture>
|
||||
#include <QFutureWatcher>
|
||||
#include <QTimer>
|
||||
|
||||
|
||||
namespace Calamares
|
||||
{
|
||||
|
||||
static void
|
||||
registerMetatypes()
|
||||
{
|
||||
static bool done = false;
|
||||
|
||||
if ( !done )
|
||||
{
|
||||
qRegisterMetaType< RequirementEntry >( "RequirementEntry" );
|
||||
// It's sensitive to the names of types in parameters; in particular
|
||||
// althrough QList<RequirementEntry> is the same as RequirementsList,
|
||||
// because we *name* the type as RequirementsList in the parameters,
|
||||
// we need to register that (as well). Here, be safe and register
|
||||
// both names.
|
||||
qRegisterMetaType< QList< RequirementEntry > >( "QList<RequirementEntry>" );
|
||||
qRegisterMetaType< RequirementsList >( "RequirementsList" );
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
check( Module * const &m, RequirementsChecker *c )
|
||||
{
|
||||
RequirementsList l = m->checkRequirements();
|
||||
if ( l.count() > 0 )
|
||||
c->addCheckedRequirements( l );
|
||||
c->requirementsProgress( QObject::tr( "Requirements checking for module <i>%1</i> is complete." ).arg( m->name() ) );
|
||||
}
|
||||
|
||||
RequirementsChecker::RequirementsChecker( QVector< Module* > modules, QObject* parent )
|
||||
: QObject( parent )
|
||||
, m_modules( std::move( modules ) )
|
||||
, m_progressTimer( nullptr )
|
||||
, m_progressTimeouts( 0 )
|
||||
{
|
||||
m_watchers.reserve( m_modules.count() );
|
||||
m_collectedRequirements.reserve( m_modules.count() );
|
||||
|
||||
registerMetatypes();
|
||||
}
|
||||
|
||||
RequirementsChecker::~RequirementsChecker()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
RequirementsChecker::run()
|
||||
{
|
||||
m_progressTimer = new QTimer( this );
|
||||
connect( m_progressTimer, &QTimer::timeout, this, &RequirementsChecker::reportProgress );
|
||||
m_progressTimer->start( 1200 ); // msec
|
||||
|
||||
for (const auto& module : m_modules )
|
||||
{
|
||||
Watcher *watcher = new Watcher( this );
|
||||
watcher->setFuture( QtConcurrent::run( check, module, this ) );
|
||||
m_watchers.append( watcher );
|
||||
connect( watcher, &Watcher::finished, this, &RequirementsChecker::finished );
|
||||
}
|
||||
|
||||
QTimer::singleShot( 0, this, &RequirementsChecker::finished );
|
||||
}
|
||||
|
||||
void
|
||||
RequirementsChecker::finished()
|
||||
{
|
||||
if ( std::all_of( m_watchers.cbegin(), m_watchers.cend(), []( const Watcher *w ) { return w && w->isFinished(); } ) )
|
||||
{
|
||||
cDebug() << "All requirements have been checked.";
|
||||
|
||||
if ( m_progressTimer )
|
||||
m_progressTimer->stop();
|
||||
|
||||
bool acceptable = true;
|
||||
int count = 0;
|
||||
for ( const auto& r : m_collectedRequirements )
|
||||
{
|
||||
if ( r.mandatory && !r.satisfied )
|
||||
{
|
||||
cDebug() << " .. requirement" << count << r.name << "is not satisfied.";
|
||||
acceptable = false;
|
||||
}
|
||||
++count;
|
||||
}
|
||||
|
||||
emit requirementsComplete( acceptable );
|
||||
QTimer::singleShot(0, this, &RequirementsChecker::done );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RequirementsChecker::addCheckedRequirements( RequirementsList l )
|
||||
{
|
||||
static QMutex addMutex;
|
||||
{
|
||||
QMutexLocker lock( &addMutex );
|
||||
m_collectedRequirements.append( l );
|
||||
}
|
||||
cDebug() << "Added" << l.count() << "requirement results";
|
||||
emit requirementsResult( l );
|
||||
}
|
||||
|
||||
void
|
||||
RequirementsChecker::reportProgress()
|
||||
{
|
||||
m_progressTimeouts++;
|
||||
|
||||
auto remaining = std::count_if( m_watchers.cbegin(), m_watchers.cend(), []( const Watcher *w ) { return w && !w->isFinished(); } );
|
||||
if ( remaining > 0 )
|
||||
{
|
||||
QString waiting = tr( "Waiting for %n module(s).", "", remaining );
|
||||
QString elapsed = tr( "(%n second(s))", "", m_progressTimeouts * m_progressTimer->interval() / 1000 );
|
||||
emit requirementsProgress( waiting + QString( " " ) + elapsed );
|
||||
}
|
||||
else
|
||||
emit requirementsProgress( tr( "System-requirements checking is complete." ) );
|
||||
}
|
||||
|
||||
}
|
87
src/libcalamaresui/modulesystem/RequirementsChecker.h
Normal file
87
src/libcalamaresui/modulesystem/RequirementsChecker.h
Normal file
@ -0,0 +1,87 @@
|
||||
/* === This file is part of Calamares - <http://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 CALAMARES_REQUIREMENTSCHECKER_H
|
||||
#define CALAMARES_REQUIREMENTSCHECKER_H
|
||||
|
||||
#include "Requirement.h"
|
||||
|
||||
#include <QFutureWatcher>
|
||||
#include <QObject>
|
||||
#include <QTimer>
|
||||
#include <QVector>
|
||||
|
||||
|
||||
namespace Calamares
|
||||
{
|
||||
|
||||
class Module;
|
||||
|
||||
/** @brief A manager-class that checks all the module requirements
|
||||
*
|
||||
* Asynchronously checks the requirements for each module, and
|
||||
* emits progress signals as appropriate.
|
||||
*/
|
||||
class RequirementsChecker : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
RequirementsChecker( QVector< Module* > modules, QObject* parent = nullptr );
|
||||
virtual ~RequirementsChecker() override;
|
||||
|
||||
public slots:
|
||||
/// @brief Start checking all the requirements
|
||||
void run();
|
||||
|
||||
/// @brief Called when requirements are reported by a module
|
||||
void addCheckedRequirements( RequirementsList );
|
||||
|
||||
/// @brief Called when all requirements have been checked
|
||||
void finished();
|
||||
|
||||
/// @brief Called periodically while requirements are being checked
|
||||
void reportProgress();
|
||||
|
||||
signals:
|
||||
/// @brief Human-readable progress message
|
||||
void requirementsProgress( const QString& );
|
||||
/// @brief Requirements from a single module
|
||||
void requirementsResult( RequirementsList );
|
||||
/** @brief When all requirements are collected
|
||||
*
|
||||
* The argument indicates if all mandatory requirements are satisfied.
|
||||
*/
|
||||
void requirementsComplete( bool );
|
||||
/// @brief Emitted after requirementsComplete
|
||||
void done();
|
||||
|
||||
private:
|
||||
QVector< Module* > m_modules;
|
||||
|
||||
using Watcher = QFutureWatcher< void >;
|
||||
QVector< Watcher* > m_watchers;
|
||||
|
||||
RequirementsList m_collectedRequirements;
|
||||
|
||||
QTimer *m_progressTimer;
|
||||
unsigned m_progressTimeouts;
|
||||
} ;
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -132,4 +132,10 @@ ViewModule::~ViewModule()
|
||||
delete m_loader;
|
||||
}
|
||||
|
||||
RequirementsList
|
||||
ViewModule::checkRequirements()
|
||||
{
|
||||
return m_viewStep->checkRequirements();
|
||||
}
|
||||
|
||||
} // namespace Calamares
|
||||
|
@ -39,6 +39,8 @@ public:
|
||||
void loadSelf() override;
|
||||
JobList jobs() const override;
|
||||
|
||||
RequirementsList checkRequirements() override;
|
||||
|
||||
protected:
|
||||
void initFrom( const QVariantMap& moduleDescriptor ) override;
|
||||
|
||||
|
@ -74,4 +74,10 @@ ViewStep::setConfigurationMap( const QVariantMap& configurationMap )
|
||||
Q_UNUSED( configurationMap );
|
||||
}
|
||||
|
||||
|
||||
RequirementsList ViewStep::checkRequirements()
|
||||
{
|
||||
return RequirementsList();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -22,6 +22,7 @@
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include "modulesystem/Requirement.h"
|
||||
#include "../UiDllMacro.h"
|
||||
#include "Typedefs.h"
|
||||
|
||||
@ -117,6 +118,12 @@ public:
|
||||
*/
|
||||
virtual void onLeave();
|
||||
|
||||
/**
|
||||
* @brief Jobs needed to run this viewstep
|
||||
*
|
||||
* When a ViewStep is listed in the exec section, its jobs are executed instead.
|
||||
* This function returns that list of jobs; an empty list is ok.
|
||||
*/
|
||||
virtual JobList jobs() const = 0;
|
||||
|
||||
void setModuleInstanceKey( const QString& instanceKey );
|
||||
@ -127,7 +134,17 @@ public:
|
||||
|
||||
virtual void setConfigurationMap( const QVariantMap& configurationMap );
|
||||
|
||||
/**
|
||||
* @brief Can this module proceed, on this machine?
|
||||
*
|
||||
* This is called asynchronously at startup, and returns a list of
|
||||
* the requirements that the module has checked, and their status.
|
||||
* See Calamares::RequirementEntry for details.
|
||||
*/
|
||||
virtual RequirementsList checkRequirements();
|
||||
|
||||
signals:
|
||||
/// @brief Tells the viewmanager to enable the *next* button according to @p status
|
||||
void nextStatusChanged( bool status );
|
||||
|
||||
/* Emitted when the viewstep thinks it needs more space than is currently
|
||||
|
@ -882,11 +882,6 @@ ChoicePage::updateDeviceStatePreview()
|
||||
PartitionModel* model = new PartitionModel( m_beforePartitionBarsView );
|
||||
model->init( deviceBefore, m_core->osproberEntries() );
|
||||
|
||||
// The QObject parents tree is meaningful for memory management here,
|
||||
// see qDeleteAll above.
|
||||
deviceBefore->setParent( model ); // Can't reparent across threads
|
||||
model->setParent( m_beforePartitionBarsView );
|
||||
|
||||
m_beforePartitionBarsView->setModel( model );
|
||||
m_beforePartitionLabelsView->setModel( model );
|
||||
|
||||
|
@ -60,6 +60,8 @@
|
||||
#include <QtConcurrent/QtConcurrent>
|
||||
#include <QFutureWatcher>
|
||||
|
||||
#include <unistd.h> // For sleep(3)
|
||||
|
||||
PartitionViewStep::PartitionViewStep( QObject* parent )
|
||||
: Calamares::ViewStep( parent )
|
||||
, m_core( nullptr )
|
||||
@ -213,8 +215,8 @@ PartitionViewStep::createSummaryWidget() const
|
||||
else // multiple disk previews!
|
||||
{
|
||||
diskInfoLabel->setText( tr( "Disk <strong>%1</strong> (%2)" )
|
||||
.arg( info.deviceNode )
|
||||
.arg( info.deviceName ) );
|
||||
.arg( info.deviceNode )
|
||||
.arg( info.deviceName ) );
|
||||
}
|
||||
formLayout->addRow( diskInfoLabel );
|
||||
|
||||
@ -223,9 +225,9 @@ PartitionViewStep::createSummaryWidget() const
|
||||
QVBoxLayout* field;
|
||||
|
||||
PartitionBarsView::NestedPartitionsMode mode = Calamares::JobQueue::instance()->globalStorage()->
|
||||
value( "drawNestedPartitions" ).toBool() ?
|
||||
PartitionBarsView::DrawNestedPartitions :
|
||||
PartitionBarsView::NoNestedPartitions;
|
||||
value( "drawNestedPartitions" ).toBool() ?
|
||||
PartitionBarsView::DrawNestedPartitions :
|
||||
PartitionBarsView::NoNestedPartitions;
|
||||
preview = new PartitionBarsView;
|
||||
preview->setNestedPartitionsMode( mode );
|
||||
previewLabels = new PartitionLabelsView;
|
||||
@ -263,7 +265,7 @@ PartitionViewStep::createSummaryWidget() const
|
||||
foreach ( const Calamares::job_ptr& job, jobs() )
|
||||
{
|
||||
if ( !job->prettyDescription().isEmpty() )
|
||||
jobsLines.append( job->prettyDescription() );
|
||||
jobsLines.append( job->prettyDescription() );
|
||||
}
|
||||
if ( !jobsLines.isEmpty() )
|
||||
{
|
||||
@ -343,8 +345,8 @@ PartitionViewStep::isAtEnd() const
|
||||
if ( m_choicePage == m_widget->currentWidget() )
|
||||
{
|
||||
if ( m_choicePage->currentChoice() == ChoicePage::Erase ||
|
||||
m_choicePage->currentChoice() == ChoicePage::Replace ||
|
||||
m_choicePage->currentChoice() == ChoicePage::Alongside )
|
||||
m_choicePage->currentChoice() == ChoicePage::Replace ||
|
||||
m_choicePage->currentChoice() == ChoicePage::Alongside )
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
@ -357,7 +359,7 @@ PartitionViewStep::onActivate()
|
||||
{
|
||||
// if we're coming back to PVS from the next VS
|
||||
if ( m_widget->currentWidget() == m_choicePage &&
|
||||
m_choicePage->currentChoice() == ChoicePage::Alongside )
|
||||
m_choicePage->currentChoice() == ChoicePage::Alongside )
|
||||
{
|
||||
m_choicePage->applyActionChoice( ChoicePage::Alongside );
|
||||
// m_choicePage->reset();
|
||||
@ -380,7 +382,7 @@ PartitionViewStep::onLeave()
|
||||
if ( PartUtils::isEfiSystem() )
|
||||
{
|
||||
QString espMountPoint = Calamares::JobQueue::instance()->globalStorage()->
|
||||
value( "efiSystemPartition").toString();
|
||||
value( "efiSystemPartition" ).toString();
|
||||
Partition* esp = m_core->findPartitionByMountPoint( espMountPoint );
|
||||
|
||||
QString message;
|
||||
@ -435,7 +437,7 @@ PartitionViewStep::onLeave()
|
||||
// If the root partition is encrypted, and there's a separate boot
|
||||
// partition which is not encrypted
|
||||
if ( root_p->fileSystem().type() == FileSystem::Luks &&
|
||||
boot_p->fileSystem().type() != FileSystem::Luks )
|
||||
boot_p->fileSystem().type() != FileSystem::Luks )
|
||||
{
|
||||
message = tr( "Boot partition not encrypted" );
|
||||
description = tr( "A separate boot partition was set up together with "
|
||||
@ -584,17 +586,18 @@ PartitionViewStep::setConfigurationMap( const QVariantMap& configurationMap )
|
||||
// Now that we have the config, we load the PartitionCoreModule in the background
|
||||
// because it could take a while. Then when it's done, we can set up the widgets
|
||||
// and remove the spinner.
|
||||
QFutureWatcher< void >* watcher = new QFutureWatcher< void >();
|
||||
connect( watcher, &QFutureWatcher< void >::finished,
|
||||
this, [ this, watcher, choices ]
|
||||
m_future = new QFutureWatcher< void >();
|
||||
connect( m_future, &QFutureWatcher< void >::finished,
|
||||
this, [ this ]
|
||||
{
|
||||
continueLoading();
|
||||
watcher->deleteLater();
|
||||
this->m_future->deleteLater();
|
||||
this->m_future = nullptr;
|
||||
} );
|
||||
|
||||
QFuture< void > future =
|
||||
QtConcurrent::run( this, &PartitionViewStep::initPartitionCoreModule );
|
||||
watcher->setFuture( future );
|
||||
QtConcurrent::run( this, &PartitionViewStep::initPartitionCoreModule );
|
||||
m_future->setFuture( future );
|
||||
|
||||
if ( configurationMap.contains( "partitionLayout" ) )
|
||||
{
|
||||
@ -613,5 +616,24 @@ PartitionViewStep::jobs() const
|
||||
return m_core->jobs();
|
||||
}
|
||||
|
||||
Calamares::RequirementsList
|
||||
PartitionViewStep::checkRequirements()
|
||||
{
|
||||
if ( m_future )
|
||||
m_future->waitForFinished();
|
||||
|
||||
Calamares::RequirementsList l;
|
||||
l.append(
|
||||
{
|
||||
QLatin1Literal( "partitions" ),
|
||||
[]{ return tr( "has at least one disk device available." ); },
|
||||
[]{ return tr( "There are no partitons to install on." ); },
|
||||
m_core->deviceModel()->rowCount() > 0, // satisfied
|
||||
true // required
|
||||
} );
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
|
||||
CALAMARES_PLUGIN_FACTORY_DEFINITION( PartitionViewStepFactory, registerPlugin<PartitionViewStep>(); )
|
||||
|
@ -36,6 +36,8 @@ class PartitionPage;
|
||||
class PartitionCoreModule;
|
||||
class QStackedWidget;
|
||||
|
||||
template<typename T> class QFutureWatcher;
|
||||
|
||||
/**
|
||||
* The starting point of the module. Instantiates PartitionCoreModule,
|
||||
* ChoicePage and PartitionPage, then connects them.
|
||||
@ -69,6 +71,8 @@ public:
|
||||
|
||||
QList< Calamares::job_ptr > jobs() const override;
|
||||
|
||||
Calamares::RequirementsList checkRequirements() override;
|
||||
|
||||
private:
|
||||
void initPartitionCoreModule();
|
||||
void continueLoading();
|
||||
@ -79,6 +83,7 @@ private:
|
||||
PartitionPage* m_manualPartitionPage;
|
||||
|
||||
QWidget* m_waitingWidget;
|
||||
QFutureWatcher<void>* m_future;
|
||||
|
||||
QSet< PartitionActions::Choices::SwapChoice > m_swapChoices;
|
||||
};
|
||||
|
@ -15,9 +15,10 @@ endif()
|
||||
include_directories( ${PROJECT_BINARY_DIR}/src/libcalamaresui )
|
||||
|
||||
set( CHECKER_SOURCES
|
||||
checker/CheckItemWidget.cpp
|
||||
checker/CheckerContainer.cpp
|
||||
checker/CheckerWidget.cpp
|
||||
checker/RequirementsChecker.cpp
|
||||
checker/CheckItemWidget.cpp
|
||||
checker/GeneralRequirements.cpp
|
||||
${PARTMAN_SRC}
|
||||
)
|
||||
|
||||
|
@ -22,10 +22,12 @@
|
||||
|
||||
#include "ui_WelcomePage.h"
|
||||
#include "CalamaresVersion.h"
|
||||
#include "checker/RequirementsChecker.h"
|
||||
#include "checker/CheckerContainer.h"
|
||||
#include "utils/Logger.h"
|
||||
#include "utils/CalamaresUtilsGui.h"
|
||||
#include "utils/Retranslator.h"
|
||||
|
||||
#include "modulesystem/ModuleManager.h"
|
||||
#include "ViewManager.h"
|
||||
|
||||
#include <QApplication>
|
||||
@ -39,11 +41,14 @@
|
||||
#include "Branding.h"
|
||||
|
||||
|
||||
WelcomePage::WelcomePage( RequirementsChecker* requirementsChecker, QWidget* parent )
|
||||
WelcomePage::WelcomePage( QWidget* parent )
|
||||
: QWidget( parent )
|
||||
, ui( new Ui::WelcomePage )
|
||||
, m_requirementsChecker( requirementsChecker )
|
||||
, m_checkingWidget( new CheckerContainer( this ) )
|
||||
{
|
||||
connect( Calamares::ModuleManager::instance(), &Calamares::ModuleManager::requirementsResult, m_checkingWidget, &CheckerContainer::requirementsChecked );
|
||||
connect( Calamares::ModuleManager::instance(), &Calamares::ModuleManager::requirementsComplete, m_checkingWidget, &CheckerContainer::requirementsComplete );
|
||||
connect( Calamares::ModuleManager::instance(), &Calamares::ModuleManager::requirementsProgress, m_checkingWidget, &CheckerContainer::requirementsProgress );
|
||||
ui->setupUi( this );
|
||||
|
||||
ui->verticalLayout->insertSpacing( 1, CalamaresUtils::defaultFontHeight() * 2 );
|
||||
@ -102,7 +107,7 @@ WelcomePage::WelcomePage( RequirementsChecker* requirementsChecker, QWidget* par
|
||||
mb.exec();
|
||||
} );
|
||||
|
||||
ui->verticalLayout->insertWidget( 3, m_requirementsChecker->widget() );
|
||||
ui->verticalLayout->insertWidget( 3, m_checkingWidget);
|
||||
}
|
||||
|
||||
|
||||
@ -277,3 +282,8 @@ WelcomePage::focusInEvent( QFocusEvent* e )
|
||||
ui->languageWidget->setFocus();
|
||||
e->accept();
|
||||
}
|
||||
|
||||
bool WelcomePage::verdict() const
|
||||
{
|
||||
return m_checkingWidget->verdict();
|
||||
}
|
||||
|
@ -26,26 +26,27 @@ namespace Ui
|
||||
class WelcomePage;
|
||||
}
|
||||
|
||||
class RequirementsChecker;
|
||||
class CheckerContainer;
|
||||
|
||||
class WelcomePage : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit WelcomePage( RequirementsChecker* requirementsChecker,
|
||||
QWidget* parent = nullptr );
|
||||
explicit WelcomePage( QWidget* parent = nullptr );
|
||||
|
||||
void setUpLinks( bool showSupportUrl,
|
||||
bool showKnownIssuesUrl,
|
||||
bool showReleaseNotesUrl );
|
||||
|
||||
bool verdict() const;
|
||||
|
||||
protected:
|
||||
void focusInEvent( QFocusEvent* e ) override; //choose the child widget to focus
|
||||
|
||||
private:
|
||||
void initLanguages();
|
||||
Ui::WelcomePage* ui;
|
||||
RequirementsChecker* m_requirementsChecker;
|
||||
CheckerContainer* m_checkingWidget;
|
||||
};
|
||||
|
||||
#endif // WELCOMEPAGE_H
|
||||
|
@ -20,9 +20,10 @@
|
||||
#include "WelcomeViewStep.h"
|
||||
|
||||
#include "WelcomePage.h"
|
||||
#include "checker/RequirementsChecker.h"
|
||||
#include "utils/Logger.h"
|
||||
#include "checker/GeneralRequirements.h"
|
||||
|
||||
#include "modulesystem/ModuleManager.h"
|
||||
#include "utils/Logger.h"
|
||||
|
||||
#include <QVariant>
|
||||
|
||||
@ -30,12 +31,10 @@ CALAMARES_PLUGIN_FACTORY_DEFINITION( WelcomeViewStepFactory, registerPlugin<Welc
|
||||
|
||||
WelcomeViewStep::WelcomeViewStep( QObject* parent )
|
||||
: Calamares::ViewStep( parent )
|
||||
, m_requirementsChecker( new RequirementsChecker( this ) )
|
||||
, m_requirementsChecker( new GeneralRequirements( this ) )
|
||||
{
|
||||
emit nextStatusChanged( true );
|
||||
m_widget = new WelcomePage( m_requirementsChecker );
|
||||
connect( m_requirementsChecker, &RequirementsChecker::verdictChanged,
|
||||
this, &WelcomeViewStep::nextStatusChanged );
|
||||
connect( Calamares::ModuleManager::instance(), &Calamares::ModuleManager::requirementsComplete, this, &WelcomeViewStep::nextStatusChanged );
|
||||
m_widget = new WelcomePage();
|
||||
}
|
||||
|
||||
|
||||
@ -63,7 +62,7 @@ WelcomeViewStep::widget()
|
||||
bool
|
||||
WelcomeViewStep::isNextEnabled() const
|
||||
{
|
||||
return m_requirementsChecker->verdict();
|
||||
return m_widget->verdict();
|
||||
}
|
||||
|
||||
|
||||
@ -88,10 +87,10 @@ WelcomeViewStep::isAtEnd() const
|
||||
}
|
||||
|
||||
|
||||
QList< Calamares::job_ptr >
|
||||
Calamares::JobList
|
||||
WelcomeViewStep::jobs() const
|
||||
{
|
||||
return QList< Calamares::job_ptr >();
|
||||
return Calamares::JobList();
|
||||
}
|
||||
|
||||
|
||||
@ -123,3 +122,7 @@ WelcomeViewStep::setConfigurationMap( const QVariantMap& configurationMap )
|
||||
"module configuration.";
|
||||
}
|
||||
|
||||
Calamares::RequirementsList WelcomeViewStep::checkRequirements()
|
||||
{
|
||||
return m_requirementsChecker->checkRequirements();
|
||||
}
|
||||
|
@ -21,6 +21,7 @@
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include <modulesystem/Requirement.h>
|
||||
#include <utils/PluginFactory.h>
|
||||
#include <viewpages/ViewStep.h>
|
||||
|
||||
@ -29,7 +30,7 @@
|
||||
#include <QVariantMap>
|
||||
|
||||
class WelcomePage;
|
||||
class RequirementsChecker;
|
||||
class GeneralRequirements;
|
||||
|
||||
class PLUGINDLLEXPORT WelcomeViewStep : public Calamares::ViewStep
|
||||
{
|
||||
@ -49,14 +50,15 @@ public:
|
||||
bool isAtBeginning() const override;
|
||||
bool isAtEnd() const override;
|
||||
|
||||
QList< Calamares::job_ptr > jobs() const override;
|
||||
Calamares::JobList jobs() const override;
|
||||
|
||||
void setConfigurationMap( const QVariantMap& configurationMap ) override;
|
||||
|
||||
Calamares::RequirementsList checkRequirements() override;
|
||||
|
||||
private:
|
||||
WelcomePage* m_widget;
|
||||
|
||||
RequirementsChecker* m_requirementsChecker;
|
||||
GeneralRequirements* m_requirementsChecker;
|
||||
};
|
||||
|
||||
CALAMARES_PLUGIN_FACTORY_DECLARATION( WelcomeViewStepFactory )
|
||||
|
78
src/modules/welcome/checker/CheckerContainer.cpp
Normal file
78
src/modules/welcome/checker/CheckerContainer.cpp
Normal file
@ -0,0 +1,78 @@
|
||||
/* === This file is part of Calamares - <https://github.com/calamares> ===
|
||||
*
|
||||
* Copyright 2014-2017, Teo Mrnjavac <teo@kde.org>
|
||||
* Copyright 2017, Adriaan de Groot <groot@kde.org>
|
||||
* Copyright 2017, Gabriel Craciunescu <crazy@frugalware.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/>.
|
||||
*/
|
||||
|
||||
/* Based on code extracted from RequirementsChecker.cpp */
|
||||
|
||||
#include "CheckerContainer.h"
|
||||
|
||||
#include "CheckerWidget.h"
|
||||
|
||||
#include "utils/CalamaresUtilsGui.h"
|
||||
#include "utils/Logger.h"
|
||||
#include "utils/Retranslator.h"
|
||||
#include "widgets/WaitingWidget.h"
|
||||
|
||||
CheckerContainer::CheckerContainer(QWidget* parent)
|
||||
: QWidget( parent )
|
||||
, m_waitingWidget( new WaitingWidget( QString() ) )
|
||||
, m_checkerWidget( new CheckerWidget() )
|
||||
, m_verdict( false )
|
||||
{
|
||||
QBoxLayout* mainLayout = new QHBoxLayout;
|
||||
setLayout( mainLayout );
|
||||
CalamaresUtils::unmarginLayout( mainLayout );
|
||||
|
||||
mainLayout->addWidget( m_waitingWidget );
|
||||
CALAMARES_RETRANSLATE( m_waitingWidget->setText( tr( "Gathering system information..." ) ); )
|
||||
}
|
||||
|
||||
CheckerContainer::~CheckerContainer()
|
||||
{
|
||||
delete m_waitingWidget;
|
||||
delete m_checkerWidget;
|
||||
}
|
||||
|
||||
void CheckerContainer::requirementsComplete( bool ok )
|
||||
{
|
||||
m_checkerWidget->init( m_requirements );
|
||||
layout()->removeWidget( m_waitingWidget );
|
||||
m_waitingWidget->deleteLater();
|
||||
m_waitingWidget = nullptr; // Don't delete in destructor
|
||||
m_checkerWidget->setParent( this );
|
||||
layout()->addWidget( m_checkerWidget );
|
||||
|
||||
m_verdict = ok;
|
||||
}
|
||||
|
||||
void CheckerContainer::requirementsChecked(const Calamares::RequirementsList& l)
|
||||
{
|
||||
m_requirements.append( l );
|
||||
}
|
||||
|
||||
void CheckerContainer::requirementsProgress(const QString& message)
|
||||
{
|
||||
if ( m_waitingWidget )
|
||||
m_waitingWidget->setText( message );
|
||||
}
|
||||
|
||||
bool CheckerContainer::verdict() const
|
||||
{
|
||||
return m_verdict;
|
||||
}
|
64
src/modules/welcome/checker/CheckerContainer.h
Normal file
64
src/modules/welcome/checker/CheckerContainer.h
Normal file
@ -0,0 +1,64 @@
|
||||
/* === This file is part of Calamares - <https://github.com/calamares> ===
|
||||
*
|
||||
* Copyright 2014-2017, Teo Mrnjavac <teo@kde.org>
|
||||
* Copyright 2017, Adriaan de Groot <groot@kde.org>
|
||||
* Copyright 2017, Gabriel Craciunescu <crazy@frugalware.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/>.
|
||||
*/
|
||||
|
||||
/* Based on code extracted from RequirementsChecker.cpp */
|
||||
|
||||
#ifndef CHECKERCONTAINER_H
|
||||
#define CHECKERCONTAINER_H
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
#include "modulesystem/Requirement.h"
|
||||
|
||||
class CheckerWidget;
|
||||
class WaitingWidget;
|
||||
|
||||
/**
|
||||
* A widget that collects requirements results; until the results are
|
||||
* all in, displays a spinner / waiting widget. Then it switches to
|
||||
* a (list) diplay of the results, plus some explanation of the
|
||||
* overall state of the entire list of results.
|
||||
*/
|
||||
class CheckerContainer : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit CheckerContainer( QWidget* parent = nullptr );
|
||||
virtual ~CheckerContainer();
|
||||
|
||||
bool verdict() const;
|
||||
|
||||
public slots:
|
||||
void requirementsChecked( const Calamares::RequirementsList& );
|
||||
|
||||
/** @brief All the requirements are complete, switch to list view */
|
||||
void requirementsComplete( bool );
|
||||
|
||||
void requirementsProgress( const QString& message );
|
||||
|
||||
protected:
|
||||
WaitingWidget *m_waitingWidget;
|
||||
CheckerWidget *m_checkerWidget;
|
||||
|
||||
Calamares::RequirementsList m_requirements;
|
||||
bool m_verdict;
|
||||
} ;
|
||||
|
||||
#endif
|
@ -53,22 +53,22 @@ CheckerWidget::CheckerWidget( QWidget* parent )
|
||||
|
||||
|
||||
void
|
||||
CheckerWidget::init( const QList< PrepareEntry >& checkEntries )
|
||||
CheckerWidget::init( const Calamares::RequirementsList& checkEntries )
|
||||
{
|
||||
bool allChecked = true;
|
||||
bool requirementsSatisfied = true;
|
||||
|
||||
for ( const PrepareEntry& entry : checkEntries )
|
||||
for ( const auto& entry : checkEntries )
|
||||
{
|
||||
if ( !entry.checked )
|
||||
if ( !entry.satisfied )
|
||||
{
|
||||
CheckItemWidget* ciw = new CheckItemWidget( entry.checked, entry.required );
|
||||
CheckItemWidget* ciw = new CheckItemWidget( entry.satisfied, entry.mandatory );
|
||||
CALAMARES_RETRANSLATE( ciw->setText( entry.negatedText() ); )
|
||||
m_entriesLayout->addWidget( ciw );
|
||||
ciw->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Preferred );
|
||||
|
||||
allChecked = false;
|
||||
if ( entry.required )
|
||||
if ( entry.mandatory )
|
||||
{
|
||||
requirementsSatisfied = false;
|
||||
}
|
||||
@ -162,7 +162,7 @@ CheckerWidget::init( const QList< PrepareEntry >& checkEntries )
|
||||
|
||||
|
||||
void
|
||||
CheckerWidget::showDetailsDialog( const QList< PrepareEntry >& checkEntries )
|
||||
CheckerWidget::showDetailsDialog( const Calamares::RequirementsList& checkEntries )
|
||||
{
|
||||
QDialog* detailsDialog = new QDialog( this );
|
||||
QBoxLayout* mainLayout = new QVBoxLayout;
|
||||
@ -177,12 +177,12 @@ CheckerWidget::showDetailsDialog( const QList< PrepareEntry >& checkEntries )
|
||||
CalamaresUtils::unmarginLayout( entriesLayout );
|
||||
mainLayout->addLayout( entriesLayout );
|
||||
|
||||
for ( const PrepareEntry& entry : checkEntries )
|
||||
for ( const auto& entry : checkEntries )
|
||||
{
|
||||
if ( entry.enumerationText().isEmpty() )
|
||||
continue;
|
||||
|
||||
CheckItemWidget* ciw = new CheckItemWidget( entry.checked, entry.required );
|
||||
CheckItemWidget* ciw = new CheckItemWidget( entry.satisfied, entry.mandatory );
|
||||
CALAMARES_RETRANSLATE( ciw->setText( entry.enumerationText() ); )
|
||||
entriesLayout->addWidget( ciw );
|
||||
ciw->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Preferred );
|
||||
|
@ -19,7 +19,7 @@
|
||||
#ifndef CHECKERWIDGET_H
|
||||
#define CHECKERWIDGET_H
|
||||
|
||||
#include "RequirementsChecker.h"
|
||||
#include "modulesystem/Requirement.h"
|
||||
|
||||
#include <QBoxLayout>
|
||||
#include <QWidget>
|
||||
@ -30,10 +30,10 @@ class CheckerWidget : public QWidget
|
||||
public:
|
||||
explicit CheckerWidget( QWidget* parent = nullptr );
|
||||
|
||||
void init( const QList< PrepareEntry >& checkEntries );
|
||||
void init( const Calamares::RequirementsList& checkEntries );
|
||||
|
||||
private:
|
||||
void showDetailsDialog( const QList< PrepareEntry >& checkEntries );
|
||||
void showDetailsDialog( const Calamares::RequirementsList& checkEntries );
|
||||
|
||||
QBoxLayout* m_mainLayout;
|
||||
QBoxLayout* m_entriesLayout;
|
||||
|
@ -18,11 +18,12 @@
|
||||
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "RequirementsChecker.h"
|
||||
#include "GeneralRequirements.h"
|
||||
|
||||
#include "CheckerWidget.h"
|
||||
#include "CheckerContainer.h"
|
||||
#include "partman_devices.h"
|
||||
|
||||
#include "modulesystem/Requirement.h"
|
||||
#include "widgets/WaitingWidget.h"
|
||||
#include "utils/CalamaresUtilsGui.h"
|
||||
#include "utils/Logger.h"
|
||||
@ -30,6 +31,7 @@
|
||||
#include "utils/CalamaresUtilsSystem.h"
|
||||
#include "utils/Units.h"
|
||||
|
||||
|
||||
#include "JobQueue.h"
|
||||
#include "GlobalStorage.h"
|
||||
|
||||
@ -51,166 +53,113 @@
|
||||
|
||||
#include <unistd.h> //geteuid
|
||||
|
||||
RequirementsChecker::RequirementsChecker( QObject* parent )
|
||||
GeneralRequirements::GeneralRequirements( QObject* parent )
|
||||
: QObject( parent )
|
||||
, m_widget( new QWidget() )
|
||||
, m_requiredStorageGB( -1 )
|
||||
, m_requiredRamGB( -1 )
|
||||
, m_actualWidget( new CheckerWidget() )
|
||||
, m_verdict( false )
|
||||
{
|
||||
QBoxLayout* mainLayout = new QHBoxLayout;
|
||||
m_widget->setLayout( mainLayout );
|
||||
CalamaresUtils::unmarginLayout( mainLayout );
|
||||
}
|
||||
|
||||
WaitingWidget* waitingWidget = new WaitingWidget( QString() );
|
||||
mainLayout->addWidget( waitingWidget );
|
||||
CALAMARES_RETRANSLATE( waitingWidget->setText( tr( "Gathering system information..." ) ); )
|
||||
Calamares::RequirementsList GeneralRequirements::checkRequirements()
|
||||
{
|
||||
QSize availableSize = qApp->desktop()->availableGeometry().size();
|
||||
|
||||
QSize availableSize = qApp->desktop()->availableGeometry( m_widget ).size();
|
||||
bool enoughStorage = false;
|
||||
bool enoughRam = false;
|
||||
bool hasPower = false;
|
||||
bool hasInternet = false;
|
||||
bool isRoot = false;
|
||||
bool enoughScreen = (availableSize.width() >= CalamaresUtils::windowMinimumWidth) && (availableSize.height() >= CalamaresUtils::windowMinimumHeight);
|
||||
|
||||
QTimer* timer = new QTimer;
|
||||
timer->setSingleShot( true );
|
||||
connect( timer, &QTimer::timeout,
|
||||
[=]()
|
||||
qint64 requiredStorageB = CalamaresUtils::GiBtoBytes(m_requiredStorageGB);
|
||||
cDebug() << "Need at least storage bytes:" << requiredStorageB;
|
||||
if ( m_entriesToCheck.contains( "storage" ) )
|
||||
enoughStorage = checkEnoughStorage( requiredStorageB );
|
||||
|
||||
qint64 requiredRamB = CalamaresUtils::GiBtoBytes(m_requiredRamGB);
|
||||
cDebug() << "Need at least ram bytes:" << requiredRamB;
|
||||
if ( m_entriesToCheck.contains( "ram" ) )
|
||||
enoughRam = checkEnoughRam( requiredRamB );
|
||||
|
||||
if ( m_entriesToCheck.contains( "power" ) )
|
||||
hasPower = checkHasPower();
|
||||
|
||||
if ( m_entriesToCheck.contains( "internet" ) )
|
||||
hasInternet = checkHasInternet();
|
||||
|
||||
if ( m_entriesToCheck.contains( "root" ) )
|
||||
isRoot = checkIsRoot();
|
||||
|
||||
using TR = Logger::DebugRow<const char *, bool>;
|
||||
cDebug() << "GeneralRequirements output:"
|
||||
<< TR("enoughStorage", enoughStorage)
|
||||
<< TR("enoughRam", enoughRam)
|
||||
<< TR("hasPower", hasPower)
|
||||
<< TR("hasInternet", hasInternet)
|
||||
<< TR("isRoot", isRoot);
|
||||
|
||||
Calamares::RequirementsList checkEntries;
|
||||
foreach ( const QString& entry, m_entriesToCheck )
|
||||
{
|
||||
bool enoughStorage = false;
|
||||
bool enoughRam = false;
|
||||
bool hasPower = false;
|
||||
bool hasInternet = false;
|
||||
bool isRoot = false;
|
||||
bool enoughScreen = (availableSize.width() >= CalamaresUtils::windowMinimumWidth) && (availableSize.height() >= CalamaresUtils::windowMinimumHeight);
|
||||
|
||||
qint64 requiredStorageB = CalamaresUtils::GiBtoBytes(m_requiredStorageGB);
|
||||
cDebug() << "Need at least storage bytes:" << requiredStorageB;
|
||||
if ( m_entriesToCheck.contains( "storage" ) )
|
||||
enoughStorage = checkEnoughStorage( requiredStorageB );
|
||||
|
||||
qint64 requiredRamB = CalamaresUtils::GiBtoBytes(m_requiredRamGB);
|
||||
cDebug() << "Need at least ram bytes:" << requiredRamB;
|
||||
if ( m_entriesToCheck.contains( "ram" ) )
|
||||
enoughRam = checkEnoughRam( requiredRamB );
|
||||
|
||||
if ( m_entriesToCheck.contains( "power" ) )
|
||||
hasPower = checkHasPower();
|
||||
|
||||
if ( m_entriesToCheck.contains( "internet" ) )
|
||||
hasInternet = checkHasInternet();
|
||||
|
||||
if ( m_entriesToCheck.contains( "root" ) )
|
||||
isRoot = checkIsRoot();
|
||||
|
||||
using TR = Logger::DebugRow<const char *, bool>;
|
||||
|
||||
cDebug() << "RequirementsChecker output:"
|
||||
<< TR("enoughStorage", enoughStorage)
|
||||
<< TR("enoughRam", enoughRam)
|
||||
<< TR("hasPower", hasPower)
|
||||
<< TR("hasInternet", hasInternet)
|
||||
<< TR("isRoot", isRoot);
|
||||
|
||||
QList< PrepareEntry > checkEntries;
|
||||
foreach ( const QString& entry, m_entriesToCheck )
|
||||
{
|
||||
if ( entry == "storage" )
|
||||
checkEntries.append( {
|
||||
entry,
|
||||
[this]{ return tr( "has at least %1 GB available drive space" )
|
||||
.arg( m_requiredStorageGB ); },
|
||||
[this]{ return tr( "There is not enough drive space. At least %1 GB is required." )
|
||||
.arg( m_requiredStorageGB ); },
|
||||
enoughStorage,
|
||||
m_entriesToRequire.contains( entry )
|
||||
} );
|
||||
else if ( entry == "ram" )
|
||||
checkEntries.append( {
|
||||
entry,
|
||||
[this]{ return tr( "has at least %1 GB working memory" )
|
||||
.arg( m_requiredRamGB ); },
|
||||
[this]{ return tr( "The system does not have enough working memory. At least %1 GB is required." )
|
||||
.arg( m_requiredRamGB ); },
|
||||
enoughRam,
|
||||
m_entriesToRequire.contains( entry )
|
||||
} );
|
||||
else if ( entry == "power" )
|
||||
checkEntries.append( {
|
||||
entry,
|
||||
[this]{ return tr( "is plugged in to a power source" ); },
|
||||
[this]{ return tr( "The system is not plugged in to a power source." ); },
|
||||
hasPower,
|
||||
m_entriesToRequire.contains( entry )
|
||||
} );
|
||||
else if ( entry == "internet" )
|
||||
checkEntries.append( {
|
||||
entry,
|
||||
[this]{ return tr( "is connected to the Internet" ); },
|
||||
[this]{ return tr( "The system is not connected to the Internet." ); },
|
||||
hasInternet,
|
||||
m_entriesToRequire.contains( entry )
|
||||
} );
|
||||
else if ( entry == "root" )
|
||||
checkEntries.append( {
|
||||
entry,
|
||||
[this]{ return QString(); }, //we hide it
|
||||
[this]{ return tr( "The installer is not running with administrator rights." ); },
|
||||
isRoot,
|
||||
m_entriesToRequire.contains( entry )
|
||||
} );
|
||||
else if ( entry == "screen" )
|
||||
checkEntries.append( {
|
||||
entry,
|
||||
[this]{ return QString(); }, // we hide it
|
||||
[this]{ return tr( "The screen is too small to display the installer." ); },
|
||||
enoughScreen,
|
||||
false
|
||||
} );
|
||||
}
|
||||
|
||||
m_actualWidget->init( checkEntries );
|
||||
m_widget->layout()->removeWidget( waitingWidget );
|
||||
waitingWidget->deleteLater();
|
||||
m_actualWidget->setParent( m_widget );
|
||||
m_widget->layout()->addWidget( m_actualWidget );
|
||||
|
||||
bool canGoNext = true;
|
||||
foreach ( const PrepareEntry& entry, checkEntries )
|
||||
{
|
||||
if ( !entry.checked && entry.required )
|
||||
{
|
||||
canGoNext = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
m_verdict = canGoNext;
|
||||
emit verdictChanged( m_verdict );
|
||||
|
||||
if ( canGoNext )
|
||||
detectFirmwareType();
|
||||
|
||||
timer->deleteLater();
|
||||
} );
|
||||
timer->start( 0 );
|
||||
|
||||
emit verdictChanged( true );
|
||||
}
|
||||
|
||||
|
||||
RequirementsChecker::~RequirementsChecker()
|
||||
{
|
||||
if ( m_widget && m_widget->parent() == nullptr )
|
||||
m_widget->deleteLater();
|
||||
}
|
||||
|
||||
|
||||
QWidget*
|
||||
RequirementsChecker::widget() const
|
||||
{
|
||||
return m_widget;
|
||||
if ( entry == "storage" )
|
||||
checkEntries.append( {
|
||||
entry,
|
||||
[this]{ return tr( "has at least %1 GB available drive space" )
|
||||
.arg( m_requiredStorageGB ); },
|
||||
[this]{ return tr( "There is not enough drive space. At least %1 GB is required." )
|
||||
.arg( m_requiredStorageGB ); },
|
||||
enoughStorage,
|
||||
m_entriesToRequire.contains( entry )
|
||||
} );
|
||||
else if ( entry == "ram" )
|
||||
checkEntries.append( {
|
||||
entry,
|
||||
[this]{ return tr( "has at least %1 GB working memory" )
|
||||
.arg( m_requiredRamGB ); },
|
||||
[this]{ return tr( "The system does not have enough working memory. At least %1 GB is required." )
|
||||
.arg( m_requiredRamGB ); },
|
||||
enoughRam,
|
||||
m_entriesToRequire.contains( entry )
|
||||
} );
|
||||
else if ( entry == "power" )
|
||||
checkEntries.append( {
|
||||
entry,
|
||||
[this]{ return tr( "is plugged in to a power source" ); },
|
||||
[this]{ return tr( "The system is not plugged in to a power source." ); },
|
||||
hasPower,
|
||||
m_entriesToRequire.contains( entry )
|
||||
} );
|
||||
else if ( entry == "internet" )
|
||||
checkEntries.append( {
|
||||
entry,
|
||||
[this]{ return tr( "is connected to the Internet" ); },
|
||||
[this]{ return tr( "The system is not connected to the Internet." ); },
|
||||
hasInternet,
|
||||
m_entriesToRequire.contains( entry )
|
||||
} );
|
||||
else if ( entry == "root" )
|
||||
checkEntries.append( {
|
||||
entry,
|
||||
[this]{ return QString(); }, //we hide it
|
||||
[this]{ return tr( "The installer is not running with administrator rights." ); },
|
||||
isRoot,
|
||||
m_entriesToRequire.contains( entry )
|
||||
} );
|
||||
else if ( entry == "screen" )
|
||||
checkEntries.append( {
|
||||
entry,
|
||||
[this]{ return QString(); }, // we hide it
|
||||
[this]{ return tr( "The screen is too small to display the installer." ); },
|
||||
enoughScreen,
|
||||
false
|
||||
} );
|
||||
}
|
||||
return checkEntries;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
RequirementsChecker::setConfigurationMap( const QVariantMap& configurationMap )
|
||||
GeneralRequirements::setConfigurationMap( const QVariantMap& configurationMap )
|
||||
{
|
||||
bool incompleteConfiguration = false;
|
||||
|
||||
@ -222,7 +171,7 @@ RequirementsChecker::setConfigurationMap( const QVariantMap& configurationMap )
|
||||
}
|
||||
else
|
||||
{
|
||||
cWarning() << "RequirementsChecker entry 'check' is incomplete.";
|
||||
cWarning() << "GeneralRequirements entry 'check' is incomplete.";
|
||||
incompleteConfiguration = true;
|
||||
}
|
||||
|
||||
@ -234,14 +183,26 @@ RequirementsChecker::setConfigurationMap( const QVariantMap& configurationMap )
|
||||
}
|
||||
else
|
||||
{
|
||||
cWarning() << "RequirementsChecker entry 'required' is incomplete.";
|
||||
cWarning() << "GeneralRequirements entry 'required' is incomplete.";
|
||||
incompleteConfiguration = true;
|
||||
}
|
||||
|
||||
#ifdef WITHOUT_LIBPARTED
|
||||
if ( m_entriesToCheck.contains( "storage" ) )
|
||||
cWarning() << "GeneralRequirements checks 'storage' but libparted is disabled.";
|
||||
if ( m_entriesToRequire.contains( "storage" ) )
|
||||
{
|
||||
// Warn, but also drop the required bit because otherwise installation
|
||||
// will be impossible (because the check always returns false).
|
||||
cWarning() << "GeneralRequirements requires 'storage' check but libparted is disabled.";
|
||||
m_entriesToRequire.removeAll( "storage" );
|
||||
}
|
||||
#endif
|
||||
|
||||
// Help out with consistency, but don't fix
|
||||
for ( const auto& r : m_entriesToRequire )
|
||||
if ( !m_entriesToCheck.contains( r ) )
|
||||
cWarning() << "RequirementsChecker requires" << r << "but does not check it.";
|
||||
cWarning() << "GeneralRequirements requires" << r << "but does not check it.";
|
||||
|
||||
if ( configurationMap.contains( "requiredStorage" ) &&
|
||||
( configurationMap.value( "requiredStorage" ).type() == QVariant::Double ||
|
||||
@ -251,7 +212,7 @@ RequirementsChecker::setConfigurationMap( const QVariantMap& configurationMap )
|
||||
m_requiredStorageGB = configurationMap.value( "requiredStorage" ).toDouble( &ok );
|
||||
if ( !ok )
|
||||
{
|
||||
cWarning() << "RequirementsChecker entry 'requiredStorage' is invalid.";
|
||||
cWarning() << "GeneralRequirements entry 'requiredStorage' is invalid.";
|
||||
m_requiredStorageGB = 3.;
|
||||
}
|
||||
|
||||
@ -259,7 +220,7 @@ RequirementsChecker::setConfigurationMap( const QVariantMap& configurationMap )
|
||||
}
|
||||
else
|
||||
{
|
||||
cWarning() << "RequirementsChecker entry 'requiredStorage' is missing.";
|
||||
cWarning() << "GeneralRequirements entry 'requiredStorage' is missing.";
|
||||
m_requiredStorageGB = 3.;
|
||||
incompleteConfiguration = true;
|
||||
}
|
||||
@ -272,14 +233,14 @@ RequirementsChecker::setConfigurationMap( const QVariantMap& configurationMap )
|
||||
m_requiredRamGB = configurationMap.value( "requiredRam" ).toDouble( &ok );
|
||||
if ( !ok )
|
||||
{
|
||||
cWarning() << "RequirementsChecker entry 'requiredRam' is invalid.";
|
||||
cWarning() << "GeneralRequirements entry 'requiredRam' is invalid.";
|
||||
m_requiredRamGB = 1.;
|
||||
incompleteConfiguration = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cWarning() << "RequirementsChecker entry 'requiredRam' is missing.";
|
||||
cWarning() << "GeneralRequirements entry 'requiredRam' is missing.";
|
||||
m_requiredRamGB = 1.;
|
||||
incompleteConfiguration = true;
|
||||
}
|
||||
@ -291,7 +252,7 @@ RequirementsChecker::setConfigurationMap( const QVariantMap& configurationMap )
|
||||
if ( m_checkHasInternetUrl.isEmpty() ||
|
||||
!QUrl( m_checkHasInternetUrl ).isValid() )
|
||||
{
|
||||
cWarning() << "RequirementsChecker entry 'internetCheckUrl' is invalid in welcome.conf" << m_checkHasInternetUrl
|
||||
cWarning() << "GeneralRequirements entry 'internetCheckUrl' is invalid in welcome.conf" << m_checkHasInternetUrl
|
||||
<< "reverting to default (http://example.com).";
|
||||
m_checkHasInternetUrl = "http://example.com";
|
||||
incompleteConfiguration = true;
|
||||
@ -299,7 +260,7 @@ RequirementsChecker::setConfigurationMap( const QVariantMap& configurationMap )
|
||||
}
|
||||
else
|
||||
{
|
||||
cWarning() << "RequirementsChecker entry 'internetCheckUrl' is undefined in welcome.conf,"
|
||||
cWarning() << "GeneralRequirements entry 'internetCheckUrl' is undefined in welcome.conf,"
|
||||
"reverting to default (http://example.com).";
|
||||
|
||||
m_checkHasInternetUrl = "http://example.com";
|
||||
@ -308,24 +269,17 @@ RequirementsChecker::setConfigurationMap( const QVariantMap& configurationMap )
|
||||
|
||||
if ( incompleteConfiguration )
|
||||
{
|
||||
cWarning() << "RequirementsChecker configuration map:" << Logger::DebugMap( configurationMap );
|
||||
cWarning() << "GeneralRequirements configuration map:" << Logger::DebugMap( configurationMap );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
RequirementsChecker::verdict() const
|
||||
{
|
||||
return m_verdict;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
RequirementsChecker::checkEnoughStorage( qint64 requiredSpace )
|
||||
GeneralRequirements::checkEnoughStorage( qint64 requiredSpace )
|
||||
{
|
||||
#ifdef WITHOUT_LIBPARTED
|
||||
Q_UNUSED( requiredSpace );
|
||||
cWarning() << "RequirementsChecker is configured without libparted.";
|
||||
cWarning() << "GeneralRequirements is configured without libparted.";
|
||||
return false;
|
||||
#else
|
||||
return check_big_enough( requiredSpace );
|
||||
@ -334,7 +288,7 @@ RequirementsChecker::checkEnoughStorage( qint64 requiredSpace )
|
||||
|
||||
|
||||
bool
|
||||
RequirementsChecker::checkEnoughRam( qint64 requiredRam )
|
||||
GeneralRequirements::checkEnoughRam( qint64 requiredRam )
|
||||
{
|
||||
// Ignore the guesstimate-factor; we get an under-estimate
|
||||
// which is probably the usable RAM for programs.
|
||||
@ -344,7 +298,7 @@ RequirementsChecker::checkEnoughRam( qint64 requiredRam )
|
||||
|
||||
|
||||
bool
|
||||
RequirementsChecker::checkBatteryExists()
|
||||
GeneralRequirements::checkBatteryExists()
|
||||
{
|
||||
const QFileInfo basePath( "/sys/class/power_supply" );
|
||||
|
||||
@ -370,7 +324,7 @@ RequirementsChecker::checkBatteryExists()
|
||||
|
||||
|
||||
bool
|
||||
RequirementsChecker::checkHasPower()
|
||||
GeneralRequirements::checkHasPower()
|
||||
{
|
||||
const QString UPOWER_SVC_NAME( "org.freedesktop.UPower" );
|
||||
const QString UPOWER_INTF_NAME( "org.freedesktop.UPower" );
|
||||
@ -401,10 +355,10 @@ RequirementsChecker::checkHasPower()
|
||||
|
||||
|
||||
bool
|
||||
RequirementsChecker::checkHasInternet()
|
||||
GeneralRequirements::checkHasInternet()
|
||||
{
|
||||
// default to true in the QNetworkAccessManager::UnknownAccessibility case
|
||||
QNetworkAccessManager qnam( this );
|
||||
QNetworkAccessManager qnam;
|
||||
bool hasInternet = qnam.networkAccessible() == QNetworkAccessManager::Accessible;
|
||||
|
||||
if ( !hasInternet && qnam.networkAccessible() == QNetworkAccessManager::UnknownAccessibility )
|
||||
@ -425,14 +379,14 @@ RequirementsChecker::checkHasInternet()
|
||||
|
||||
|
||||
bool
|
||||
RequirementsChecker::checkIsRoot()
|
||||
GeneralRequirements::checkIsRoot()
|
||||
{
|
||||
return !geteuid();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
RequirementsChecker::detectFirmwareType()
|
||||
GeneralRequirements::detectFirmwareType()
|
||||
{
|
||||
QString fwType = QFile::exists( "/sys/firmware/efi/efivars" ) ? "efi" : "bios";
|
||||
Calamares::JobQueue::instance()->globalStorage()->insert( "firmwareType", fwType );
|
@ -17,52 +17,23 @@
|
||||
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef REQUIREMENTSCHECKER_H
|
||||
#define REQUIREMENTSCHECKER_H
|
||||
#ifndef GENERALREQUIREMENTS_H
|
||||
#define GENERALREQUIREMENTS_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QStringList>
|
||||
|
||||
#include <functional>
|
||||
#include "modulesystem/Requirement.h"
|
||||
|
||||
class CheckerWidget;
|
||||
class QWidget;
|
||||
|
||||
/**
|
||||
* An indication of a requirement, which is checked in preparation
|
||||
* for system installation. An entry has a name and some explanation,
|
||||
* as well as three meaningful states:
|
||||
* - checked = true, the requirement is met (green)
|
||||
* - checked = false, the requirement is not met
|
||||
* - required = false, warn about it (yellow), no failure
|
||||
* - required = true, prohibit installation (red)
|
||||
*/
|
||||
struct PrepareEntry
|
||||
{
|
||||
QString name;
|
||||
std::function< QString() > enumerationText; //Partial string, inserted in a
|
||||
//list of requirements to satisfy.
|
||||
std::function< QString() > negatedText; //Complete sentence about this requirement
|
||||
//not having been met.
|
||||
bool checked;
|
||||
bool required;
|
||||
};
|
||||
|
||||
class RequirementsChecker : public QObject
|
||||
class GeneralRequirements : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit RequirementsChecker( QObject* parent = nullptr );
|
||||
virtual ~RequirementsChecker();
|
||||
|
||||
QWidget* widget() const;
|
||||
explicit GeneralRequirements( QObject* parent = nullptr );
|
||||
|
||||
void setConfigurationMap( const QVariantMap& configurationMap );
|
||||
|
||||
bool verdict() const;
|
||||
|
||||
signals:
|
||||
void verdictChanged( bool );
|
||||
Calamares::RequirementsList checkRequirements();
|
||||
|
||||
private:
|
||||
QStringList m_entriesToCheck;
|
||||
@ -76,13 +47,9 @@ private:
|
||||
bool checkIsRoot();
|
||||
void detectFirmwareType();
|
||||
|
||||
QWidget* m_widget;
|
||||
qreal m_requiredStorageGB;
|
||||
qreal m_requiredRamGB;
|
||||
QString m_checkHasInternetUrl;
|
||||
|
||||
CheckerWidget* m_actualWidget;
|
||||
bool m_verdict;
|
||||
};
|
||||
|
||||
#endif // REQUIREMENTSCHECKER_H
|
@ -1,18 +1,37 @@
|
||||
# Configuration for the welcome module. The welcome page
|
||||
# displays some information from the branding file.
|
||||
# Which parts it displays can be configured through
|
||||
# the show* variables.
|
||||
#
|
||||
# In addition to displaying the welcome page, this module
|
||||
# can check requirements for installation.
|
||||
---
|
||||
# Display settings for various buttons on the welcome page.
|
||||
showSupportUrl: true
|
||||
showKnownIssuesUrl: true
|
||||
showReleaseNotesUrl: true
|
||||
|
||||
# Requirements checking. These are general, generic, things
|
||||
# that are checked. They may not match with the actual requirements
|
||||
# imposed by other modules in the system.
|
||||
requirements:
|
||||
# Amount of available disk, in GB. Floating-point is allowed here.
|
||||
# Note that this does not account for *usable* disk, so it is possible
|
||||
# to pass this requirement, yet have no space to install to.
|
||||
requiredStorage: 5.5
|
||||
|
||||
# Amount of available RAM, in GB. Floating-point is allowed here.
|
||||
requiredRam: 1.0
|
||||
|
||||
# To check for internet connectivity, Calamares does a HTTP GET
|
||||
# on this URL; on success (e.g. HTTP code 200) internet is OK.
|
||||
internetCheckUrl: http://google.com
|
||||
|
||||
# List conditions to check. Each listed condition will be
|
||||
# probed in some way, and yields true or false according to
|
||||
# the host system satisfying the condition.
|
||||
#
|
||||
# This sample file lists all the conditions that are know.
|
||||
# This sample file lists all the conditions that are known.
|
||||
check:
|
||||
- storage
|
||||
- ram
|
||||
@ -20,7 +39,7 @@ requirements:
|
||||
- internet
|
||||
- root
|
||||
- screen
|
||||
# List conditions that must be satisfied (from the list
|
||||
# List conditions that **must** be satisfied (from the list
|
||||
# of conditions, above) for installation to proceed.
|
||||
# If any of these conditions are not met, the user cannot
|
||||
# continue past the welcome page.
|
||||
|
Loading…
Reference in New Issue
Block a user