summaryrefslogtreecommitdiffstats
path: root/src/libs
diff options
context:
space:
mode:
authorArttu Tarkiainen <arttu.tarkiainen@qt.io>2023-01-10 16:16:41 +0200
committerArttu Tarkiainen <arttu.tarkiainen@qt.io>2023-02-08 16:37:22 +0200
commit399c010235bdb9079005930e125f301f53153808 (patch)
treeaeb0bea9d6530930ccf60a6e26bab3652e8a5647 /src/libs
parent3ef3edd5206552dd037774594901780a4c817687 (diff)
Add common base class for the installer calculator classes
As the classes already share similar features and public API, it would make sense to inherit a common abstract class to define the interface. Change-Id: I7ed278b1b049b7ec12c4401e55fdf39306b0ab85 Reviewed-by: Katja Marttila <katja.marttila@qt.io>
Diffstat (limited to 'src/libs')
-rw-r--r--src/libs/installer/calculatorbase.cpp76
-rw-r--r--src/libs/installer/calculatorbase.h84
-rw-r--r--src/libs/installer/installer.pro2
-rw-r--r--src/libs/installer/installercalculator.cpp84
-rw-r--r--src/libs/installer/installercalculator.h40
-rw-r--r--src/libs/installer/packagemanagercore.cpp24
-rw-r--r--src/libs/installer/packagemanagercore_p.cpp14
-rw-r--r--src/libs/installer/uninstallercalculator.cpp85
-rw-r--r--src/libs/installer/uninstallercalculator.h36
9 files changed, 261 insertions, 184 deletions
diff --git a/src/libs/installer/calculatorbase.cpp b/src/libs/installer/calculatorbase.cpp
new file mode 100644
index 000000000..4f1732677
--- /dev/null
+++ b/src/libs/installer/calculatorbase.cpp
@@ -0,0 +1,76 @@
+/**************************************************************************
+**
+** Copyright (C) 2023 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Installer Framework.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+**************************************************************************/
+
+#include "calculatorbase.h"
+
+#include "component.h"
+
+namespace QInstaller {
+
+CalculatorBase::CalculatorBase(PackageManagerCore *core)
+ : m_core(core)
+{
+}
+
+CalculatorBase::~CalculatorBase()
+{
+}
+
+void CalculatorBase::insertResolution(Component *component, const Resolution resolutionType
+ , const QString &referencedComponent)
+{
+ // Keep the first reason
+ if (m_componentNameResolutionHash.contains(component->name()))
+ return;
+
+ m_componentNameResolutionHash.insert(component->name(),
+ QPair<Resolution, QString>(resolutionType, referencedComponent));
+}
+
+QList<Component *> CalculatorBase::resolvedComponents() const
+{
+ return m_resolvedComponents;
+}
+
+CalculatorBase::Resolution CalculatorBase::resolutionType(Component *component) const
+{
+ return m_componentNameResolutionHash.value(component->name()).first;
+}
+
+QString CalculatorBase::error() const
+{
+ return m_errorString;
+}
+
+QString CalculatorBase::referencedComponent(Component *component) const
+{
+ return m_componentNameResolutionHash.value(component->name()).second;
+}
+
+} // namespace QInstaller
+
diff --git a/src/libs/installer/calculatorbase.h b/src/libs/installer/calculatorbase.h
new file mode 100644
index 000000000..baf51c5b4
--- /dev/null
+++ b/src/libs/installer/calculatorbase.h
@@ -0,0 +1,84 @@
+/**************************************************************************
+**
+** Copyright (C) 2023 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt Installer Framework.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+**************************************************************************/
+
+#ifndef CALCULATORBASE_H
+#define CALCULATORBASE_H
+
+#include "installer_global.h"
+
+#include <QList>
+#include <QString>
+#include <QMetaEnum>
+
+namespace QInstaller {
+
+class Component;
+class PackageManagerCore;
+
+class INSTALLER_EXPORT CalculatorBase
+{
+public:
+ enum class Resolution {
+ Selected = 0, // "Selected Component(s) without Dependencies" / "Deselected Component(s)"
+ Replaced, // "Component(s) replaced by other components"
+ VirtualDependent, // "No dependencies to virtual component"
+ Dependent, // "Added as dependency for %1." / "Removed as dependency component is removed"
+ Automatic, // "Component(s) added as automatic dependencies" / "Removed as autodependency component is removed"
+ Resolved // "Component(s) that have resolved Dependencies"
+ };
+
+ CalculatorBase(PackageManagerCore *core);
+ virtual ~CalculatorBase() = 0;
+
+ virtual bool solve(const QList<Component *> &components) = 0;
+ void insertResolution(Component *component, const Resolution resolutionType,
+ const QString &referencedComponent = QString());
+
+ QList<Component *> resolvedComponents() const;
+ virtual QString resolutionText(Component *component) const = 0;
+ Resolution resolutionType(Component *component) const;
+
+ QString error() const;
+
+protected:
+ virtual bool solveComponent(Component *component, const QString &version = QString()) = 0;
+ QString referencedComponent(Component *component) const;
+
+protected:
+ PackageManagerCore *m_core;
+ QString m_errorString;
+
+ QList<Component *> m_resolvedComponents;
+ QHash<QString, QPair<Resolution, QString> > m_componentNameResolutionHash;
+};
+
+} // namespace QInstaller
+
+Q_DECLARE_METATYPE(QInstaller::CalculatorBase::Resolution)
+
+#endif // CALCULATORBASE_H
diff --git a/src/libs/installer/installer.pro b/src/libs/installer/installer.pro
index 0de80b064..5a58968ee 100644
--- a/src/libs/installer/installer.pro
+++ b/src/libs/installer/installer.pro
@@ -46,6 +46,7 @@ greaterThan(QT_MAJOR_VERSION, 5):QT += core5compat
HEADERS += packagemanagercore.h \
aspectratiolabel.h \
+ calculatorbase.h \
componentsortfilterproxymodel.h \
concurrentoperationrunner.h \
genericdatacache.h \
@@ -149,6 +150,7 @@ SOURCES += packagemanagercore.cpp \
abstractarchive.cpp \
archivefactory.cpp \
aspectratiolabel.cpp \
+ calculatorbase.cpp \
concurrentoperationrunner.cpp \
directoryguard.cpp \
fileguard.cpp \
diff --git a/src/libs/installer/installercalculator.cpp b/src/libs/installer/installercalculator.cpp
index 77989e3f8..105e99fd8 100644
--- a/src/libs/installer/installercalculator.cpp
+++ b/src/libs/installer/installercalculator.cpp
@@ -1,6 +1,6 @@
/**************************************************************************
**
-** Copyright (C) 2022 The Qt Company Ltd.
+** Copyright (C) 2023 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Installer Framework.
@@ -42,48 +42,38 @@ namespace QInstaller {
*/
InstallerCalculator::InstallerCalculator(PackageManagerCore *core, const AutoDependencyHash &autoDependencyComponentHash)
- : m_core(core)
+ : CalculatorBase(core)
, m_autoDependencyComponentHash(autoDependencyComponentHash)
{
}
-InstallerCalculator::InstallReasonType InstallerCalculator::installReasonType(const Component *c) const
+InstallerCalculator::~InstallerCalculator()
{
- return m_toInstallComponentIdReasonHash.value(c->name(),
- qMakePair(InstallerCalculator::Selected, QString())).first;
}
-QString InstallerCalculator::installReason(const Component *component) const
+QString InstallerCalculator::resolutionText(Component *component) const
{
- InstallerCalculator::InstallReasonType reason = installReasonType(component);
+ const Resolution reason = resolutionType(component);
switch (reason) {
- case Automatic:
+ case Resolution::Automatic:
return QCoreApplication::translate("InstallerCalculator",
"Components added as automatic dependencies:");
- case Dependent:
+ case Resolution::Dependent:
return QCoreApplication::translate("InstallerCalculator", "Components added as "
- "dependency for \"%1\":").arg(installReasonReferencedComponent(component));
- case Resolved:
+ "dependency for \"%1\":").arg(referencedComponent(component));
+ case Resolution::Resolved:
return QCoreApplication::translate("InstallerCalculator",
"Components that have resolved dependencies:");
- case Selected:
+ case Resolution::Selected:
return QCoreApplication::translate("InstallerCalculator",
"Selected components without dependencies:");
+ default:
+ Q_ASSERT_X(false, Q_FUNC_INFO, "Invalid install resolution detected!");
}
return QString();
}
-QList<Component*> InstallerCalculator::orderedComponentsToInstall() const
-{
- return m_orderedComponentsToInstall;
-}
-
-QString InstallerCalculator::componentsToInstallError() const
-{
- return m_componentsToInstallError;
-}
-
-bool InstallerCalculator::appendComponentsToInstall(const QList<Component *> &components)
+bool InstallerCalculator::solve(const QList<Component *> &components)
{
if (components.isEmpty())
return true;
@@ -95,54 +85,38 @@ bool InstallerCalculator::appendComponentsToInstall(const QList<Component *> &co
if (m_toInstallComponentIds.contains(component->name())) {
const QString errorMessage = recursionError(component);
qCWarning(QInstaller::lcInstallerInstallLog).noquote() << errorMessage;
- m_componentsToInstallError.append(errorMessage);
+ m_errorString.append(errorMessage);
Q_ASSERT_X(!m_toInstallComponentIds.contains(component->name()), Q_FUNC_INFO,
qPrintable(errorMessage));
return false;
}
if (component->currentDependencies().isEmpty())
- realAppendToInstallComponents(component);
+ addComponentForInstall(component);
else
notAppendedComponents.append(component);
}
for (Component *component : qAsConst(notAppendedComponents)) {
- if (!appendComponentToInstall(component))
+ if (!solveComponent(component))
return false;
}
// All regular dependencies are resolved. Now we are looking for auto depend on components.
QSet<Component *> foundAutoDependOnList = autodependencyComponents();
-
if (!foundAutoDependOnList.isEmpty())
- return appendComponentsToInstall(foundAutoDependOnList.values());
- return true;
-}
+ return solve(foundAutoDependOnList.values());
-QString InstallerCalculator::installReasonReferencedComponent(const Component *component) const
-{
- return m_toInstallComponentIdReasonHash.value(component->name(),
- qMakePair(InstallerCalculator::Selected, QString())).second;
-}
-
-void InstallerCalculator::insertInstallReason(Component *component,
- InstallReasonType installReason, const QString &referencedComponentName)
-{
- // keep the first reason
- if (m_toInstallComponentIdReasonHash.contains(component->name()))
- return;
- m_toInstallComponentIdReasonHash.insert(component->name(),
- qMakePair(installReason, referencedComponentName));
+ return true;
}
-void InstallerCalculator::realAppendToInstallComponents(Component *component, const QString &version)
+void InstallerCalculator::addComponentForInstall(Component *component, const QString &version)
{
if (!m_componentsForAutodepencencyCheck.contains(component))
m_componentsForAutodepencencyCheck.append(component);
if (!component->isInstalled(version) || (m_core->isUpdater() && component->isUpdateAvailable())) {
- m_orderedComponentsToInstall.append(component);
+ m_resolvedComponents.append(component);
m_toInstallComponentIds.insert(component->name());
}
}
@@ -150,10 +124,10 @@ void InstallerCalculator::realAppendToInstallComponents(Component *component, co
QString InstallerCalculator::recursionError(Component *component) const
{
return QCoreApplication::translate("InstallerCalculator", "Recursion detected, component \"%1\" "
- "already added with reason: \"%2\"").arg(component->name(), installReason(component));
+ "already added with reason: \"%2\"").arg(component->name(), resolutionText(component));
}
-bool InstallerCalculator::appendComponentToInstall(Component *component, const QString &version)
+bool InstallerCalculator::solveComponent(Component *component, const QString &version)
{
const QStringList dependenciesList = component->currentDependencies();
QString requiredDependencyVersion = version;
@@ -166,7 +140,7 @@ bool InstallerCalculator::appendComponentToInstall(Component *component, const Q
"Cannot find missing dependency \"%1\" for \"%2\".").arg(dependencyComponentName,
component->name());
qCWarning(QInstaller::lcInstallerInstallLog).noquote() << errorMessage;
- m_componentsToInstallError.append(errorMessage);
+ m_errorString.append(errorMessage);
if (component->packageManagerCore()->settings().allowUnstableComponents()) {
component->setUnstable(Component::UnstableError::MissingDependency, errorMessage);
continue;
@@ -204,24 +178,24 @@ bool InstallerCalculator::appendComponentToInstall(Component *component, const Q
if (m_visitedComponents.value(component).contains(dependencyComponent)) {
const QString errorMessage = recursionError(component);
qCWarning(QInstaller::lcInstallerInstallLog).noquote() << errorMessage;
- m_componentsToInstallError = errorMessage;
+ m_errorString = errorMessage;
Q_ASSERT_X(!m_visitedComponents.value(component).contains(dependencyComponent),
Q_FUNC_INFO, qPrintable(errorMessage));
return false;
}
m_visitedComponents[component].insert(dependencyComponent);
// add needed dependency components to the next run
- insertInstallReason(dependencyComponent, InstallerCalculator::Dependent,
+ insertResolution(dependencyComponent, Resolution::Dependent,
component->name());
- if (!appendComponentToInstall(dependencyComponent, requiredDependencyVersion))
+ if (!solveComponent(dependencyComponent, requiredDependencyVersion))
return false;
}
}
if (!m_toInstallComponentIds.contains(component->name())) {
- realAppendToInstallComponents(component, requiredDependencyVersion);
- insertInstallReason(component, InstallerCalculator::Resolved);
+ addComponentForInstall(component, requiredDependencyVersion);
+ insertResolution(component, Resolution::Resolved);
}
return true;
}
@@ -253,7 +227,7 @@ QSet<Component *> InstallerCalculator::autodependencyComponents()
// are other autodependencies as well
if (autoDependComponent->isAutoDependOn(m_toInstallComponentIds)) {
foundAutoDependOnList.insert(autoDependComponent);
- insertInstallReason(autoDependComponent, InstallerCalculator::Automatic);
+ insertResolution(autoDependComponent, Resolution::Automatic);
}
}
}
diff --git a/src/libs/installer/installercalculator.h b/src/libs/installer/installercalculator.h
index 422de439c..339dbeffd 100644
--- a/src/libs/installer/installercalculator.h
+++ b/src/libs/installer/installercalculator.h
@@ -1,6 +1,6 @@
/**************************************************************************
**
-** Copyright (C) 2022 The Qt Company Ltd.
+** Copyright (C) 2023 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Installer Framework.
@@ -30,6 +30,7 @@
#include "installer_global.h"
#include "qinstallerglobal.h"
+#include "calculatorbase.h"
#include <QHash>
#include <QList>
@@ -41,51 +42,30 @@ namespace QInstaller {
class Component;
class PackageManagerCore;
-class INSTALLER_EXPORT InstallerCalculator
+class INSTALLER_EXPORT InstallerCalculator : public CalculatorBase
{
public:
InstallerCalculator(PackageManagerCore *core, const AutoDependencyHash &autoDependencyComponentHash);
+ ~InstallerCalculator();
- enum InstallReasonType
- {
- Selected, // "Selected Component(s) without Dependencies"
- Automatic, // "Component(s) added as automatic dependencies"
- Dependent, // "Added as dependency for %1."
- Resolved // "Component(s) that have resolved Dependencies"
- };
-
- InstallReasonType installReasonType(const Component *component) const;
- QString installReason(const Component *component) const;
- QList<Component*> orderedComponentsToInstall() const;
- QString componentsToInstallError() const;
- bool appendComponentsToInstall(const QList<Component*> &components);
+ bool solve(const QList<Component *> &components) override;
+ QString resolutionText(Component *component) const override;
private:
- QString installReasonReferencedComponent(const Component *component) const;
- void insertInstallReason(Component *component,
- InstallReasonType installReasonType,
- const QString &referencedComponentName = QString());
- void realAppendToInstallComponents(Component *component, const QString &version = QString());
- bool appendComponentToInstall(Component *components, const QString &version = QString());
+ bool solveComponent(Component *component, const QString &version = QString()) override;
+
+ void addComponentForInstall(Component *component, const QString &version = QString());
QSet<Component *> autodependencyComponents();
QString recursionError(Component *component) const;
private:
- PackageManagerCore *m_core;
QHash<Component*, QSet<Component*> > m_visitedComponents;
QList<const Component*> m_componentsForAutodepencencyCheck;
QSet<QString> m_toInstallComponentIds; //for faster lookups
- QString m_componentsToInstallError;
- //calculate installation order variables
- QList<Component*> m_orderedComponentsToInstall;
- //we can't use this reason hash as component id hash, because some reasons are ready before
- //the component is added
- QHash<QString, QPair<InstallReasonType, QString> > m_toInstallComponentIdReasonHash;
//Helper hash for quicker search for autodependency components
AutoDependencyHash m_autoDependencyComponentHash;
};
-}
-
+} // namespace QInstaller
#endif // INSTALLERCALCULATOR_H
diff --git a/src/libs/installer/packagemanagercore.cpp b/src/libs/installer/packagemanagercore.cpp
index d5758438d..ebefafab6 100644
--- a/src/libs/installer/packagemanagercore.cpp
+++ b/src/libs/installer/packagemanagercore.cpp
@@ -2199,7 +2199,7 @@ bool PackageManagerCore::calculateComponentsToInstall() const
const QList<Component*> selectedComponentsToInstall = componentsMarkedForInstallation();
const bool componentsToInstallCalculated =
- d->installerCalculator()->appendComponentsToInstall(selectedComponentsToInstall);
+ d->installerCalculator()->solve(selectedComponentsToInstall);
emit finishedCalculateComponentsToInstall();
return componentsToInstallCalculated;
@@ -2210,7 +2210,7 @@ bool PackageManagerCore::calculateComponentsToInstall() const
*/
QList<Component*> PackageManagerCore::orderedComponentsToInstall() const
{
- return d->installerCalculator()->orderedComponentsToInstall();
+ return d->installerCalculator()->resolvedComponents();
}
/*!
@@ -2287,15 +2287,15 @@ bool PackageManagerCore::calculateComponentsToUninstall() const
emit aboutCalculateComponentsToUninstall();
d->clearUninstallerCalculator();
- const QList<Component *> componentsToInstallList = d->installerCalculator()->orderedComponentsToInstall();
+ const QList<Component *> componentsToInstallList = d->installerCalculator()->resolvedComponents();
QList<Component *> selectedComponentsToUninstall;
foreach (Component* component, components(PackageManagerCore::ComponentType::Replacements)) {
// Uninstall the component if replacement is selected for install or update
QPair<Component*, Component*> comp = d->componentsToReplace().value(component->name());
- if (comp.first && d->m_installerCalculator->orderedComponentsToInstall().contains(comp.first)) {
- d->uninstallerCalculator()->insertUninstallReason(component,
- UninstallerCalculator::Replaced, comp.first->name());
+ if (comp.first && d->m_installerCalculator->resolvedComponents().contains(comp.first)) {
+ d->uninstallerCalculator()->insertResolution(component,
+ CalculatorBase::Resolution::Replaced, comp.first->name());
selectedComponentsToUninstall.append(comp.second);
}
}
@@ -2304,7 +2304,7 @@ bool PackageManagerCore::calculateComponentsToUninstall() const
selectedComponentsToUninstall.append(component);
}
const bool componentsToUninstallCalculated =
- d->uninstallerCalculator()->appendComponentsToUninstall(selectedComponentsToUninstall);
+ d->uninstallerCalculator()->solve(selectedComponentsToUninstall);
emit finishedCalculateComponentsToUninstall();
return componentsToUninstallCalculated;
@@ -2319,7 +2319,7 @@ bool PackageManagerCore::calculateComponentsToUninstall() const
*/
QList<Component *> PackageManagerCore::componentsToUninstall() const
{
- return d->uninstallerCalculator()->componentsToUninstall().values();
+ return d->uninstallerCalculator()->resolvedComponents();
}
/*!
@@ -2327,7 +2327,7 @@ QList<Component *> PackageManagerCore::componentsToUninstall() const
*/
QString PackageManagerCore::componentsToInstallError() const
{
- return d->installerCalculator()->componentsToInstallError();
+ return d->installerCalculator()->error();
}
/*!
@@ -2335,7 +2335,7 @@ QString PackageManagerCore::componentsToInstallError() const
*/
QString PackageManagerCore::componentsToUninstallError() const
{
- return d->uninstallerCalculator()->componentsToUninstallError();
+ return d->uninstallerCalculator()->error();
}
/*!
@@ -2349,7 +2349,7 @@ QString PackageManagerCore::componentsToUninstallError() const
*/
QString PackageManagerCore::installReason(Component *component) const
{
- return d->installerCalculator()->installReason(component);
+ return d->installerCalculator()->resolutionText(component);
}
/*!
@@ -2365,7 +2365,7 @@ QString PackageManagerCore::installReason(Component *component) const
*/
QString PackageManagerCore::uninstallReason(Component *component) const
{
- return d->uninstallerCalculator()->uninstallReason(component);
+ return d->uninstallerCalculator()->resolutionText(component);
}
/*!
diff --git a/src/libs/installer/packagemanagercore_p.cpp b/src/libs/installer/packagemanagercore_p.cpp
index 7313a2761..a4e5b185d 100644
--- a/src/libs/installer/packagemanagercore_p.cpp
+++ b/src/libs/installer/packagemanagercore_p.cpp
@@ -401,10 +401,10 @@ bool PackageManagerCorePrivate::buildComponentTree(QHash<QString, Component*> &c
component->setCheckState(Qt::Checked);
clearInstallerCalculator();
- if (installerCalculator()->appendComponentsToInstall(components.values()) == false) {
- setStatus(PackageManagerCore::Failure, installerCalculator()->componentsToInstallError());
+ if (installerCalculator()->solve(components.values()) == false) {
+ setStatus(PackageManagerCore::Failure, installerCalculator()->error());
MessageBoxHandler::critical(MessageBoxHandler::currentBestSuitParent(), QLatin1String("Error"),
- tr("Unresolved dependencies"), installerCalculator()->componentsToInstallError());
+ tr("Unresolved dependencies"), installerCalculator()->error());
return false;
}
@@ -1932,7 +1932,7 @@ bool PackageManagerCorePrivate::runPackageUpdater()
// There is a replacement, but the replacement is not scheduled for update, keep it as well.
if (m_componentsToReplaceUpdaterMode.contains(name)
- && !m_installerCalculator->orderedComponentsToInstall().contains(m_componentsToReplaceUpdaterMode.value(name).first)) {
+ && !m_installerCalculator->resolvedComponents().contains(m_componentsToReplaceUpdaterMode.value(name).first)) {
nonRevertedOperations.append(operation);
continue;
}
@@ -2935,9 +2935,9 @@ void PackageManagerCorePrivate::updateComponentCheckedState()
? ComponentModelHelper::KeepInstalled
: ComponentModelHelper::KeepUninstalled);
}
- for (Component *component : uninstallerCalculator()->componentsToUninstall())
+ for (Component *component : uninstallerCalculator()->resolvedComponents())
component->setInstallAction(ComponentModelHelper::Uninstall);
- for (Component *component : installerCalculator()->orderedComponentsToInstall())
+ for (Component *component : installerCalculator()->resolvedComponents())
component->setInstallAction(ComponentModelHelper::Install);
}
@@ -3062,7 +3062,7 @@ bool PackageManagerCorePrivate::calculateComponentsAndRun()
qCDebug(QInstaller::lcInstallerInstallLog) << "Installation canceled.";
} else if (componentsOk && acceptLicenseAgreements()) {
try {
- loadComponentScripts(installerCalculator()->orderedComponentsToInstall(), true);
+ loadComponentScripts(installerCalculator()->resolvedComponents(), true);
} catch (const Error &error) {
qCWarning(QInstaller::lcInstallerInstallLog) << error.message();
return false;
diff --git a/src/libs/installer/uninstallercalculator.cpp b/src/libs/installer/uninstallercalculator.cpp
index ebfc52efe..de753f71a 100644
--- a/src/libs/installer/uninstallercalculator.cpp
+++ b/src/libs/installer/uninstallercalculator.cpp
@@ -44,25 +44,21 @@ UninstallerCalculator::UninstallerCalculator(PackageManagerCore *core
, const AutoDependencyHash &autoDependencyComponentHash
, const LocalDependencyHash &localDependencyComponentHash
, const QStringList &localVirtualComponents)
- : m_core(core)
+ : CalculatorBase(core)
, m_autoDependencyComponentHash(autoDependencyComponentHash)
, m_localDependencyComponentHash(localDependencyComponentHash)
, m_localVirtualComponents(localVirtualComponents)
{
}
-QSet<Component *> UninstallerCalculator::componentsToUninstall() const
+UninstallerCalculator::~UninstallerCalculator()
{
- return m_componentsToUninstall;
}
-QString UninstallerCalculator::componentsToUninstallError() const
+bool UninstallerCalculator::solveComponent(Component *component, const QString &version)
{
- return m_componentsToUninstallError;
-}
+ Q_UNUSED(version)
-bool UninstallerCalculator::appendComponentToUninstall(Component *component)
-{
if (!component)
return true;
@@ -76,7 +72,7 @@ bool UninstallerCalculator::appendComponentToUninstall(Component *component)
if (!depComponent || !depComponent->isInstalled())
continue;
- if (m_componentsToUninstall.contains(depComponent)
+ if (m_resolvedComponents.contains(depComponent)
|| m_core->orderedComponentsToInstall().contains(depComponent)) {
// Component is already selected for uninstall or update
continue;
@@ -86,28 +82,28 @@ bool UninstallerCalculator::appendComponentToUninstall(Component *component)
const QString errorMessage = QCoreApplication::translate("InstallerCalculator",
"Impossible dependency resolution detected. Forced install component \"%1\" would be uninstalled "
"because its dependency \"%2\" is marked for uninstallation with reason: \"%3\".")
- .arg(depComponent->name(), component->name(), uninstallReason(component));
+ .arg(depComponent->name(), component->name(), resolutionText(component));
qCWarning(QInstaller::lcInstallerInstallLog).noquote() << errorMessage;
- m_componentsToUninstallError.append(errorMessage);
+ m_errorString.append(errorMessage);
return false;
}
// Resolve also all cascading dependencies
- if (!appendComponentToUninstall(depComponent))
+ if (!solveComponent(depComponent))
return false;
- insertUninstallReason(depComponent, UninstallerCalculator::Dependent, component->name());
+ insertResolution(depComponent, Resolution::Dependent, component->name());
}
}
- m_componentsToUninstall.insert(component);
+ m_resolvedComponents.append(component);
return true;
}
-bool UninstallerCalculator::appendComponentsToUninstall(const QList<Component*> &components)
+bool UninstallerCalculator::solve(const QList<Component*> &components)
{
foreach (Component *component, components) {
- if (!appendComponentToUninstall(component))
+ if (!solveComponent(component))
return false;
}
@@ -122,8 +118,8 @@ bool UninstallerCalculator::appendComponentsToUninstall(const QList<Component*>
Component *autoDepComponent = m_core->componentByName(autoDependencyComponent);
if (autoDepComponent && autoDepComponent->isInstalled()) {
// A component requested auto uninstallation, keep it to resolve their dependencies as well.
- if (!m_componentsToUninstall.contains(autoDepComponent)) {
- insertUninstallReason(autoDepComponent, UninstallerCalculator::AutoDependent, component->name());
+ if (!m_resolvedComponents.contains(autoDepComponent)) {
+ insertResolution(autoDepComponent, Resolution::Automatic, component->name());
autoDepComponent->setInstallAction(ComponentModelHelper::AutodependUninstallation);
autoDependOnList.append(autoDepComponent);
}
@@ -132,56 +128,38 @@ bool UninstallerCalculator::appendComponentsToUninstall(const QList<Component*>
}
if (!autoDependOnList.isEmpty())
- appendComponentsToUninstall(autoDependOnList);
+ solve(autoDependOnList);
else
appendVirtualComponentsToUninstall();
return true;
}
-void UninstallerCalculator::insertUninstallReason(Component *component, const UninstallReasonType uninstallReason,
- const QString &referencedComponentName)
-{
- // keep the first reason
- if (m_toUninstallComponentIdReasonHash.contains(component->name()))
- return;
- m_toUninstallComponentIdReasonHash.insert(component->name(),
- qMakePair(uninstallReason, referencedComponentName));
-}
-
-QString UninstallerCalculator::uninstallReason(Component *component) const
+QString UninstallerCalculator::resolutionText(Component *component) const
{
- UninstallerCalculator::UninstallReasonType reason = uninstallReasonType(component);
+ Resolution reason = resolutionType(component);
switch (reason) {
- case Selected:
+ case Resolution::Selected:
return QCoreApplication::translate("UninstallerCalculator",
"Deselected Components:");
- case Replaced:
+ case Resolution::Replaced:
return QCoreApplication::translate("UninstallerCalculator", "Components replaced "
- "by \"%1\":").arg(uninstallReasonReferencedComponent(component));
- case VirtualDependent:
+ "by \"%1\":").arg(referencedComponent(component));
+ case Resolution::VirtualDependent:
return QCoreApplication::translate("UninstallerCalculator",
"Removing virtual components without existing dependencies:");
- case Dependent:
+ case Resolution::Dependent:
return QCoreApplication::translate("UninstallerCalculator", "Components "
- "dependency \"%1\" removed:").arg(uninstallReasonReferencedComponent(component));
- case AutoDependent:
+ "dependency \"%1\" removed:").arg(referencedComponent(component));
+ case Resolution::Automatic:
return QCoreApplication::translate("UninstallerCalculator", "Components "
- "autodependency \"%1\" removed:").arg(uninstallReasonReferencedComponent(component));
+ "autodependency \"%1\" removed:").arg(referencedComponent(component));
+ default:
+ Q_ASSERT_X(false, Q_FUNC_INFO, "Invalid uninstall resolution detected!");
}
return QString();
}
-UninstallerCalculator::UninstallReasonType UninstallerCalculator::uninstallReasonType(Component *c) const
-{
- return m_toUninstallComponentIdReasonHash.value(c->name()).first;
-}
-
-QString UninstallerCalculator::uninstallReasonReferencedComponent(Component *component) const
-{
- return m_toUninstallComponentIdReasonHash.value(component->name()).second;
-}
-
void UninstallerCalculator::appendVirtualComponentsToUninstall()
{
QList<Component*> unneededVirtualList;
@@ -191,20 +169,20 @@ void UninstallerCalculator::appendVirtualComponentsToUninstall()
if (!virtualComponent)
continue;
- if (virtualComponent->isInstalled() && !m_componentsToUninstall.contains(virtualComponent)) {
+ if (virtualComponent->isInstalled() && !m_resolvedComponents.contains(virtualComponent)) {
// Components with auto dependencies were handled in the previous step
if (!virtualComponent->autoDependencies().isEmpty() || virtualComponent->forcedInstallation())
continue;
if (!isRequiredVirtualPackage(virtualComponent)) {
unneededVirtualList.append(virtualComponent);
- insertUninstallReason(virtualComponent, UninstallerCalculator::VirtualDependent);
+ insertResolution(virtualComponent, Resolution::VirtualDependent);
}
}
}
if (!unneededVirtualList.isEmpty())
- appendComponentsToUninstall(unneededVirtualList);
+ solve(unneededVirtualList);
}
bool UninstallerCalculator::isRequiredVirtualPackage(Component *component)
@@ -212,10 +190,11 @@ bool UninstallerCalculator::isRequiredVirtualPackage(Component *component)
const QStringList localInstallDependents = m_core->localDependenciesToComponent(component);
for (const QString &dependent : localInstallDependents) {
Component *comp = m_core->componentByName(dependent);
- if (!m_componentsToUninstall.contains(comp)) {
+ if (!m_resolvedComponents.contains(comp)) {
return true;
}
}
return m_core->isDependencyForRequestedComponent(component);
}
+
} // namespace QInstaller
diff --git a/src/libs/installer/uninstallercalculator.h b/src/libs/installer/uninstallercalculator.h
index b764042aa..24979a9bb 100644
--- a/src/libs/installer/uninstallercalculator.h
+++ b/src/libs/installer/uninstallercalculator.h
@@ -30,6 +30,7 @@
#include "installer_global.h"
#include "qinstallerglobal.h"
+#include "calculatorbase.h"
#include <QHash>
#include <QList>
@@ -41,49 +42,30 @@ namespace QInstaller {
class Component;
class PackageManagerCore;
-class INSTALLER_EXPORT UninstallerCalculator
+class INSTALLER_EXPORT UninstallerCalculator : public CalculatorBase
{
public:
- enum UninstallReasonType
- {
- Selected, // "Deselected Component(s)"
- Replaced, // "Component(s) replaced by other components"
- VirtualDependent, // "No dependencies to virtual component"
- Dependent, // "Removed as dependency component is removed"
- AutoDependent // "Removed as autodependency component is removed"
- };
-
UninstallerCalculator(PackageManagerCore *core,
const AutoDependencyHash &autoDependencyComponentHash,
const LocalDependencyHash &localDependencyComponentHash,
const QStringList &localVirtualComponents);
+ ~UninstallerCalculator();
- QSet<Component*> componentsToUninstall() const;
- QString componentsToUninstallError() const;
-
- bool appendComponentsToUninstall(const QList<Component*> &components);
- void insertUninstallReason(Component *component,
- const UninstallReasonType uninstallReason,
- const QString &referencedComponentName = QString());
- QString uninstallReason(Component *component) const;
- UninstallerCalculator::UninstallReasonType uninstallReasonType(Component *c) const;
+ bool solve(const QList<Component*> &components) override;
+ QString resolutionText(Component *component) const override;
private:
- QString uninstallReasonReferencedComponent(Component *component) const;
+ bool solveComponent(Component *component, const QString &version = QString()) override;
+
bool isRequiredVirtualPackage(Component *component);
- bool appendComponentToUninstall(Component *component);
void appendVirtualComponentsToUninstall();
- QString m_componentsToUninstallError;
- QSet<Component *> m_componentsToUninstall;
- PackageManagerCore *m_core;
- QHash<QString, QPair<UninstallReasonType, QString> > m_toUninstallComponentIdReasonHash;
+private:
AutoDependencyHash m_autoDependencyComponentHash;
LocalDependencyHash m_localDependencyComponentHash;
QStringList m_localVirtualComponents;
};
-}
-
+} // namespace QInstaller
#endif // UNINSTALLERCALCULATOR_H