Merge branch 'issue-1287' into calamares
Major update to the 'tracking' module with improved wording, functionality, QML-preparation, and a working kuserfeedback mode. FIXES #1287
This commit is contained in:
commit
0305476f8a
@ -26,6 +26,7 @@ ReflowComments: "false"
|
|||||||
SortIncludes: "true"
|
SortIncludes: "true"
|
||||||
SpaceAfterCStyleCast: "false"
|
SpaceAfterCStyleCast: "false"
|
||||||
SpacesBeforeTrailingComments: "2"
|
SpacesBeforeTrailingComments: "2"
|
||||||
|
# SpaceInEmptyBlock: "true"
|
||||||
SpacesInAngles: "true"
|
SpacesInAngles: "true"
|
||||||
SpacesInParentheses: "true"
|
SpacesInParentheses: "true"
|
||||||
SpacesInSquareBrackets: "true"
|
SpacesInSquareBrackets: "true"
|
||||||
|
3
CHANGES
3
CHANGES
@ -6,6 +6,7 @@ website will have to do for older versions.
|
|||||||
# 3.2.26 (unreleased) #
|
# 3.2.26 (unreleased) #
|
||||||
|
|
||||||
This release contains contributions from (alphabetically by first name):
|
This release contains contributions from (alphabetically by first name):
|
||||||
|
- Anke Boersma
|
||||||
- Gaël PORTAY
|
- Gaël PORTAY
|
||||||
- Pablo Ovelleiro Corral
|
- Pablo Ovelleiro Corral
|
||||||
- Philip Müller
|
- Philip Müller
|
||||||
@ -26,6 +27,8 @@ This release contains contributions from (alphabetically by first name):
|
|||||||
UTC+11, but Calamares still showed it in a zone separate from UTC+11.
|
UTC+11, but Calamares still showed it in a zone separate from UTC+11.
|
||||||
- *packages* gained support for the Void Linux package manager,
|
- *packages* gained support for the Void Linux package manager,
|
||||||
*xbps*. (thanks Pablo)
|
*xbps*. (thanks Pablo)
|
||||||
|
- *tracking* now supports kuserfeedback configuration.
|
||||||
|
|
||||||
|
|
||||||
# 3.2.25 (2020-06-06) #
|
# 3.2.25 (2020-06-06) #
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ export LANG LC_ALL LC_NUMERIC
|
|||||||
|
|
||||||
AS=$( which astyle )
|
AS=$( which astyle )
|
||||||
|
|
||||||
CF_VERSIONS="clang-format-7 clang-format-8 clang-format70 clang-format80 clang-format"
|
CF_VERSIONS="clang-format-7 clang-format-8 clang-format70 clang-format80 clang-format-9.0.1 clang-format"
|
||||||
for _cf in $CF_VERSIONS
|
for _cf in $CF_VERSIONS
|
||||||
do
|
do
|
||||||
# Not an error if this particular clang-format isn't found
|
# Not an error if this particular clang-format isn't found
|
||||||
@ -26,6 +26,8 @@ test -n "$CF" || { echo "! No clang-format ($CF_VERSIONS) found in PATH"; exit 1
|
|||||||
test -x "$AS" || { echo "! $AS is not executable."; exit 1 ; }
|
test -x "$AS" || { echo "! $AS is not executable."; exit 1 ; }
|
||||||
test -x "$CF" || { echo "! $CF is not executable."; exit 1 ; }
|
test -x "$CF" || { echo "! $CF is not executable."; exit 1 ; }
|
||||||
|
|
||||||
|
expr `"$CF" --version | tr -dc '[^.0-9]' | cut -d . -f 1` '<' 10 > /dev/null || { echo "! $CF is version 10 or later, needs different .clang-format" ; exit 1 ; }
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
any_dirs=no
|
any_dirs=no
|
||||||
|
@ -65,6 +65,20 @@ getString( const QVariantMap& map, const QString& key )
|
|||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QStringList
|
||||||
|
getStringList( const QVariantMap& map, const QString& key )
|
||||||
|
{
|
||||||
|
if ( map.contains( key ) )
|
||||||
|
{
|
||||||
|
auto v = map.value( key );
|
||||||
|
if ( v.type() == QVariant::StringList )
|
||||||
|
{
|
||||||
|
return v.toStringList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return QStringList();
|
||||||
|
}
|
||||||
|
|
||||||
qint64
|
qint64
|
||||||
getInteger( const QVariantMap& map, const QString& key, qint64 d )
|
getInteger( const QVariantMap& map, const QString& key, qint64 d )
|
||||||
{
|
{
|
||||||
|
@ -43,6 +43,11 @@ DLLEXPORT bool getBool( const QVariantMap& map, const QString& key, bool d );
|
|||||||
*/
|
*/
|
||||||
DLLEXPORT QString getString( const QVariantMap& map, const QString& key );
|
DLLEXPORT QString getString( const QVariantMap& map, const QString& key );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a string list from a mapping; returns empty list if no value.
|
||||||
|
*/
|
||||||
|
DLLEXPORT QStringList getStringList( const QVariantMap& map, const QString& key );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get an integer value from a mapping; returns @p d if no value.
|
* Get an integer value from a mapping; returns @p d if no value.
|
||||||
*/
|
*/
|
||||||
|
@ -2,6 +2,7 @@ calamares_add_plugin( tracking
|
|||||||
TYPE viewmodule
|
TYPE viewmodule
|
||||||
EXPORT_MACRO PLUGINDLLEXPORT_PRO
|
EXPORT_MACRO PLUGINDLLEXPORT_PRO
|
||||||
SOURCES
|
SOURCES
|
||||||
|
Config.cpp
|
||||||
TrackingJobs.cpp
|
TrackingJobs.cpp
|
||||||
TrackingPage.cpp
|
TrackingPage.cpp
|
||||||
TrackingViewStep.cpp
|
TrackingViewStep.cpp
|
||||||
|
256
src/modules/tracking/Config.cpp
Normal file
256
src/modules/tracking/Config.cpp
Normal file
@ -0,0 +1,256 @@
|
|||||||
|
/* === This file is part of Calamares - <https://github.com/calamares> ===
|
||||||
|
*
|
||||||
|
* Copyright 2020, Adriaan de Groot <groot@kde.org>
|
||||||
|
*
|
||||||
|
* Calamares is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Calamares is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Config.h"
|
||||||
|
|
||||||
|
#include "TrackingType.h"
|
||||||
|
|
||||||
|
#include "utils/Logger.h"
|
||||||
|
#include "utils/Variant.h"
|
||||||
|
|
||||||
|
#include <QUrl>
|
||||||
|
|
||||||
|
const NamedEnumTable< TrackingType >&
|
||||||
|
trackingNames()
|
||||||
|
{
|
||||||
|
// *INDENT-OFF*
|
||||||
|
// clang-format off
|
||||||
|
static const NamedEnumTable< TrackingType > names {
|
||||||
|
{ QStringLiteral( "none" ), TrackingType::NoTracking },
|
||||||
|
{ QStringLiteral( "install" ), TrackingType::InstallTracking },
|
||||||
|
{ QStringLiteral( "machine" ), TrackingType::MachineTracking },
|
||||||
|
{ QStringLiteral( "user" ), TrackingType::UserTracking }
|
||||||
|
};
|
||||||
|
// clang-format on
|
||||||
|
// *INDENT-ON*
|
||||||
|
|
||||||
|
return names;
|
||||||
|
}
|
||||||
|
|
||||||
|
TrackingStyleConfig::TrackingStyleConfig( QObject* parent )
|
||||||
|
: QObject( parent )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
TrackingStyleConfig::~TrackingStyleConfig() {}
|
||||||
|
|
||||||
|
void
|
||||||
|
TrackingStyleConfig::setTracking( bool enabled )
|
||||||
|
{
|
||||||
|
setTracking( enabled ? EnabledByUser : DisabledByUser );
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TrackingStyleConfig::setTracking( TrackingStyleConfig::TrackingState state )
|
||||||
|
{
|
||||||
|
if ( m_state != TrackingState::DisabledByConfig )
|
||||||
|
{
|
||||||
|
m_state = state;
|
||||||
|
}
|
||||||
|
emit trackingChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TrackingStyleConfig::validate( QString& s, std::function< bool( const QString& ) >&& pred )
|
||||||
|
{
|
||||||
|
if ( !pred( s ) )
|
||||||
|
{
|
||||||
|
if ( m_state != DisabledByConfig )
|
||||||
|
{
|
||||||
|
cError() << "Configuration string" << s << "is not valid; disabling this tracking type.";
|
||||||
|
m_state = DisabledByConfig;
|
||||||
|
emit trackingChanged();
|
||||||
|
}
|
||||||
|
s = QString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TrackingStyleConfig::validateUrl( QString& urlString )
|
||||||
|
{
|
||||||
|
if ( !QUrl( urlString ).isValid() )
|
||||||
|
{
|
||||||
|
if ( m_state != DisabledByConfig )
|
||||||
|
{
|
||||||
|
cError() << "URL" << urlString << "is not valid; disabling tracking type" << objectName();
|
||||||
|
m_state = DisabledByConfig;
|
||||||
|
emit trackingChanged();
|
||||||
|
}
|
||||||
|
urlString = QString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TrackingStyleConfig::setConfigurationMap( const QVariantMap& config )
|
||||||
|
{
|
||||||
|
m_state = CalamaresUtils::getBool( config, "enabled", false ) ? DisabledByUser : DisabledByConfig;
|
||||||
|
m_policy = CalamaresUtils::getString( config, "policy" );
|
||||||
|
validateUrl( m_policy );
|
||||||
|
emit policyChanged( m_policy );
|
||||||
|
emit trackingChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
InstallTrackingConfig::InstallTrackingConfig( QObject* parent )
|
||||||
|
: TrackingStyleConfig( parent )
|
||||||
|
{
|
||||||
|
setObjectName( "InstallTrackingConfig" );
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
InstallTrackingConfig::setConfigurationMap( const QVariantMap& configurationMap )
|
||||||
|
{
|
||||||
|
TrackingStyleConfig::setConfigurationMap( configurationMap );
|
||||||
|
|
||||||
|
m_installTrackingUrl = CalamaresUtils::getString( configurationMap, "url" );
|
||||||
|
validateUrl( m_installTrackingUrl );
|
||||||
|
}
|
||||||
|
|
||||||
|
MachineTrackingConfig::MachineTrackingConfig( QObject* parent )
|
||||||
|
: TrackingStyleConfig( parent )
|
||||||
|
{
|
||||||
|
setObjectName( "MachineTrackingConfig" );
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @brief Is @p s a valid machine-tracking style. */
|
||||||
|
static bool
|
||||||
|
isValidMachineTrackingStyle( const QString& s )
|
||||||
|
{
|
||||||
|
static QStringList knownStyles { "updatemanager" };
|
||||||
|
return knownStyles.contains( s );
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MachineTrackingConfig::setConfigurationMap( const QVariantMap& configurationMap )
|
||||||
|
{
|
||||||
|
TrackingStyleConfig::setConfigurationMap( configurationMap );
|
||||||
|
|
||||||
|
m_machineTrackingStyle = CalamaresUtils::getString( configurationMap, "style" );
|
||||||
|
validate( m_machineTrackingStyle, isValidMachineTrackingStyle );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
UserTrackingConfig::UserTrackingConfig( QObject* parent )
|
||||||
|
: TrackingStyleConfig( parent )
|
||||||
|
{
|
||||||
|
setObjectName( "UserTrackingConfig" );
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
isValidUserTrackingStyle( const QString& s )
|
||||||
|
{
|
||||||
|
static QStringList knownStyles { "kuserfeedback" };
|
||||||
|
return knownStyles.contains( s );
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
UserTrackingConfig::setConfigurationMap( const QVariantMap& configurationMap )
|
||||||
|
{
|
||||||
|
TrackingStyleConfig::setConfigurationMap( configurationMap );
|
||||||
|
|
||||||
|
m_userTrackingStyle = CalamaresUtils::getString( configurationMap, "style" );
|
||||||
|
validate( m_userTrackingStyle, isValidUserTrackingStyle );
|
||||||
|
|
||||||
|
m_userTrackingAreas = CalamaresUtils::getStringList( configurationMap, "areas" );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Config::Config( QObject* parent )
|
||||||
|
: QObject( parent )
|
||||||
|
, m_installTracking( new InstallTrackingConfig( this ) )
|
||||||
|
, m_machineTracking( new MachineTrackingConfig( this ) )
|
||||||
|
, m_userTracking( new UserTrackingConfig( this ) )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
enableLevelsBelow( Config* config, TrackingType level )
|
||||||
|
{
|
||||||
|
switch ( level )
|
||||||
|
{
|
||||||
|
case TrackingType::UserTracking:
|
||||||
|
config->userTracking()->setTracking( TrackingStyleConfig::TrackingState::EnabledByUser );
|
||||||
|
FALLTHRU;
|
||||||
|
case TrackingType::MachineTracking:
|
||||||
|
config->machineTracking()->setTracking( TrackingStyleConfig::TrackingState::EnabledByUser );
|
||||||
|
FALLTHRU;
|
||||||
|
case TrackingType::InstallTracking:
|
||||||
|
config->installTracking()->setTracking( TrackingStyleConfig::TrackingState::EnabledByUser );
|
||||||
|
break;
|
||||||
|
case TrackingType::NoTracking:
|
||||||
|
config->noTracking( true );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Config::setConfigurationMap( const QVariantMap& configurationMap )
|
||||||
|
{
|
||||||
|
m_generalPolicy = CalamaresUtils::getString( configurationMap, "policy" );
|
||||||
|
|
||||||
|
if ( !QUrl( m_generalPolicy ).isValid() )
|
||||||
|
{
|
||||||
|
m_generalPolicy = QString();
|
||||||
|
}
|
||||||
|
emit generalPolicyChanged( m_generalPolicy );
|
||||||
|
|
||||||
|
bool success = false;
|
||||||
|
auto subconfig = CalamaresUtils::getSubMap( configurationMap, "install", success );
|
||||||
|
if ( success )
|
||||||
|
{
|
||||||
|
m_installTracking->setConfigurationMap( subconfig );
|
||||||
|
}
|
||||||
|
|
||||||
|
subconfig = CalamaresUtils::getSubMap( configurationMap, "machine", success );
|
||||||
|
if ( success )
|
||||||
|
{
|
||||||
|
m_machineTracking->setConfigurationMap( subconfig );
|
||||||
|
}
|
||||||
|
|
||||||
|
subconfig = CalamaresUtils::getSubMap( configurationMap, "user", success );
|
||||||
|
if ( success )
|
||||||
|
{
|
||||||
|
m_userTracking->setConfigurationMap( subconfig );
|
||||||
|
}
|
||||||
|
|
||||||
|
auto level = trackingNames().find( CalamaresUtils::getString( configurationMap, "default" ), success );
|
||||||
|
if ( !success )
|
||||||
|
{
|
||||||
|
cWarning() << "Default tracking level unknown:" << CalamaresUtils::getString( configurationMap, "default" );
|
||||||
|
level = TrackingType::NoTracking;
|
||||||
|
}
|
||||||
|
enableLevelsBelow( this, level );
|
||||||
|
}
|
||||||
|
|
||||||
|
QString
|
||||||
|
Config::generalPolicy() const
|
||||||
|
{
|
||||||
|
return m_generalPolicy;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Config::noTracking( bool switchOffAllTracking )
|
||||||
|
{
|
||||||
|
if ( !switchOffAllTracking )
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
m_installTracking->setTracking( TrackingStyleConfig::TrackingState::DisabledByUser );
|
||||||
|
m_machineTracking->setTracking( TrackingStyleConfig::TrackingState::DisabledByUser );
|
||||||
|
m_userTracking->setTracking( TrackingStyleConfig::TrackingState::DisabledByUser );
|
||||||
|
}
|
192
src/modules/tracking/Config.h
Normal file
192
src/modules/tracking/Config.h
Normal file
@ -0,0 +1,192 @@
|
|||||||
|
/* === This file is part of Calamares - <https://github.com/calamares> ===
|
||||||
|
*
|
||||||
|
* Copyright 2020, Adriaan de Groot <groot@kde.org>
|
||||||
|
*
|
||||||
|
* Calamares is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Calamares is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef TRACKING_CONFIG_H
|
||||||
|
#define TRACKING_CONFIG_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QString>
|
||||||
|
#include <QVariantMap>
|
||||||
|
|
||||||
|
/** @brief Base class for configuring a specific kind of tracking.
|
||||||
|
*
|
||||||
|
* All tracking types have a policy URL, which is used to explain what
|
||||||
|
* kind of tracking is involved, what data is sent, etc. The content
|
||||||
|
* of that URL is the responsibility of the distro.
|
||||||
|
*
|
||||||
|
* A tracking type is disabled by default: if it isn't specifically
|
||||||
|
* enabled (for configuration) in the config file, it will always be disabled.
|
||||||
|
* If it is enabled (for configuration) in the config file, it still
|
||||||
|
* defaults to disabled, but the user can choose to enable it.
|
||||||
|
*/
|
||||||
|
class TrackingStyleConfig : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
Q_PROPERTY( TrackingState trackingStatus READ tracking WRITE setTracking NOTIFY trackingChanged FINAL )
|
||||||
|
Q_PROPERTY( bool isEnabled READ isEnabled NOTIFY trackingChanged FINAL )
|
||||||
|
Q_PROPERTY( bool isConfigurable READ isConfigurable NOTIFY trackingChanged FINAL )
|
||||||
|
Q_PROPERTY( QString policy READ policy NOTIFY policyChanged FINAL )
|
||||||
|
|
||||||
|
public:
|
||||||
|
TrackingStyleConfig( QObject* parent );
|
||||||
|
virtual ~TrackingStyleConfig();
|
||||||
|
|
||||||
|
void setConfigurationMap( const QVariantMap& );
|
||||||
|
|
||||||
|
enum TrackingState
|
||||||
|
{
|
||||||
|
DisabledByConfig,
|
||||||
|
DisabledByUser,
|
||||||
|
EnabledByUser
|
||||||
|
};
|
||||||
|
Q_ENUM( TrackingState );
|
||||||
|
|
||||||
|
public Q_SLOTS:
|
||||||
|
TrackingState tracking() const { return m_state; }
|
||||||
|
/// @brief Has the user specifically enabled this kind of tracking?
|
||||||
|
bool isEnabled() const { return m_state == EnabledByUser; }
|
||||||
|
/// @brief Is this tracking enabled for configuration?
|
||||||
|
bool isConfigurable() const { return m_state != DisabledByConfig; }
|
||||||
|
/** @brief Sets the tracking state
|
||||||
|
*
|
||||||
|
* Unless the tracking is enabled for configuration, it always
|
||||||
|
* remains disabled.
|
||||||
|
*/
|
||||||
|
void setTracking( TrackingState );
|
||||||
|
/** @brief Sets the tracking state
|
||||||
|
*
|
||||||
|
* Use @c true for @c EnabledByUser, @c false for DisabledByUser,
|
||||||
|
* but keep in mind that if the tracking is not enabled for
|
||||||
|
* configuration, it will always remain disabled.
|
||||||
|
*/
|
||||||
|
void setTracking( bool );
|
||||||
|
|
||||||
|
/// @brief URL for the policy explaining this tracking
|
||||||
|
QString policy() const { return m_policy; }
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void trackingChanged();
|
||||||
|
void policyChanged( QString );
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/// @brief Validates the @p urlString, disables tracking if invalid
|
||||||
|
void validateUrl( QString& urlString );
|
||||||
|
/// @brief Validates the @p string, disables tracking if invalid
|
||||||
|
void validate( QString& s, std::function< bool( const QString& s ) >&& pred );
|
||||||
|
|
||||||
|
private:
|
||||||
|
TrackingState m_state = DisabledByConfig;
|
||||||
|
QString m_policy; // URL
|
||||||
|
};
|
||||||
|
|
||||||
|
/** @brief Install tracking pings a URL at the end of installation
|
||||||
|
*
|
||||||
|
* Install tracking will do a single GET on the given URL at
|
||||||
|
* the end of installation. The information included in the GET
|
||||||
|
* request depends on the URL configuration, see also the tracking
|
||||||
|
* jobs.
|
||||||
|
*/
|
||||||
|
class InstallTrackingConfig : public TrackingStyleConfig
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
InstallTrackingConfig( QObject* parent );
|
||||||
|
void setConfigurationMap( const QVariantMap& configurationMap );
|
||||||
|
|
||||||
|
QString installTrackingUrl() { return m_installTrackingUrl; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString m_installTrackingUrl;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** @brief Machine tracking reports from the installed system
|
||||||
|
*
|
||||||
|
* When machine tracking is on, the installed system will report
|
||||||
|
* back ("call home") at some point. This can mean Debian pop-con,
|
||||||
|
* or updatemanager maching tracking, or something else. The kind
|
||||||
|
* of configuration depends on the style of tracking that is enabled.
|
||||||
|
*/
|
||||||
|
class MachineTrackingConfig : public TrackingStyleConfig
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MachineTrackingConfig( QObject* parent );
|
||||||
|
void setConfigurationMap( const QVariantMap& configurationMap );
|
||||||
|
|
||||||
|
QString machineTrackingStyle() { return m_machineTrackingStyle; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString m_machineTrackingStyle;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** @brief User tracking reports user actions
|
||||||
|
*
|
||||||
|
* When user tracking is on, it is enabled for the user configured
|
||||||
|
* in Calamares -- not for users created afterwards in the target
|
||||||
|
* system, unless the target system defaults to tracking them.
|
||||||
|
* The kind of user tracking depends on the target system and
|
||||||
|
* environment; KDE user tracking is one example, which can be
|
||||||
|
* configured in a fine-grained way and defaults to off.
|
||||||
|
*/
|
||||||
|
class UserTrackingConfig : public TrackingStyleConfig
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
UserTrackingConfig( QObject* parent );
|
||||||
|
void setConfigurationMap( const QVariantMap& configurationMap );
|
||||||
|
|
||||||
|
QString userTrackingStyle() { return m_userTrackingStyle; }
|
||||||
|
QStringList userTrackingAreas() const { return m_userTrackingAreas; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString m_userTrackingStyle;
|
||||||
|
QStringList m_userTrackingAreas; // fine-grained areas
|
||||||
|
};
|
||||||
|
|
||||||
|
class Config : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PROPERTY( QString generalPolicy READ generalPolicy NOTIFY generalPolicyChanged FINAL )
|
||||||
|
Q_PROPERTY( TrackingStyleConfig* installTracking READ installTracking FINAL )
|
||||||
|
Q_PROPERTY( TrackingStyleConfig* machineTracking READ machineTracking FINAL )
|
||||||
|
Q_PROPERTY( TrackingStyleConfig* userTracking READ userTracking FINAL )
|
||||||
|
|
||||||
|
public:
|
||||||
|
Config( QObject* parent = nullptr );
|
||||||
|
void setConfigurationMap( const QVariantMap& );
|
||||||
|
|
||||||
|
public Q_SLOTS:
|
||||||
|
QString generalPolicy() const;
|
||||||
|
|
||||||
|
InstallTrackingConfig* installTracking() const { return m_installTracking; }
|
||||||
|
MachineTrackingConfig* machineTracking() const { return m_machineTracking; }
|
||||||
|
UserTrackingConfig* userTracking() const { return m_userTracking; }
|
||||||
|
|
||||||
|
/// @brief Call with @c true to turn off all the trackings
|
||||||
|
void noTracking( bool );
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void generalPolicyChanged( QString );
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString m_generalPolicy;
|
||||||
|
|
||||||
|
InstallTrackingConfig* m_installTracking;
|
||||||
|
MachineTrackingConfig* m_machineTracking;
|
||||||
|
UserTrackingConfig* m_userTracking;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -18,10 +18,16 @@
|
|||||||
|
|
||||||
#include "TrackingJobs.h"
|
#include "TrackingJobs.h"
|
||||||
|
|
||||||
|
#include "Config.h"
|
||||||
|
|
||||||
|
#include "GlobalStorage.h"
|
||||||
|
#include "JobQueue.h"
|
||||||
#include "network/Manager.h"
|
#include "network/Manager.h"
|
||||||
#include "utils/CalamaresUtilsSystem.h"
|
#include "utils/CalamaresUtilsSystem.h"
|
||||||
#include "utils/Logger.h"
|
#include "utils/Logger.h"
|
||||||
|
|
||||||
|
#include <KMacroExpander>
|
||||||
|
|
||||||
#include <QSemaphore>
|
#include <QSemaphore>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
|
||||||
@ -32,7 +38,7 @@ TrackingInstallJob::TrackingInstallJob( const QString& url )
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
TrackingInstallJob::~TrackingInstallJob() { }
|
TrackingInstallJob::~TrackingInstallJob() {}
|
||||||
|
|
||||||
QString
|
QString
|
||||||
TrackingInstallJob::prettyName() const
|
TrackingInstallJob::prettyName() const
|
||||||
@ -72,38 +78,72 @@ TrackingInstallJob::exec()
|
|||||||
return Calamares::JobResult::ok();
|
return Calamares::JobResult::ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TrackingInstallJob::addJob( Calamares::JobList& list, InstallTrackingConfig* config )
|
||||||
|
{
|
||||||
|
if ( config->isEnabled() )
|
||||||
|
{
|
||||||
|
const auto* s = CalamaresUtils::System::instance();
|
||||||
|
QHash< QString, QString > map { std::initializer_list< std::pair< QString, QString > > {
|
||||||
|
{ QStringLiteral( "CPU" ), s->getCpuDescription() },
|
||||||
|
{ QStringLiteral( "MEMORY" ), QString::number( s->getTotalMemoryB().first ) },
|
||||||
|
{ QStringLiteral( "DISK" ), QString::number( s->getTotalDiskB() ) } } };
|
||||||
|
QString installUrl = KMacroExpander::expandMacros( config->installTrackingUrl(), map );
|
||||||
|
|
||||||
|
cDebug() << Logger::SubEntry << "install-tracking URL" << installUrl;
|
||||||
|
|
||||||
|
list.append( Calamares::job_ptr( new TrackingInstallJob( installUrl ) ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TrackingMachineJob::addJob( Calamares::JobList& list, MachineTrackingConfig* config )
|
||||||
|
{
|
||||||
|
if ( config->isEnabled() )
|
||||||
|
{
|
||||||
|
const auto style = config->machineTrackingStyle();
|
||||||
|
if ( style == "updatemanager" )
|
||||||
|
{
|
||||||
|
list.append( Calamares::job_ptr( new TrackingMachineUpdateManagerJob() ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cWarning() << "Unsupported machine tracking style" << style;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
QString
|
QString
|
||||||
TrackingMachineNeonJob::prettyName() const
|
TrackingMachineUpdateManagerJob::prettyName() const
|
||||||
{
|
{
|
||||||
return tr( "Machine feedback" );
|
return tr( "Machine feedback" );
|
||||||
}
|
}
|
||||||
|
|
||||||
QString
|
QString
|
||||||
TrackingMachineNeonJob::prettyDescription() const
|
TrackingMachineUpdateManagerJob::prettyDescription() const
|
||||||
{
|
{
|
||||||
return prettyName();
|
return prettyName();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString
|
QString
|
||||||
TrackingMachineNeonJob::prettyStatusMessage() const
|
TrackingMachineUpdateManagerJob::prettyStatusMessage() const
|
||||||
{
|
{
|
||||||
return tr( "Configuring machine feedback." );
|
return tr( "Configuring machine feedback." );
|
||||||
}
|
}
|
||||||
|
|
||||||
Calamares::JobResult
|
Calamares::JobResult
|
||||||
TrackingMachineNeonJob::exec()
|
TrackingMachineUpdateManagerJob::exec()
|
||||||
{
|
{
|
||||||
static const auto script = QStringLiteral(
|
static const auto script = QStringLiteral(
|
||||||
R"x(
|
"sed -i '/^URI/s,${MACHINE_ID},'`cat /etc/machine-id`',' /etc/update-manager/meta-release || true" );
|
||||||
MACHINE_ID=`cat /etc/machine-id`
|
|
||||||
sed -i "s,URI =.*,URI = http://releases.neon.kde.org/meta-release/${MACHINE_ID}," /etc/update-manager/meta-release
|
auto res = CalamaresUtils::System::instance()->runCommand( CalamaresUtils::System::RunLocation::RunInTarget,
|
||||||
sed -i "s,URI_LTS =.*,URI_LTS = http://releases.neon.kde.org/meta-release-lts/${MACHINE_ID}," /etc/update-manager/meta-release
|
QStringList { QStringLiteral( "/bin/sh" ) },
|
||||||
true
|
|
||||||
)x" );
|
|
||||||
int r = CalamaresUtils::System::instance()->targetEnvCall( "/bin/sh",
|
|
||||||
QString(), // Working dir
|
QString(), // Working dir
|
||||||
script,
|
script, // standard input
|
||||||
std::chrono::seconds( 1 ) );
|
std::chrono::seconds( 1 ) );
|
||||||
|
int r = res.first;
|
||||||
|
|
||||||
if ( r == 0 )
|
if ( r == 0 )
|
||||||
{
|
{
|
||||||
@ -122,3 +162,87 @@ true
|
|||||||
tr( "Could not configure machine feedback correctly, Calamares error %1." ).arg( r ) );
|
tr( "Could not configure machine feedback correctly, Calamares error %1." ).arg( r ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TrackingUserJob::addJob( Calamares::JobList& list, UserTrackingConfig* config )
|
||||||
|
{
|
||||||
|
if ( config->isEnabled() )
|
||||||
|
{
|
||||||
|
const auto* gs = Calamares::JobQueue::instance()->globalStorage();
|
||||||
|
static const auto key = QStringLiteral( "username" );
|
||||||
|
QString username = ( gs && gs->contains( key ) ) ? gs->value( key ).toString() : QString();
|
||||||
|
|
||||||
|
if ( username.isEmpty() )
|
||||||
|
{
|
||||||
|
cWarning() << "No username is set in GlobalStorage, skipping user-tracking.";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto style = config->userTrackingStyle();
|
||||||
|
if ( style == "kuserfeedback" )
|
||||||
|
{
|
||||||
|
list.append( Calamares::job_ptr( new TrackingKUserFeedbackJob( username, config->userTrackingAreas() ) ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cWarning() << "Unsupported user tracking style" << style;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TrackingKUserFeedbackJob::TrackingKUserFeedbackJob( const QString& username, const QStringList& areas )
|
||||||
|
: m_username( username )
|
||||||
|
, m_areas( areas )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QString
|
||||||
|
TrackingKUserFeedbackJob::prettyName() const
|
||||||
|
{
|
||||||
|
return tr( "KDE user feedback" );
|
||||||
|
}
|
||||||
|
|
||||||
|
QString
|
||||||
|
TrackingKUserFeedbackJob::prettyDescription() const
|
||||||
|
{
|
||||||
|
return prettyName();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString
|
||||||
|
TrackingKUserFeedbackJob::prettyStatusMessage() const
|
||||||
|
{
|
||||||
|
return tr( "Configuring KDE user feedback." );
|
||||||
|
}
|
||||||
|
|
||||||
|
Calamares::JobResult
|
||||||
|
TrackingKUserFeedbackJob::exec()
|
||||||
|
{
|
||||||
|
// This is the contents of a config file to turn on some kind
|
||||||
|
// of KUserFeedback tracking; the level (16) is chosen for minimal
|
||||||
|
// but not zero tracking.
|
||||||
|
static const char config[] = R"x([Global]
|
||||||
|
FeedbackLevel=16
|
||||||
|
)x";
|
||||||
|
|
||||||
|
for ( const QString& area : m_areas )
|
||||||
|
{
|
||||||
|
QString path = QStringLiteral( "/home/%1/.config/%2" ).arg( m_username, area );
|
||||||
|
cDebug() << "Configuring KUserFeedback" << path;
|
||||||
|
|
||||||
|
int r = CalamaresUtils::System::instance()->createTargetFile( path, config );
|
||||||
|
if ( r > 0 )
|
||||||
|
{
|
||||||
|
return Calamares::JobResult::error(
|
||||||
|
tr( "Error in KDE user feedback configuration." ),
|
||||||
|
tr( "Could not configure KDE user feedback correctly, script error %1." ).arg( r ) );
|
||||||
|
}
|
||||||
|
else if ( r < 0 )
|
||||||
|
{
|
||||||
|
return Calamares::JobResult::error(
|
||||||
|
tr( "Error in KDE user feedback configuration." ),
|
||||||
|
tr( "Could not configure KDE user feedback correctly, Calamares error %1." ).arg( r ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Calamares::JobResult::ok();
|
||||||
|
}
|
||||||
|
@ -16,13 +16,36 @@
|
|||||||
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
|
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef TRACKINGJOBS
|
#ifndef TRACKING_TRACKINGJOBS_H
|
||||||
#define TRACKINGJOBS
|
#define TRACKING_TRACKINGJOBS_H
|
||||||
|
|
||||||
#include "Job.h"
|
#include "Job.h"
|
||||||
|
|
||||||
|
class InstallTrackingConfig;
|
||||||
|
class MachineTrackingConfig;
|
||||||
|
class UserTrackingConfig;
|
||||||
|
|
||||||
class QSemaphore;
|
class QSemaphore;
|
||||||
|
|
||||||
|
/** @section Tracking Jobs
|
||||||
|
*
|
||||||
|
* The tracking jobs do the actual work of configuring tracking on the
|
||||||
|
* target machine. Tracking jobs may have *styles*, variations depending
|
||||||
|
* on the distro or environment of the target system. At the root of
|
||||||
|
* each family of tracking jobs (installation, machine, user) there is
|
||||||
|
* a class with static method `addJob()` that takes the configuration
|
||||||
|
* information from the relevant Config sub-object and optionally
|
||||||
|
* adds the right job (subclass!) to the list of jobs.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @brief Install-tracking job (gets a URL)
|
||||||
|
*
|
||||||
|
* The install-tracking job (there is only one kind) does a GET
|
||||||
|
* on a configured URL with some additional information about
|
||||||
|
* the machine (if configured into the URL).
|
||||||
|
*
|
||||||
|
* No persistent tracking is done.
|
||||||
|
*/
|
||||||
class TrackingInstallJob : public Calamares::Job
|
class TrackingInstallJob : public Calamares::Job
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@ -35,11 +58,31 @@ public:
|
|||||||
QString prettyStatusMessage() const override;
|
QString prettyStatusMessage() const override;
|
||||||
Calamares::JobResult exec() override;
|
Calamares::JobResult exec() override;
|
||||||
|
|
||||||
|
static void addJob( Calamares::JobList& list, InstallTrackingConfig* config );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const QString m_url;
|
const QString m_url;
|
||||||
};
|
};
|
||||||
|
|
||||||
class TrackingMachineNeonJob : public Calamares::Job
|
/** @brief Base class for machine-tracking jobs
|
||||||
|
*
|
||||||
|
* Machine-tracking configuraiton depends on the distro / style of machine
|
||||||
|
* being tracked, so it has subclasses to switch on the relevant kind
|
||||||
|
* of tracking. A machine is tracked persistently.
|
||||||
|
*/
|
||||||
|
class TrackingMachineJob : public Calamares::Job
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static void addJob( Calamares::JobList& list, MachineTrackingConfig* config );
|
||||||
|
};
|
||||||
|
|
||||||
|
/** @brief Tracking machines, update-manager style
|
||||||
|
*
|
||||||
|
* The machine has a machine-id, and this is sed(1)'ed into the
|
||||||
|
* update-manager configuration, to report the machine-id back
|
||||||
|
* to distro servers.
|
||||||
|
*/
|
||||||
|
class TrackingMachineUpdateManagerJob : public TrackingMachineJob
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
@ -49,5 +92,38 @@ public:
|
|||||||
Calamares::JobResult exec() override;
|
Calamares::JobResult exec() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** @brief Base class for user-tracking jobs
|
||||||
|
*
|
||||||
|
* User-tracking configuration depends on the distro / style of user
|
||||||
|
* tracking being implemented, so there are subclasses to switch on the
|
||||||
|
* relevant kind of tracking. Users are tracked persistently (the user
|
||||||
|
* can of course configure the tracking again once the system is restarted).
|
||||||
|
*/
|
||||||
|
class TrackingUserJob : public Calamares::Job
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static void addJob( Calamares::JobList& list, UserTrackingConfig* config );
|
||||||
|
};
|
||||||
|
|
||||||
|
/** @brief Turn on KUserFeedback in target system
|
||||||
|
*
|
||||||
|
* This writes suitable files for turning on KUserFeedback for the
|
||||||
|
* normal user configured in Calamares. The feedback can be reconfigured
|
||||||
|
* by the user through Plasma's user-feedback dialog.
|
||||||
|
*/
|
||||||
|
class TrackingKUserFeedbackJob : public Calamares::Job
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TrackingKUserFeedbackJob( const QString& username, const QStringList& areas );
|
||||||
|
|
||||||
|
QString prettyName() const override;
|
||||||
|
QString prettyDescription() const override;
|
||||||
|
QString prettyStatusMessage() const override;
|
||||||
|
Calamares::JobResult exec() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString m_username;
|
||||||
|
QStringList m_areas;
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
#include "TrackingPage.h"
|
#include "TrackingPage.h"
|
||||||
|
|
||||||
|
#include "Config.h"
|
||||||
#include "ui_page_trackingstep.h"
|
#include "ui_page_trackingstep.h"
|
||||||
|
|
||||||
#include "Branding.h"
|
#include "Branding.h"
|
||||||
@ -28,178 +29,128 @@
|
|||||||
#include "utils/Logger.h"
|
#include "utils/Logger.h"
|
||||||
#include "utils/Retranslator.h"
|
#include "utils/Retranslator.h"
|
||||||
|
|
||||||
#include <QButtonGroup>
|
|
||||||
#include <QDesktopServices>
|
#include <QDesktopServices>
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
|
|
||||||
TrackingPage::TrackingPage( QWidget* parent )
|
TrackingPage::TrackingPage( Config* config, QWidget* parent )
|
||||||
: QWidget( parent )
|
: QWidget( parent )
|
||||||
, ui( new Ui::TrackingPage )
|
, ui( new Ui::TrackingPage )
|
||||||
{
|
{
|
||||||
ui->setupUi( this );
|
ui->setupUi( this );
|
||||||
CALAMARES_RETRANSLATE(
|
CALAMARES_RETRANSLATE_SLOT( &TrackingPage::retranslate );
|
||||||
QString product = Calamares::Branding::instance()->shortProductName(); ui->retranslateUi( this );
|
|
||||||
ui->generalExplanation->setText(
|
|
||||||
tr( "Install tracking helps %1 to see how many users they have, what hardware they install %1 to and (with "
|
|
||||||
"the last two options below), get continuous information about preferred applications. To see what "
|
|
||||||
"will be sent, please click the help icon next to each area." )
|
|
||||||
.arg( product ) );
|
|
||||||
ui->installExplanation->setText(
|
|
||||||
tr( "By selecting this you will send information about your installation and hardware. This information "
|
|
||||||
"will <b>only be sent once</b> after the installation finishes." ) );
|
|
||||||
ui->machineExplanation->setText( tr( "By selecting this you will <b>periodically</b> send information about "
|
|
||||||
"your installation, hardware and applications, to %1." )
|
|
||||||
.arg( product ) );
|
|
||||||
ui->userExplanation->setText( tr( "By selecting this you will <b>regularly</b> send information about your "
|
|
||||||
"installation, hardware, applications and usage patterns, to %1." )
|
|
||||||
.arg( product ) ); )
|
|
||||||
|
|
||||||
QButtonGroup* group = new QButtonGroup( this );
|
ui->noneCheckBox->setChecked( true );
|
||||||
group->setExclusive( true );
|
ui->noneCheckBox->setEnabled( false );
|
||||||
group->addButton( ui->noneRadio );
|
connect( ui->noneCheckBox, &QCheckBox::stateChanged, this, &TrackingPage::buttonNoneChecked );
|
||||||
group->addButton( ui->installRadio );
|
|
||||||
group->addButton( ui->machineRadio );
|
// Each "panel" of configuration has the same kind of setup,
|
||||||
group->addButton( ui->userRadio );
|
// where the xButton and xCheckBox is connected to the xTracking
|
||||||
ui->noneRadio->setChecked( true );
|
// configuration object; that takes macro-trickery, unfortunately.
|
||||||
|
#define trackingSetup( x ) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
connect( ui->x##CheckBox, &QCheckBox::stateChanged, this, &TrackingPage::buttonChecked ); \
|
||||||
|
connect( ui->x##CheckBox, \
|
||||||
|
&QCheckBox::stateChanged, \
|
||||||
|
config->x##Tracking(), \
|
||||||
|
QOverload< bool >::of( &TrackingStyleConfig::setTracking ) ); \
|
||||||
|
connect( config->x##Tracking(), &TrackingStyleConfig::trackingChanged, this, [this, config]() { \
|
||||||
|
this->trackerChanged( config->x##Tracking(), this->ui->x##Group, this->ui->x##CheckBox ); \
|
||||||
|
} ); \
|
||||||
|
connect( ui->x##PolicyButton, &QAbstractButton::clicked, config, [config] { \
|
||||||
|
QString url( config->x##Tracking()->policy() ); \
|
||||||
|
if ( !url.isEmpty() ) \
|
||||||
|
{ \
|
||||||
|
QDesktopServices::openUrl( url ); \
|
||||||
|
} \
|
||||||
|
} ); \
|
||||||
|
} while ( false )
|
||||||
|
|
||||||
|
trackingSetup( install );
|
||||||
|
trackingSetup( machine );
|
||||||
|
trackingSetup( user );
|
||||||
|
|
||||||
|
#undef trackingSetup
|
||||||
|
|
||||||
|
connect( config, &Config::generalPolicyChanged, [this]( const QString& url ) {
|
||||||
|
this->ui->generalPolicyLabel->setVisible( !url.isEmpty() );
|
||||||
|
} );
|
||||||
|
connect( ui->generalPolicyLabel, &QLabel::linkActivated, [config] {
|
||||||
|
QString url( config->generalPolicy() );
|
||||||
|
if ( !url.isEmpty() )
|
||||||
|
{
|
||||||
|
QDesktopServices::openUrl( url );
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
|
||||||
|
retranslate();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
TrackingPage::enableTrackingOption( TrackingType t, bool enabled )
|
TrackingPage::retranslate()
|
||||||
{
|
{
|
||||||
QWidget* group = nullptr;
|
QString product = Calamares::Branding::instance()->shortProductName();
|
||||||
|
ui->retranslateUi( this );
|
||||||
switch ( t )
|
ui->generalExplanation->setText(
|
||||||
{
|
tr( "Tracking helps %1 to see how often it is installed, what hardware it is installed on and "
|
||||||
case TrackingType::InstallTracking:
|
"which applications are used. To see what "
|
||||||
group = ui->installGroup;
|
"will be sent, please click the help icon next to each area." )
|
||||||
break;
|
.arg( product ) );
|
||||||
case TrackingType::MachineTracking:
|
ui->installExplanation->setText(
|
||||||
group = ui->machineGroup;
|
tr( "By selecting this you will send information about your installation and hardware. This information "
|
||||||
break;
|
"will only be sent <b>once</b> after the installation finishes." ) );
|
||||||
case TrackingType::UserTracking:
|
ui->machineExplanation->setText(
|
||||||
group = ui->userGroup;
|
tr( "By selecting this you will periodically send information about your <b>machine</b> installation, "
|
||||||
break;
|
"hardware and applications, to %1." )
|
||||||
}
|
.arg( product ) );
|
||||||
|
ui->userExplanation->setText(
|
||||||
if ( group != nullptr )
|
tr( "By selecting this you will regularly send information about your "
|
||||||
{
|
"<b>user</b> installation, hardware, applications and application usage patterns, to %1." )
|
||||||
if ( enabled )
|
.arg( product ) );
|
||||||
{
|
|
||||||
group->show();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
group->hide();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cWarning() << "unknown tracking option" << int( t );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
TrackingPage::getTrackingOption( TrackingType t )
|
TrackingPage::anyOtherChecked() const
|
||||||
{
|
{
|
||||||
bool enabled = false;
|
return ui->installCheckBox->isChecked() || ui->machineCheckBox->isChecked() || ui->userCheckBox->isChecked();
|
||||||
|
}
|
||||||
|
|
||||||
// A tracking type is enabled if it is checked, or
|
|
||||||
// any higher level is checked.
|
void
|
||||||
#define ch( x ) ui->x->isChecked()
|
TrackingPage::buttonNoneChecked( int state )
|
||||||
switch ( t )
|
{
|
||||||
|
if ( state )
|
||||||
{
|
{
|
||||||
case TrackingType::InstallTracking:
|
cDebug() << "Unchecking all other buttons because 'None' was checked";
|
||||||
enabled = ch( installRadio ) || ch( machineRadio ) || ch( userRadio );
|
ui->installCheckBox->setChecked( false );
|
||||||
break;
|
ui->machineCheckBox->setChecked( false );
|
||||||
case TrackingType::MachineTracking:
|
ui->userCheckBox->setChecked( false );
|
||||||
enabled = ch( machineRadio ) || ch( userRadio );
|
ui->noneCheckBox->setEnabled( false );
|
||||||
break;
|
|
||||||
case TrackingType::UserTracking:
|
|
||||||
enabled = ch( userRadio );
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
#undef ch
|
|
||||||
return enabled;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
TrackingPage::setTrackingPolicy( TrackingType t, QString url )
|
TrackingPage::buttonChecked( int state )
|
||||||
{
|
{
|
||||||
QToolButton* button = nullptr;
|
if ( state )
|
||||||
switch ( t )
|
|
||||||
{
|
{
|
||||||
case TrackingType::InstallTracking:
|
// Can't have none checked, if another one is
|
||||||
button = ui->installPolicyButton;
|
ui->noneCheckBox->setEnabled( true );
|
||||||
break;
|
ui->noneCheckBox->setChecked( false );
|
||||||
case TrackingType::MachineTracking:
|
|
||||||
button = ui->machinePolicyButton;
|
|
||||||
break;
|
|
||||||
case TrackingType::UserTracking:
|
|
||||||
button = ui->userPolicyButton;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
if ( button != nullptr )
|
{
|
||||||
if ( url.isEmpty() )
|
if ( !anyOtherChecked() )
|
||||||
{
|
{
|
||||||
button->hide();
|
ui->noneCheckBox->setChecked( true );
|
||||||
|
ui->noneCheckBox->setEnabled( false );
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
connect( button, &QToolButton::clicked, [ url ] { QDesktopServices::openUrl( url ); } );
|
|
||||||
cDebug() << "Tracking policy" << int( t ) << "set to" << url;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cWarning() << "unknown tracking option" << int( t );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
TrackingPage::setGeneralPolicy( QString url )
|
TrackingPage::trackerChanged( TrackingStyleConfig* config, QWidget* panel, QCheckBox* check )
|
||||||
{
|
{
|
||||||
if ( url.isEmpty() )
|
panel->setVisible( config->isConfigurable() );
|
||||||
{
|
check->setChecked( config->isEnabled() );
|
||||||
ui->generalPolicyLabel->hide();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ui->generalPolicyLabel->show();
|
|
||||||
ui->generalPolicyLabel->setTextInteractionFlags( Qt::TextBrowserInteraction );
|
|
||||||
ui->generalPolicyLabel->show();
|
|
||||||
connect( ui->generalPolicyLabel, &QLabel::linkActivated, [ url ] { QDesktopServices::openUrl( url ); } );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
TrackingPage::setTrackingLevel( const QString& l )
|
|
||||||
{
|
|
||||||
QString level = l.toLower();
|
|
||||||
QRadioButton* button = nullptr;
|
|
||||||
|
|
||||||
if ( level.isEmpty() || level == "none" )
|
|
||||||
{
|
|
||||||
button = ui->noneRadio;
|
|
||||||
}
|
|
||||||
else if ( level == "install" )
|
|
||||||
{
|
|
||||||
button = ui->installRadio;
|
|
||||||
}
|
|
||||||
else if ( level == "machine" )
|
|
||||||
{
|
|
||||||
button = ui->machineRadio;
|
|
||||||
}
|
|
||||||
else if ( level == "user" )
|
|
||||||
{
|
|
||||||
button = ui->userRadio;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( button != nullptr )
|
|
||||||
{
|
|
||||||
button->setChecked( true );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cWarning() << "unknown default tracking level" << l;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
#include "TrackingType.h"
|
#include "TrackingType.h"
|
||||||
|
|
||||||
|
#include <QCheckBox>
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
|
|
||||||
@ -29,35 +30,48 @@ namespace Ui
|
|||||||
class TrackingPage;
|
class TrackingPage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class Config;
|
||||||
|
class TrackingStyleConfig;
|
||||||
|
|
||||||
class TrackingPage : public QWidget
|
class TrackingPage : public QWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
explicit TrackingPage( QWidget* parent = nullptr );
|
explicit TrackingPage( Config* config, QWidget* parent = nullptr );
|
||||||
|
|
||||||
/**
|
/** @brief is any of the enable-tracking buttons checked?
|
||||||
* Enables or disables the tracking-option block for the given
|
|
||||||
* tracking option @p t, and sets the initial state of the
|
|
||||||
* checkbox to the @p user default.
|
|
||||||
*
|
*
|
||||||
* Call this in ascending order of tracking type.
|
* Returns true if any one or more of install, machine or user
|
||||||
|
* tracking is enabled.
|
||||||
*/
|
*/
|
||||||
void enableTrackingOption( TrackingType t, bool enabled );
|
bool anyOtherChecked() const;
|
||||||
/**
|
|
||||||
* Returns whether tracking type @p is selected by the user
|
|
||||||
* (i.e. is the radio button for that level, or for a higher
|
|
||||||
* tracking level, enabled).
|
|
||||||
*/
|
|
||||||
bool getTrackingOption( TrackingType t );
|
|
||||||
|
|
||||||
/* URL for given level @p t */
|
public Q_SLOTS:
|
||||||
void setTrackingPolicy( TrackingType t, QString url );
|
void retranslate();
|
||||||
/* URL for the global link */
|
|
||||||
void setGeneralPolicy( QString url );
|
/** @brief When the *no tracking* checkbox is changed
|
||||||
/* Select one of the four levels by name */
|
*
|
||||||
void setTrackingLevel( const QString& level );
|
* @p state will be non-zero when the box is checked; this
|
||||||
|
* **unchecks** all the other boxes.
|
||||||
|
*/
|
||||||
|
void buttonNoneChecked( int state );
|
||||||
|
|
||||||
|
/** @brief Some other checkbox changed
|
||||||
|
*
|
||||||
|
* This may check the *none* button if all the others are
|
||||||
|
* now unchecked.
|
||||||
|
*/
|
||||||
|
void buttonChecked( int state );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
/** @brief Apply the tracking configuration to the UI
|
||||||
|
*
|
||||||
|
* If the config cannot be changed (disabled in config) then
|
||||||
|
* hide the UI parts on the @p panel; otherwise show it
|
||||||
|
* and set @p check state to whether the user has enabled it.
|
||||||
|
*/
|
||||||
|
void trackerChanged( TrackingStyleConfig* subconfig, QWidget* panel, QCheckBox* check );
|
||||||
|
|
||||||
Ui::TrackingPage* ui;
|
Ui::TrackingPage* ui;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -19,11 +19,17 @@
|
|||||||
#ifndef TRACKINGTYPE_H
|
#ifndef TRACKINGTYPE_H
|
||||||
#define TRACKINGTYPE_H
|
#define TRACKINGTYPE_H
|
||||||
|
|
||||||
|
#include "utils/NamedEnum.h"
|
||||||
|
|
||||||
enum class TrackingType
|
enum class TrackingType
|
||||||
{
|
{
|
||||||
InstallTracking,
|
NoTracking, // Do not enable tracking at all
|
||||||
MachineTracking,
|
InstallTracking, // Track that *this* install has happened
|
||||||
UserTracking
|
MachineTracking, // Track the machine, ongoing
|
||||||
|
UserTracking // Track the user, ongoing
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Implemented in Config.cpp
|
||||||
|
const NamedEnumTable< TrackingType >& trackingNames();
|
||||||
|
|
||||||
#endif //TRACKINGTYPE_H
|
#endif //TRACKINGTYPE_H
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
#include "TrackingViewStep.h"
|
#include "TrackingViewStep.h"
|
||||||
|
|
||||||
|
#include "Config.h"
|
||||||
#include "TrackingJobs.h"
|
#include "TrackingJobs.h"
|
||||||
#include "TrackingPage.h"
|
#include "TrackingPage.h"
|
||||||
|
|
||||||
@ -33,17 +34,10 @@
|
|||||||
|
|
||||||
CALAMARES_PLUGIN_FACTORY_DEFINITION( TrackingViewStepFactory, registerPlugin< TrackingViewStep >(); )
|
CALAMARES_PLUGIN_FACTORY_DEFINITION( TrackingViewStepFactory, registerPlugin< TrackingViewStep >(); )
|
||||||
|
|
||||||
/** @brief Is @p s a valid machine-tracking style. */
|
|
||||||
static bool
|
|
||||||
isValidStyle( const QString& s )
|
|
||||||
{
|
|
||||||
static QStringList knownStyles { "neon" };
|
|
||||||
return knownStyles.contains( s );
|
|
||||||
}
|
|
||||||
|
|
||||||
TrackingViewStep::TrackingViewStep( QObject* parent )
|
TrackingViewStep::TrackingViewStep( QObject* parent )
|
||||||
: Calamares::ViewStep( parent )
|
: Calamares::ViewStep( parent )
|
||||||
, m_widget( new TrackingPage )
|
, m_config( new Config( this ) )
|
||||||
|
, m_widget( new TrackingPage( m_config ) )
|
||||||
{
|
{
|
||||||
emit nextStatusChanged( false );
|
emit nextStatusChanged( false );
|
||||||
}
|
}
|
||||||
@ -103,89 +97,28 @@ TrackingViewStep::isAtEnd() const
|
|||||||
void
|
void
|
||||||
TrackingViewStep::onLeave()
|
TrackingViewStep::onLeave()
|
||||||
{
|
{
|
||||||
m_installTracking.userEnabled = m_widget->getTrackingOption( TrackingType::InstallTracking );
|
cDebug() << "Install tracking:" << m_config->installTracking()->isEnabled();
|
||||||
m_machineTracking.userEnabled = m_widget->getTrackingOption( TrackingType::MachineTracking );
|
cDebug() << Logger::SubEntry << "Machine tracking:" << m_config->machineTracking()->isEnabled();
|
||||||
m_userTracking.userEnabled = m_widget->getTrackingOption( TrackingType::UserTracking );
|
cDebug() << Logger::SubEntry << " User tracking:" << m_config->userTracking()->isEnabled();
|
||||||
cDebug() << "Install tracking:" << m_installTracking.enabled();
|
|
||||||
cDebug() << "Machine tracking:" << m_machineTracking.enabled();
|
|
||||||
cDebug() << " User tracking:" << m_userTracking.enabled();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Calamares::JobList
|
Calamares::JobList
|
||||||
TrackingViewStep::jobs() const
|
TrackingViewStep::jobs() const
|
||||||
{
|
{
|
||||||
Calamares::JobList l;
|
|
||||||
|
|
||||||
cDebug() << "Creating tracking jobs ..";
|
cDebug() << "Creating tracking jobs ..";
|
||||||
if ( m_installTracking.enabled() && !m_installTrackingUrl.isEmpty() )
|
|
||||||
{
|
|
||||||
QString installUrl = m_installTrackingUrl;
|
|
||||||
const auto s = CalamaresUtils::System::instance();
|
|
||||||
|
|
||||||
QString memory, disk;
|
Calamares::JobList l;
|
||||||
memory.setNum( s->getTotalMemoryB().first );
|
TrackingInstallJob::addJob( l, m_config->installTracking() );
|
||||||
disk.setNum( s->getTotalDiskB() );
|
TrackingMachineJob::addJob( l, m_config->machineTracking() );
|
||||||
|
TrackingUserJob::addJob( l, m_config->userTracking() );
|
||||||
installUrl.replace( "$CPU", s->getCpuDescription() ).replace( "$MEMORY", memory ).replace( "$DISK", disk );
|
cDebug() << Logger::SubEntry << l.count() << "jobs queued.";
|
||||||
|
|
||||||
cDebug() << Logger::SubEntry << "install-tracking URL" << installUrl;
|
|
||||||
|
|
||||||
l.append( Calamares::job_ptr( new TrackingInstallJob( installUrl ) ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( m_machineTracking.enabled() && !m_machineTrackingStyle.isEmpty() )
|
|
||||||
{
|
|
||||||
Q_ASSERT( isValidStyle( m_machineTrackingStyle ) );
|
|
||||||
if ( m_machineTrackingStyle == "neon" )
|
|
||||||
{
|
|
||||||
l.append( Calamares::job_ptr( new TrackingMachineNeonJob() ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
QVariantMap
|
|
||||||
TrackingViewStep::setTrackingOption( const QVariantMap& configurationMap, const QString& key, TrackingType t )
|
|
||||||
{
|
|
||||||
bool settingEnabled = false;
|
|
||||||
|
|
||||||
bool success = false;
|
|
||||||
auto config = CalamaresUtils::getSubMap( configurationMap, key, success );
|
|
||||||
|
|
||||||
if ( success )
|
|
||||||
{
|
|
||||||
settingEnabled = CalamaresUtils::getBool( config, "enabled", false );
|
|
||||||
}
|
|
||||||
|
|
||||||
TrackingEnabled& trackingConfiguration = tracking( t );
|
|
||||||
trackingConfiguration.settingEnabled = settingEnabled;
|
|
||||||
trackingConfiguration.userEnabled = false;
|
|
||||||
|
|
||||||
m_widget->enableTrackingOption( t, settingEnabled );
|
|
||||||
m_widget->setTrackingPolicy( t, CalamaresUtils::getString( config, "policy" ) );
|
|
||||||
|
|
||||||
return config;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
TrackingViewStep::setConfigurationMap( const QVariantMap& configurationMap )
|
TrackingViewStep::setConfigurationMap( const QVariantMap& configurationMap )
|
||||||
{
|
{
|
||||||
QVariantMap config;
|
m_config->setConfigurationMap( configurationMap );
|
||||||
|
|
||||||
config = setTrackingOption( configurationMap, "install", TrackingType::InstallTracking );
|
|
||||||
m_installTrackingUrl = CalamaresUtils::getString( config, "url" );
|
|
||||||
|
|
||||||
config = setTrackingOption( configurationMap, "machine", TrackingType::MachineTracking );
|
|
||||||
auto s = CalamaresUtils::getString( config, "style" );
|
|
||||||
if ( isValidStyle( s ) )
|
|
||||||
{
|
|
||||||
m_machineTrackingStyle = s;
|
|
||||||
}
|
|
||||||
|
|
||||||
setTrackingOption( configurationMap, "user", TrackingType::UserTracking );
|
|
||||||
|
|
||||||
m_widget->setGeneralPolicy( CalamaresUtils::getString( configurationMap, "policy" ) );
|
|
||||||
m_widget->setTrackingLevel( CalamaresUtils::getString( configurationMap, "default" ) );
|
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
#include <QVariantMap>
|
#include <QVariantMap>
|
||||||
|
|
||||||
|
class Config;
|
||||||
class TrackingPage;
|
class TrackingPage;
|
||||||
|
|
||||||
class PLUGINDLLEXPORT TrackingViewStep : public Calamares::ViewStep
|
class PLUGINDLLEXPORT TrackingViewStep : public Calamares::ViewStep
|
||||||
@ -56,42 +57,8 @@ public:
|
|||||||
void setConfigurationMap( const QVariantMap& configurationMap ) override;
|
void setConfigurationMap( const QVariantMap& configurationMap ) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QVariantMap setTrackingOption( const QVariantMap& configurationMap, const QString& key, TrackingType t );
|
Config* m_config;
|
||||||
|
|
||||||
TrackingPage* m_widget;
|
TrackingPage* m_widget;
|
||||||
QString m_installTrackingUrl;
|
|
||||||
QString m_machineTrackingStyle;
|
|
||||||
|
|
||||||
struct TrackingEnabled
|
|
||||||
{
|
|
||||||
bool settingEnabled; // Enabled in config file
|
|
||||||
bool userEnabled; // User checked "yes"
|
|
||||||
|
|
||||||
TrackingEnabled()
|
|
||||||
: settingEnabled( false )
|
|
||||||
, userEnabled( false )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool enabled() const { return settingEnabled && userEnabled; }
|
|
||||||
};
|
|
||||||
TrackingEnabled m_installTracking, m_machineTracking, m_userTracking;
|
|
||||||
|
|
||||||
inline TrackingEnabled& tracking( TrackingType t )
|
|
||||||
{
|
|
||||||
if ( t == TrackingType::UserTracking )
|
|
||||||
{
|
|
||||||
return m_userTracking;
|
|
||||||
}
|
|
||||||
else if ( t == TrackingType::MachineTracking )
|
|
||||||
{
|
|
||||||
return m_machineTracking;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return m_installTracking;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
CALAMARES_PLUGIN_FACTORY_DECLARATION( TrackingViewStepFactory )
|
CALAMARES_PLUGIN_FACTORY_DECLARATION( TrackingViewStepFactory )
|
||||||
|
@ -32,7 +32,7 @@ margin-left: 2em;</string>
|
|||||||
<widget class="QWidget" name="noneGroup" native="true">
|
<widget class="QWidget" name="noneGroup" native="true">
|
||||||
<layout class="QHBoxLayout" name="noneLayout">
|
<layout class="QHBoxLayout" name="noneLayout">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QRadioButton" name="noneRadio">
|
<widget class="QCheckBox" name="noneCheckBox">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
@ -69,7 +69,7 @@ margin-left: 2em;</string>
|
|||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string><html><head/><body><p>By selecting this, you will send <span style=" font-weight:600;">no information at all</span> about your installation.</p></body></html></string>
|
<string><html><head/><body><p>Click here to send <span style=" font-weight:600;">no information at all</span> about your installation.</p></body></html></string>
|
||||||
</property>
|
</property>
|
||||||
<property name="wordWrap">
|
<property name="wordWrap">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
@ -83,7 +83,7 @@ margin-left: 2em;</string>
|
|||||||
<widget class="QWidget" name="installGroup" native="true">
|
<widget class="QWidget" name="installGroup" native="true">
|
||||||
<layout class="QHBoxLayout" name="installLayout">
|
<layout class="QHBoxLayout" name="installLayout">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QRadioButton" name="installRadio">
|
<widget class="QCheckBox" name="installCheckBox">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
@ -145,7 +145,7 @@ margin-left: 2em;</string>
|
|||||||
<widget class="QWidget" name="machineGroup" native="true">
|
<widget class="QWidget" name="machineGroup" native="true">
|
||||||
<layout class="QHBoxLayout" name="machineLayout">
|
<layout class="QHBoxLayout" name="machineLayout">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QRadioButton" name="machineRadio">
|
<widget class="QCheckBox" name="machineCheckBox">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
@ -207,7 +207,7 @@ margin-left: 2em;</string>
|
|||||||
<widget class="QWidget" name="userGroup" native="true">
|
<widget class="QWidget" name="userGroup" native="true">
|
||||||
<layout class="QHBoxLayout" name="userLayout">
|
<layout class="QHBoxLayout" name="userLayout">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QRadioButton" name="userRadio">
|
<widget class="QCheckBox" name="userCheckBox">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
@ -279,6 +279,9 @@ margin-left: 2em;</string>
|
|||||||
<property name="openExternalLinks">
|
<property name="openExternalLinks">
|
||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="textInteractionFlags">
|
||||||
|
<set>Qt::TextBrowserInteraction</set>
|
||||||
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
|
@ -28,14 +28,16 @@
|
|||||||
# policy applies.
|
# policy applies.
|
||||||
#
|
#
|
||||||
# Each area has a key *enabled*. If the area is enabled, it is shown to
|
# Each area has a key *enabled*. If the area is enabled, it is shown to
|
||||||
# the user. This defaults to off, which means no tracking would be
|
# the user. This defaults to false, which means no tracking would be
|
||||||
# configured or enabled by Calamares.
|
# configured or enabled by Calamares.
|
||||||
#
|
#
|
||||||
# Each area has a key *policy*, which is a Url to be opened when
|
# Each area has a key *policy*, which is a Url to be opened when
|
||||||
# the user clicks on the corresponding Help button for an explanation
|
# the user clicks on the corresponding Help button for an explanation
|
||||||
# of the details of that particular kind of tracking. If no policy
|
# of the details of that particular kind of tracking. If no policy
|
||||||
# is set, the help button is hidden. The example policy links
|
# is set, that tracking style is disabled. The example policy links
|
||||||
# go to Calamares' generic user manual.
|
# go to Calamares' generic user manual (which is a terrible idea
|
||||||
|
# for distro's: you have GDPR obligations under most of these tracking
|
||||||
|
# styles, so do your homework).
|
||||||
#
|
#
|
||||||
# Each area may have other configuration keys, depending on the
|
# Each area may have other configuration keys, depending on the
|
||||||
# area and how it needs to be configured.
|
# area and how it needs to be configured.
|
||||||
@ -48,13 +50,14 @@
|
|||||||
---
|
---
|
||||||
# This is the global policy; it is displayed as a link on the page.
|
# This is the global policy; it is displayed as a link on the page.
|
||||||
# If blank or commented out, no link is displayed on the tracking
|
# If blank or commented out, no link is displayed on the tracking
|
||||||
# page. It is recommended to either provide policy URLs for each
|
# page. You **must** provide policy links per-area as well.
|
||||||
# area, *or* one general link, and not to mix them.
|
|
||||||
policy: "https://github.com/calamares/calamares/wiki/Use-Guide#installation-tracking"
|
policy: "https://github.com/calamares/calamares/wiki/Use-Guide#installation-tracking"
|
||||||
|
|
||||||
# This is the default level to enable for tracking. If commented out,
|
# This is the default area to enable for tracking. If commented out,
|
||||||
# empty, or otherwise invalid, "none" is used, so no tracking by default.
|
# empty, or otherwise invalid, "none" is used, so no tracking by default.
|
||||||
default: user
|
# Setting an area here also checks the areas before it (install, machine,
|
||||||
|
# then user) by default -- subject to those areas being enabled at all.
|
||||||
|
# default: user
|
||||||
|
|
||||||
# The install area has one specific configuration key:
|
# The install area has one specific configuration key:
|
||||||
# url: this URL (remember to include the protocol, and prefer https)
|
# url: this URL (remember to include the protocol, and prefer https)
|
||||||
@ -72,17 +75,28 @@ default: user
|
|||||||
install:
|
install:
|
||||||
enabled: false
|
enabled: false
|
||||||
policy: "https://github.com/calamares/calamares/wiki/Use-Guide#installation-tracking"
|
policy: "https://github.com/calamares/calamares/wiki/Use-Guide#installation-tracking"
|
||||||
# url: "https://example.com/install.php?c=$CPU&m=$MEMORY"
|
url: "https://example.com/install.php?c=$CPU&m=$MEMORY"
|
||||||
|
|
||||||
# The machine area has one specific configuration key:
|
# The machine area has one specific configuration key:
|
||||||
# style: This string specifies what kind of tracking configuration
|
# style: This string specifies what kind of tracking configuration
|
||||||
# needs to be done. There is currently only one valid
|
# needs to be done. See below for valid styles.
|
||||||
# style, "neon", which edits two files in the installed
|
#
|
||||||
# system to enable system-tracking.
|
# Available styles:
|
||||||
|
# - *updatemanager* replaces the literal string "${MACHINE_ID}" with the contents of
|
||||||
|
# /etc/machine-id, in lines starting with "URI" in the file /etc/update-manager/meta-release
|
||||||
machine:
|
machine:
|
||||||
enabled: false
|
enabled: false
|
||||||
style: neon
|
style: updatemanager
|
||||||
|
policy: "https://github.com/calamares/calamares/wiki/Use-Guide#machine-tracking"
|
||||||
|
|
||||||
# The user area is not yet implemented, and has no specific configuration.
|
# The user area has one specific configuration key:
|
||||||
|
# style: This string specifies what kind of tracking configuration
|
||||||
|
# needs to be done. See below for valid styles.
|
||||||
|
#
|
||||||
|
# Available styles:
|
||||||
|
# - *kuserfeedback* sets up KUserFeedback tracking (applicable to the KDE
|
||||||
|
# Plasma Desktop) for each KUserFeedback area listed in *areas*.
|
||||||
user:
|
user:
|
||||||
enabled: false
|
enabled: false
|
||||||
|
style: kuserfeedback
|
||||||
|
areas: [ PlasmaUserFeedback ]
|
||||||
|
Loading…
Reference in New Issue
Block a user