summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKatja Marttila <katja.marttila@qt.io>2022-11-28 13:30:21 +0200
committerKatja Marttila <katja.marttila@qt.io>2022-11-30 15:03:46 +0200
commit51e02b08abb44131929dba2d86860d10ca17cf41 (patch)
treec74ea513a2385f430c8a2491fcdebf08e39c2937
parentf02c3a2f2a6a5db84a947ca6d4f4ab5f5d867d41 (diff)
Cleanup installer calculator classes
As there are several optimizations done, the single click of component in component selection tree is not slow anymore. Cleaning the code so it is easier to maintain. Basically this revers commit a28cf55b5a5007c0dd952b3012c076d9da329f0f but as there are bug fixes made after that so pure revert could not be done. Task-number: QTIFW-2885 Change-Id: Id486d5dc68c42c31b4848cd19a1761bcfe242db6 Reviewed-by: Arttu Tarkiainen <arttu.tarkiainen@qt.io>
-rw-r--r--src/libs/installer/componentmodel.cpp38
-rw-r--r--src/libs/installer/componentmodel.h7
-rw-r--r--src/libs/installer/componentselectionpage_p.cpp14
-rw-r--r--src/libs/installer/installercalculator.cpp201
-rw-r--r--src/libs/installer/installercalculator.h27
-rw-r--r--src/libs/installer/packagemanagercore.cpp66
-rw-r--r--src/libs/installer/packagemanagercore.h1
-rw-r--r--src/libs/installer/packagemanagercore_p.cpp17
-rw-r--r--src/libs/installer/packagemanagercore_p.h1
-rw-r--r--src/libs/installer/uninstallercalculator.cpp83
-rw-r--r--src/libs/installer/uninstallercalculator.h14
-rw-r--r--tests/auto/installer/solver/tst_solver.cpp6
12 files changed, 128 insertions, 347 deletions
diff --git a/src/libs/installer/componentmodel.cpp b/src/libs/installer/componentmodel.cpp
index e60ba92ae..ef662b309 100644
--- a/src/libs/installer/componentmodel.cpp
+++ b/src/libs/installer/componentmodel.cpp
@@ -58,14 +58,7 @@ namespace QInstaller {
*/
/*!
- \fn void QInstaller::ComponentModel::componentsCheckStateChanged(const QList<QModelIndex> &indexes)
-
- This signal is emitted whenever the checked state of components are changed. The \a indexes value
- indicates the QModelIndexes representation of the components as seen from the model.
-*/
-
-/*!
- \fn void QInstaller::ComponentModel::modelCheckStateChanged(QInstaller::ComponentModel::ModelState state)
+ \fn void QInstaller::ComponentModel::checkStateChanged(QInstaller::ComponentModel::ModelState state)
This signal is emitted whenever the checked state of a model is changed after all state
calculations have taken place. The \a state is a combination of \c ModelStateFlag values
@@ -238,7 +231,6 @@ QVariant ComponentModel::data(const QModelIndex &index, int role) const
/*!
Sets the \a role data for the item at \a index to \a value. Returns true if successful;
otherwise returns false. The dataChanged() signal is emitted if the data was successfully set.
- The componentsCheckStateChanged() signal is emitted in addition if the checked state of the item is set.
*/
bool ComponentModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
@@ -260,13 +252,10 @@ bool ComponentModel::setData(const QModelIndex &index, const QVariant &value, in
const Qt::CheckState oldValue = component->checkState();
newValue = (oldValue == Qt::Checked) ? Qt::Unchecked : Qt::Checked;
}
- const QList<QModelIndex> changed = updateCheckedState(nodes << component, newValue);
- foreach (const QModelIndex &changedIndex, changed) {
+ const QSet<QModelIndex> changed = updateCheckedState(nodes << component, newValue);
+ foreach (const QModelIndex &changedIndex, changed)
emit dataChanged(changedIndex, changedIndex);
- }
- updateModelState();
- if (changed.count() > 0)
- emit componentsCheckStateChanged(changed);
+ updateAndEmitModelState(); // update the internal state
} else {
component->setData(value, role);
emit dataChanged(index, index);
@@ -446,8 +435,7 @@ void ComponentModel::setCheckedState(QInstaller::ComponentModel::ModelStateFlag
default:
break;
}
- updateModelState();
- emit modelCheckStateChanged(m_modelState);
+ updateAndEmitModelState(); // update the internal state
}
@@ -485,11 +473,10 @@ void ComponentModel::postModelReset()
}
m_currentCheckedState = m_initialCheckedState;
- updateModelState(); // update the internal state
- emit modelCheckStateChanged(m_modelState);
+ updateAndEmitModelState(); // update the internal state
}
-void ComponentModel::updateModelState()
+void ComponentModel::updateAndEmitModelState()
{
m_modelState = ComponentModel::DefaultChecked;
if (m_initialCheckedState != m_currentCheckedState)
@@ -504,6 +491,8 @@ void ComponentModel::updateModelState()
m_modelState |= ComponentModel::AllChecked;
m_modelState &= ~ComponentModel::PartiallyChecked;
}
+
+ emit checkStateChanged(m_modelState);
}
void ComponentModel::collectComponents(Component *const component, const QModelIndex &parent) const
@@ -547,7 +536,7 @@ static Qt::CheckState verifyPartiallyChecked(Component *component)
} // namespace ComponentModelPrivate
-QList<QModelIndex> ComponentModel::updateCheckedState(const ComponentSet &components, const Qt::CheckState state)
+QSet<QModelIndex> ComponentModel::updateCheckedState(const ComponentSet &components, const Qt::CheckState state)
{
// get all parent nodes for the components we're going to update
QMultiMap<QString, Component *> sortedNodesMap;
@@ -558,7 +547,7 @@ QList<QModelIndex> ComponentModel::updateCheckedState(const ComponentSet &compon
}
}
- QList<QModelIndex> changed;
+ QSet<QModelIndex> changed;
const ComponentList sortedNodes = sortedNodesMap.values();
// we can start in descending order to check node and tri-state nodes properly
for (int i = sortedNodes.count(); i > 0; i--) {
@@ -580,10 +569,7 @@ QList<QModelIndex> ComponentModel::updateCheckedState(const ComponentSet &compon
continue;
node->setCheckState(newState);
- QModelIndex index = indexFromComponentName(node->treeName());
- //Prepend to the list so that install order is correct (parent first)
- if (!changed.contains(index))
- changed.prepend(indexFromComponentName(node->treeName()));
+ changed.insert(indexFromComponentName(node->treeName()));
m_currentCheckedState[Qt::Checked].remove(node);
m_currentCheckedState[Qt::Unchecked].remove(node);
diff --git a/src/libs/installer/componentmodel.h b/src/libs/installer/componentmodel.h
index f9fbae47a..26cd888a3 100644
--- a/src/libs/installer/componentmodel.h
+++ b/src/libs/installer/componentmodel.h
@@ -90,17 +90,16 @@ public Q_SLOTS:
void setCheckedState(QInstaller::ComponentModel::ModelStateFlag state);
Q_SIGNALS:
- void componentsCheckStateChanged(const QList<QModelIndex> &indexes);
- void modelCheckStateChanged(QInstaller::ComponentModel::ModelState state);
+ void checkStateChanged(QInstaller::ComponentModel::ModelState state);
private Q_SLOTS:
void onVirtualStateChanged();
private:
void postModelReset();
- void updateModelState();
+ void updateAndEmitModelState();
void collectComponents(Component *const component, const QModelIndex &parent) const;
- QList<QModelIndex> updateCheckedState(const ComponentSet &components, const Qt::CheckState state);
+ QSet<QModelIndex> updateCheckedState(const ComponentSet &components, const Qt::CheckState state);
private:
PackageManagerCore *m_core;
diff --git a/src/libs/installer/componentselectionpage_p.cpp b/src/libs/installer/componentselectionpage_p.cpp
index 0dcdc2de9..292b28e67 100644
--- a/src/libs/installer/componentselectionpage_p.cpp
+++ b/src/libs/installer/componentselectionpage_p.cpp
@@ -185,16 +185,10 @@ ComponentSelectionPagePrivate::ComponentSelectionPagePrivate(ComponentSelectionP
m_stackedLayout->addWidget(progressStackedWidget);
m_stackedLayout->setCurrentIndex(0);
- connect(m_allModel, &ComponentModel::modelCheckStateChanged,
- this, &ComponentSelectionPagePrivate::onModelStateChanged);
- connect(m_updaterModel, &ComponentModel::modelCheckStateChanged,
- this, &ComponentSelectionPagePrivate::onModelStateChanged);
-
- connect(m_allModel, &ComponentModel::componentsCheckStateChanged, this,
- [=]() { onModelStateChanged(m_allModel->checkedState());});
-
- connect(m_updaterModel, &ComponentModel::componentsCheckStateChanged, this,
- [=]() { onModelStateChanged(m_allModel->checkedState());});
+ connect(m_allModel, &ComponentModel::checkStateChanged,
+ this, &ComponentSelectionPagePrivate::onModelStateChanged);
+ connect(m_updaterModel, &ComponentModel::checkStateChanged,
+ this, &ComponentSelectionPagePrivate::onModelStateChanged);
connect(m_core, SIGNAL(metaJobProgress(int)), this, SLOT(onProgressChanged(int)));
connect(m_core, SIGNAL(metaJobInfoMessage(QString)), this, SLOT(setMessage(QString)));
diff --git a/src/libs/installer/installercalculator.cpp b/src/libs/installer/installercalculator.cpp
index 48c90621b..4eb65f1ad 100644
--- a/src/libs/installer/installercalculator.cpp
+++ b/src/libs/installer/installercalculator.cpp
@@ -49,7 +49,8 @@ InstallerCalculator::InstallerCalculator(PackageManagerCore *core, const AutoDep
InstallerCalculator::InstallReasonType InstallerCalculator::installReasonType(const Component *c) const
{
- return m_toInstallComponentIdReasonHash.value(c->name()).first;
+ return m_toInstallComponentIdReasonHash.value(c->name(),
+ qMakePair(InstallerCalculator::Selected, QString())).first;
}
QString InstallerCalculator::installReason(const Component *component) const
@@ -82,103 +83,77 @@ QString InstallerCalculator::componentsToInstallError() const
return m_componentsToInstallError;
}
-bool InstallerCalculator::appendComponentsToInstall(const QList<Component *> &components, bool modelReset, const bool revertFromInstall)
+bool InstallerCalculator::appendComponentsToInstall(const QList<Component *> &components)
{
if (components.isEmpty())
return true;
QList<Component*> notAppendedComponents; // for example components with unresolved dependencies
- foreach (Component *component, components) {
+ for (Component *component : qAsConst(components)){
if (!component)
continue;
- // When model has been reseted, there should not be components with the same name
if (m_toInstallComponentIds.contains(component->name())) {
- if (modelReset) {
- const QString errorMessage = recursionError(component);
- qCWarning(QInstaller::lcInstallerInstallLog).noquote() << errorMessage;
- m_componentsToInstallError.append(errorMessage);
- Q_ASSERT_X(!m_toInstallComponentIds.contains(component->name()), Q_FUNC_INFO,
- qPrintable(errorMessage));
- return false;
- }
- if (!revertFromInstall && !modelReset) {
- // We can end up here if component is already added as dependency and
- // user explicitly selects it to install. Increase the references to
- // know when the component should be removed from install
- const QStringList dependenciesList = component->currentDependencies();
- for (const QString &dependencyComponentName : dependenciesList)
- calculateComponentDependencyReferences(dependencyComponentName, component);
- continue;
- }
+ const QString errorMessage = recursionError(component);
+ qCWarning(QInstaller::lcInstallerInstallLog).noquote() << errorMessage;
+ m_componentsToInstallError.append(errorMessage);
+ Q_ASSERT_X(!m_toInstallComponentIds.contains(component->name()), Q_FUNC_INFO,
+ qPrintable(errorMessage));
+ return false;
}
if (component->currentDependencies().isEmpty())
- realAppendToInstallComponents(component, QString(), revertFromInstall);
+ realAppendToInstallComponents(component);
else
notAppendedComponents.append(component);
}
- foreach (Component *component, notAppendedComponents) {
- if (!appendComponentToInstall(component, QString(), revertFromInstall))
+ for (Component *component : qAsConst(notAppendedComponents)) {
+ if (!appendComponentToInstall(component))
return false;
}
// All regular dependencies are resolved. Now we are looking for auto depend on components.
- QSet<Component *> foundAutoDependOnList = autodependencyComponents(revertFromInstall);
+ QSet<Component *> foundAutoDependOnList = autodependencyComponents();
if (!foundAutoDependOnList.isEmpty())
- return appendComponentsToInstall(foundAutoDependOnList.values(), modelReset, revertFromInstall);
-
+ return appendComponentsToInstall(foundAutoDependOnList.values());
return true;
}
-bool InstallerCalculator::removeComponentsFromInstall(const QList<Component *> &components)
-{
- return appendComponentsToInstall(components, false, true);
-}
-
QString InstallerCalculator::installReasonReferencedComponent(const Component *component) const
{
- const QString componentName = component->name();
- if (m_referenceCount.contains(componentName))
- return m_referenceCount.value(componentName).first();
- return m_toInstallComponentIdReasonHash.value(componentName,
- qMakePair(InstallerCalculator::Selected, QString())).second;
+ return m_toInstallComponentIdReasonHash.value(component->name(),
+ qMakePair(InstallerCalculator::Selected, QString())).second;
}
-void InstallerCalculator::insertInstallReason(const Component *component,
- const InstallReasonType installReason, const QString &referencedComponentName, const bool revertFromInstall)
+void InstallerCalculator::insertInstallReason(Component *component,
+ InstallReasonType installReason, const QString &referencedComponentName)
{
- if (revertFromInstall && m_toInstallComponentIdReasonHash.contains(component->name())) {
- m_toInstallComponentIdReasonHash.remove(component->name());
- } else if (!m_toInstallComponentIdReasonHash.contains(component->name())) {
- m_toInstallComponentIdReasonHash.insert(component->name(),
- qMakePair(installReason, referencedComponentName));
- }
+ // keep the first reason
+ if (m_toInstallComponentIdReasonHash.contains(component->name()))
+ return;
+ m_toInstallComponentIdReasonHash.insert(component->name(),
+ qMakePair(installReason, referencedComponentName));
}
-void InstallerCalculator::realAppendToInstallComponents(Component *component, const QString &version, const bool revertFromInstall)
+void InstallerCalculator::realAppendToInstallComponents(Component *component, const QString &version)
{
if (!m_componentsForAutodepencencyCheck.contains(component))
m_componentsForAutodepencencyCheck.append(component);
- if (revertFromInstall) {
- if (m_toInstallComponentIds.contains(component->name())) {
- // Component is no longer added as dependency and is not explicitly selected for install by user
- if (m_referenceCount.value(component->name()).isEmpty() && !component->isSelected()) {
- m_toInstallComponentIds.remove(component->name());
- m_orderedComponentsToInstall.removeAll(component);
- }
- }
- } else {
- if (!component->isInstalled(version)
- || (m_core->isUpdater() && component->isUpdateAvailable())) {
- m_toInstallComponentIds.insert(component->name());
- m_orderedComponentsToInstall.append(component);
- }
+
+ if (!component->isInstalled(version) || (m_core->isUpdater() && component->isUpdateAvailable())) {
+ m_orderedComponentsToInstall.append(component);
+ m_toInstallComponentIds.insert(component->name());
}
}
-bool InstallerCalculator::appendComponentToInstall(Component *component, const QString &version, bool revertFromInstall)
+QString InstallerCalculator::recursionError(Component *component) const
+{
+ return QCoreApplication::translate("InstallerCalculator", "Recursion detected, component \"%1\" "
+ "already added with reason: \"%2\"").arg(component->name(), installReason(component));
+}
+
+bool InstallerCalculator::appendComponentToInstall(Component *component, const QString &version)
{
const QStringList dependenciesList = component->currentDependencies();
QString requiredDependencyVersion = version;
@@ -199,8 +174,6 @@ bool InstallerCalculator::appendComponentToInstall(Component *component, const Q
return false;
}
}
- if (revertFromInstall && dependencyComponent->forcedInstallation())
- continue;
//Check if component requires higher version than what might be already installed
bool isUpdateRequired = false;
QString requiredName;
@@ -219,72 +192,39 @@ bool InstallerCalculator::appendComponentToInstall(Component *component, const Q
requiredDependencyVersion = requiredVersion;
}
}
-
- // Component can be requested for install by several component (as a dependency).
- // Keep the reference count to a dependency component, so we know when component
- // needs to be removed from install. Do not increase the reference count when
- // the dependency is also autodependency as the component is removed anyway only
- // when there are no references to the dependency.
- if (revertFromInstall) {
- if (m_toInstallComponentIds.contains(dependencyComponentName)
- && m_referenceCount.contains(dependencyComponentName)) {
- if (!component->autoDependencies().contains(dependencyComponentName)) {
- QStringList &value = m_referenceCount[dependencyComponentName];
- if (value.contains(component->name())) {
- value.removeOne(component->name());
- if (value.isEmpty())
- m_referenceCount.remove(dependencyComponentName);
- }
- }
- }
- insertInstallReason(dependencyComponent, InstallerCalculator::Dependent,
- component->name(), true);
- if (!appendComponentToInstall(dependencyComponent, requiredDependencyVersion, revertFromInstall))
+ //Check dependencies only if
+ //- Dependency is not installed or update requested, nor newer version of dependency component required
+ //- And dependency component is not already added for install
+ //- And component is not already added for install, then dependencies are already resolved
+ if (((!dependencyComponent->isInstalled() || dependencyComponent->updateRequested())
+ || isUpdateRequired) && (!m_toInstallComponentIds.contains(dependencyComponent->name())
+ && !m_toInstallComponentIds.contains(component->name()))) {
+ if (m_visitedComponents.value(component).contains(dependencyComponent)) {
+ const QString errorMessage = recursionError(component);
+ qCWarning(QInstaller::lcInstallerInstallLog).noquote() << errorMessage;
+ m_componentsToInstallError = errorMessage;
+ Q_ASSERT_X(!m_visitedComponents.value(component).contains(dependencyComponent),
+ Q_FUNC_INFO, qPrintable(errorMessage));
return false;
- m_visitedComponents.remove(component);
- } else {
- //Check dependencies only if
- //- Dependency is not installed or update requested, nor newer version of dependency component required
- //- And dependency component is not already added for install
- //- And component is not already added for install, then dependencies are already resolved
- if (((!dependencyComponent->isInstalled() || dependencyComponent->updateRequested())
- || isUpdateRequired) && (!m_toInstallComponentIds.contains(dependencyComponent->name())
- && !m_toInstallComponentIds.contains(component->name()))) {
- if (m_visitedComponents.value(component).contains(dependencyComponent)) {
- const QString errorMessage = recursionError(component);
- qCWarning(QInstaller::lcInstallerInstallLog).noquote() << errorMessage;
- m_componentsToInstallError = errorMessage;
- Q_ASSERT_X(!m_visitedComponents.value(component).contains(dependencyComponent),
- Q_FUNC_INFO, qPrintable(errorMessage));
- return false;
- }
- m_visitedComponents[component].insert(dependencyComponent);
}
- if (!component->autoDependencies().contains(dependencyComponentName))
- m_referenceCount[dependencyComponentName] << component->name();
+ m_visitedComponents[component].insert(dependencyComponent);
+ // add needed dependency components to the next run
+ insertInstallReason(dependencyComponent, InstallerCalculator::Dependent,
+ component->name());
- insertInstallReason(dependencyComponent, InstallerCalculator::Dependent, component->name());
- if (!appendComponentToInstall(dependencyComponent, requiredDependencyVersion, revertFromInstall))
+ if (!appendComponentToInstall(dependencyComponent, requiredDependencyVersion))
return false;
}
}
- if (!revertFromInstall && !m_toInstallComponentIds.contains(component->name())) {
- realAppendToInstallComponents(component, requiredDependencyVersion, revertFromInstall);
+
+ if (!m_toInstallComponentIds.contains(component->name())) {
+ realAppendToInstallComponents(component, requiredDependencyVersion);
insertInstallReason(component, InstallerCalculator::Resolved);
}
- if (revertFromInstall && m_toInstallComponentIds.contains(component->name())) {
- realAppendToInstallComponents(component, requiredDependencyVersion, revertFromInstall);
- }
return true;
}
-QString InstallerCalculator::recursionError(const Component *component) const
-{
- return QCoreApplication::translate("InstallerCalculator", "Recursion detected, component \"%1\" "
- "already added with reason: \"%2\"").arg(component->name(), installReason(component));
-}
-
-QSet<Component *> InstallerCalculator::autodependencyComponents(const bool revertFromInstall)
+QSet<Component *> InstallerCalculator::autodependencyComponents()
{
// All regular dependencies are resolved. Now we are looking for auto depend on components.
// m_componentsForAutodepencencyCheck is a list of recently calculated components to be installed
@@ -293,13 +233,12 @@ QSet<Component *> InstallerCalculator::autodependencyComponents(const bool rever
QSet<Component *> foundAutoDependOnList;
for (const Component *component : qAsConst(m_componentsForAutodepencencyCheck)) {
if (!m_autoDependencyComponentHash.contains(component->name())
- || (!revertFromInstall && m_core->isUpdater() && !component->updateRequested()))
+ || (m_core->isUpdater() && !component->updateRequested()))
continue;
for (const QString& autoDependency : m_autoDependencyComponentHash.value(component->name())) {
// If a components is already installed or is scheduled for installation, no need to check
// for auto depend installation.
- if ((!revertFromInstall && m_toInstallComponentIds.contains(autoDependency))
- || (revertFromInstall && !m_toInstallComponentIds.contains(autoDependency))) {
+ if (m_toInstallComponentIds.contains(autoDependency)) {
continue;
}
Component *autoDependComponent = m_core->componentByName(autoDependency);
@@ -314,10 +253,6 @@ QSet<Component *> InstallerCalculator::autodependencyComponents(const bool rever
foundAutoDependOnList.insert(autoDependComponent);
insertInstallReason(autoDependComponent, InstallerCalculator::Automatic);
}
- } else if (revertFromInstall
- && m_toInstallComponentIds.contains(autoDependComponent->name())
- && !m_toInstallComponentIds.contains(component->name())) {
- foundAutoDependOnList.insert(autoDependComponent);
}
}
}
@@ -325,20 +260,4 @@ QSet<Component *> InstallerCalculator::autodependencyComponents(const bool rever
return foundAutoDependOnList;
}
-void InstallerCalculator::calculateComponentDependencyReferences(const QString dependencyComponentName, const Component *component)
-{
- Component *dependencyComponent = m_core->componentByName(dependencyComponentName);
- if (!dependencyComponent || component->autoDependencies().contains(dependencyComponentName))
- return;
- QStringList value = m_referenceCount.value(dependencyComponentName, QStringList());
- value << component->name();
- m_referenceCount.insert(dependencyComponentName, value);
-
- const QStringList dependenciesList = dependencyComponent->currentDependencies();
- for (const QString &depComponentName : dependenciesList) {
- Component *dependencyComponent = m_core->componentByName(depComponentName);
- calculateComponentDependencyReferences(depComponentName, dependencyComponent);
- }
-}
-
} // namespace QInstaller
diff --git a/src/libs/installer/installercalculator.h b/src/libs/installer/installercalculator.h
index c2fa8761c..422de439c 100644
--- a/src/libs/installer/installercalculator.h
+++ b/src/libs/installer/installercalculator.h
@@ -39,6 +39,7 @@
namespace QInstaller {
class Component;
+class PackageManagerCore;
class INSTALLER_EXPORT InstallerCalculator
{
@@ -53,33 +54,27 @@ public:
Resolved // "Component(s) that have resolved Dependencies"
};
- InstallReasonType installReasonType(const Component *c) const;
+ 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 modelReset = false, const bool revertFromInstall = false);
- bool removeComponentsFromInstall(const QList<Component*> &components);
+ bool appendComponentsToInstall(const QList<Component*> &components);
private:
QString installReasonReferencedComponent(const Component *component) const;
- void insertInstallReason(const Component *component,
- const InstallReasonType installReason,
- const QString &referencedComponentName = QString(),
- const bool revertFromInstall = false);
- void realAppendToInstallComponents(Component *component, const QString &version, const bool revertFromInstall);
- bool appendComponentToInstall(Component *component, const QString &version, const bool revertFromInstall);
- QString recursionError(const Component *component) const;
- QSet<Component *> autodependencyComponents(const bool revertFromInstall);
- void calculateComponentDependencyReferences(const QString dependencyComponentName, const Component *component);
+ 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());
+ QSet<Component *> autodependencyComponents();
+ QString recursionError(Component *component) const;
private:
PackageManagerCore *m_core;
QHash<Component*, QSet<Component*> > m_visitedComponents;
QList<const Component*> m_componentsForAutodepencencyCheck;
- //for faster lookups.
- QSet<QString> m_toInstallComponentIds;
- QHash<QString, QStringList> m_referenceCount;
+ QSet<QString> m_toInstallComponentIds; //for faster lookups
QString m_componentsToInstallError;
//calculate installation order variables
QList<Component*> m_orderedComponentsToInstall;
diff --git a/src/libs/installer/packagemanagercore.cpp b/src/libs/installer/packagemanagercore.cpp
index 0788387a2..c866f1112 100644
--- a/src/libs/installer/packagemanagercore.cpp
+++ b/src/libs/installer/packagemanagercore.cpp
@@ -611,7 +611,7 @@ void PackageManagerCore::componentsToInstallNeedsRecalculation()
QList<Component*> selectedComponentsToInstall = componentsMarkedForInstallation();
d->m_componentsToInstallCalculated =
- d->installerCalculator()->appendComponentsToInstall(selectedComponentsToInstall, true);
+ d->installerCalculator()->appendComponentsToInstall(selectedComponentsToInstall);
d->calculateUninstallComponents();
d->updateComponentCheckedState();
@@ -622,66 +622,6 @@ void PackageManagerCore::componentsToInstallNeedsRecalculation()
}
/*!
- Calculates components to install based on user selection. \a indexes
- contains list of model indexes user has selected for install, dependencies
- and autodependencies are resolved later.
- */
-void PackageManagerCore::calculateUserSelectedComponentsToInstall(const QList<QModelIndex> &indexes)
-{
- QList<Component*> componentsToInstall;
- QList<Component*> componentsToUnInstall;
- ComponentModel *model = isUpdater() ? updaterComponentModel() : defaultComponentModel();
- for (QModelIndex index : indexes) {
- Component *installComponent = model->componentFromIndex(index);
- // 1. Component is selected for install
- if (installComponent->isSelected() && !installComponent->isInstalled()) {
- componentsToInstall.append(installComponent);
- // Check if component has replacements that needs to be removed
- const QList<Component*> replacedComponents = d->replacedComponentsByName(installComponent->name());
- for (Component *replacedComponent : replacedComponents) {
- componentsToUnInstall.append(replacedComponent);
- d->uninstallerCalculator()->insertUninstallReason(replacedComponent,
- UninstallerCalculator::UninstallReasonType::Replaced);
- }
- }
- // 2. Component is reselected for install (tapping checkbox off/on)
- else if (installComponent->isSelected() && installComponent->isInstalled()
- && !d->installerCalculator()->orderedComponentsToInstall().contains(installComponent)) {
- componentsToInstall.append(installComponent);
- }
- // 3. Component is selected for uninstall
- else if (!isUpdater() && !installComponent->isSelected() && installComponent->isInstalled()) {
- componentsToUnInstall.append(installComponent);
- }
- // 4. Component is reselected for uninstall (tapping checkbox on/off)
- else if (!installComponent->isSelected()
- && d->installerCalculator()->orderedComponentsToInstall().contains(installComponent)) {
- componentsToUnInstall.append(installComponent);
- // Check if component has replacements that needs to be readded
- componentsToInstall.append(d->replacedComponentsByName(installComponent->name()));
- }
- }
-
- d->installerCalculator()->removeComponentsFromInstall(componentsToUnInstall);
- d->m_componentsToInstallCalculated
- = d->installerCalculator()->appendComponentsToInstall(componentsToInstall, false);
- if (!isUpdater()) {
- d->uninstallerCalculator()->appendComponentsToUninstall(componentsToUnInstall, false);
- }
- d->uninstallerCalculator()->removeComponentsFromUnInstall(componentsToInstall);
- if (componentsToUnInstall.isEmpty() && !componentsToInstall.isEmpty()) {
- // There are no new components to be uninstalled but there
- // are new components to be installed which might have virtual
- // dependences to components which are already selected for uninstall.
- // We need to remove those components from uninstall.
- d->uninstallerCalculator()->appendVirtualComponentsToUninstall(true);
- }
-
- d->updateComponentCheckedState();
-}
-
-
-/*!
Forces a recalculation of components to install.
\sa {installer::clearComponentsToInstallCalculated}{installer.clearComponentsToInstallCalculated}
*/
@@ -4576,10 +4516,8 @@ ComponentModel *PackageManagerCore::componentModel(PackageManagerCore *core, con
ComponentModel::tr("Release Date"));
model->setHeaderData(ComponentModelHelper::UncompressedSizeColumn, Qt::Horizontal,
ComponentModel::tr("Size"));
- connect(model, &ComponentModel::modelCheckStateChanged,
+ connect(model, &ComponentModel::checkStateChanged,
this, &PackageManagerCore::componentsToInstallNeedsRecalculation);
- connect(model, &ComponentModel::componentsCheckStateChanged,
- this, &PackageManagerCore::calculateUserSelectedComponentsToInstall);
return model;
}
diff --git a/src/libs/installer/packagemanagercore.h b/src/libs/installer/packagemanagercore.h
index 911c4b480..26fa8e086 100644
--- a/src/libs/installer/packagemanagercore.h
+++ b/src/libs/installer/packagemanagercore.h
@@ -361,7 +361,6 @@ public Q_SLOTS:
void setCompleteUninstallation(bool complete);
void cancelMetaInfoJob();
void componentsToInstallNeedsRecalculation();
- void calculateUserSelectedComponentsToInstall(const QList<QModelIndex> &indexes);
void clearComponentsToInstallCalculated();
Q_SIGNALS:
diff --git a/src/libs/installer/packagemanagercore_p.cpp b/src/libs/installer/packagemanagercore_p.cpp
index 6eb589086..129c35d46 100644
--- a/src/libs/installer/packagemanagercore_p.cpp
+++ b/src/libs/installer/packagemanagercore_p.cpp
@@ -542,21 +542,6 @@ QHash<QString, QStringList> &PackageManagerCorePrivate::componentReplaces()
return m_componentReplaces;
}
-QList<Component*> PackageManagerCorePrivate::replacedComponentsByName(const QString &name)
-{
- // Creates a list of components which are replaced by component 'name'
- QList<Component*> replacedComponents;
- if (m_componentReplaces.contains(name)) {
- for (const QString &replacedComponentName : m_componentReplaces.value(name)) {
- Component *replacedComponent = m_core->componentByName(replacedComponentName,
- m_core->components(PackageManagerCore::ComponentType::All));
- if (replacedComponent)
- replacedComponents.append(replacedComponent);
- }
- }
- return replacedComponents;
-}
-
void PackageManagerCorePrivate::clearInstallerCalculator()
{
delete m_installerCalculator;
@@ -591,7 +576,7 @@ UninstallerCalculator *PackageManagerCorePrivate::uninstallerCalculator() const
}
}
- pmcp->m_uninstallerCalculator = new UninstallerCalculator(installedComponents, m_core,
+ pmcp->m_uninstallerCalculator = new UninstallerCalculator(m_core,
pmcp->m_autoDependencyComponentHash, pmcp->m_localDependencyComponentHash, pmcp->m_localVirtualComponents);
}
return m_uninstallerCalculator;
diff --git a/src/libs/installer/packagemanagercore_p.h b/src/libs/installer/packagemanagercore_p.h
index a42033ff6..56cf48d25 100644
--- a/src/libs/installer/packagemanagercore_p.h
+++ b/src/libs/installer/packagemanagercore_p.h
@@ -119,7 +119,6 @@ public:
QList<Component*> &replacementDependencyComponents();
QHash<QString, QPair<Component*, Component*> > &componentsToReplace();
QHash<QString, QStringList > &componentReplaces();
- QList<Component*> replacedComponentsByName(const QString &name);
void clearInstallerCalculator();
InstallerCalculator *installerCalculator() const;
diff --git a/src/libs/installer/uninstallercalculator.cpp b/src/libs/installer/uninstallercalculator.cpp
index 36d769207..4c07d81e3 100644
--- a/src/libs/installer/uninstallercalculator.cpp
+++ b/src/libs/installer/uninstallercalculator.cpp
@@ -30,9 +30,6 @@
#include "component.h"
#include "packagemanagercore.h"
-#include "globals.h"
-
-#include <QDebug>
namespace QInstaller {
@@ -42,13 +39,11 @@ namespace QInstaller {
\internal
*/
-UninstallerCalculator::UninstallerCalculator(const QList<Component *> &installedComponents
- , PackageManagerCore *core
+UninstallerCalculator::UninstallerCalculator(PackageManagerCore *core
, const AutoDependencyHash &autoDependencyComponentHash
, const LocalDependencyHash &localDependencyComponentHash
, const QStringList &localVirtualComponents)
- : m_installedComponents(installedComponents)
- , m_core(core)
+ : m_core(core)
, m_autoDependencyComponentHash(autoDependencyComponentHash)
, m_localDependencyComponentHash(localDependencyComponentHash)
, m_localVirtualComponents(localVirtualComponents)
@@ -60,7 +55,7 @@ QSet<Component *> UninstallerCalculator::componentsToUninstall() const
return m_componentsToUninstall;
}
-void UninstallerCalculator::appendComponentToUninstall(Component *component, const bool reverse)
+void UninstallerCalculator::appendComponentToUninstall(Component *component)
{
if (!component)
return;
@@ -75,28 +70,20 @@ void UninstallerCalculator::appendComponentToUninstall(Component *component, con
if (!depComponent)
continue;
if (depComponent->isInstalled() && !m_componentsToUninstall.contains(depComponent)) {
- appendComponentToUninstall(depComponent, reverse);
+ appendComponentToUninstall(depComponent);
insertUninstallReason(depComponent, UninstallerCalculator::Dependent, component->name());
- } else if (reverse && depComponent->isVirtual()) {
- // Remove from uninstall only hidden components, user
- // can select other dependencies manually
- appendComponentToUninstall(depComponent, true);
}
}
}
- if (reverse) {
- m_componentsToUninstall.remove(component);
- } else {
- m_componentsToUninstall.insert(component);
- }
+
+ m_componentsToUninstall.insert(component);
}
-void UninstallerCalculator::appendComponentsToUninstall(const QList<Component*> &components, const bool reverse)
+void UninstallerCalculator::appendComponentsToUninstall(const QList<Component*> &components)
{
- if (components.isEmpty())
- return;
foreach (Component *component, components)
- appendComponentToUninstall(component, reverse);
+ appendComponentToUninstall(component);
+
QList<Component*> autoDependOnList;
// All regular dependees are resolved. Now we are looking for auto depend on components.
for (Component *component : components) {
@@ -108,9 +95,7 @@ void 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 (reverse) {
- autoDependOnList.append(autoDepComponent);
- } else if (!m_componentsToUninstall.contains(autoDepComponent)) {
+ if (!m_componentsToUninstall.contains(autoDepComponent)) {
insertUninstallReason(autoDepComponent, UninstallerCalculator::AutoDependent, component->name());
autoDepComponent->setInstallAction(ComponentModelHelper::AutodependUninstallation);
autoDependOnList.append(autoDepComponent);
@@ -118,15 +103,11 @@ void UninstallerCalculator::appendComponentsToUninstall(const QList<Component*>
}
}
}
+
if (!autoDependOnList.isEmpty())
- appendComponentsToUninstall(autoDependOnList, reverse);
+ appendComponentsToUninstall(autoDependOnList);
else
- appendVirtualComponentsToUninstall(reverse);
-}
-
-void UninstallerCalculator::removeComponentsFromUnInstall(const QList<Component*> &components)
-{
- appendComponentsToUninstall(components, true);
+ appendVirtualComponentsToUninstall();
}
void UninstallerCalculator::insertUninstallReason(Component *component, const UninstallReasonType uninstallReason,
@@ -172,38 +153,30 @@ QString UninstallerCalculator::uninstallReasonReferencedComponent(Component *com
return m_toUninstallComponentIdReasonHash.value(component->name()).second;
}
-void UninstallerCalculator::appendVirtualComponentsToUninstall(const bool reverse)
+void UninstallerCalculator::appendVirtualComponentsToUninstall()
{
QList<Component*> unneededVirtualList;
-
// Check for virtual components without dependees
- if (reverse) {
- for (Component *reverseFromUninstall : qAsConst(m_virtualComponentsForReverse)) {
- if (m_componentsToUninstall.contains(reverseFromUninstall) && (isRequiredVirtualPackage(reverseFromUninstall)))
- unneededVirtualList.append(reverseFromUninstall);
- }
- } else {
- for (const QString &componentName : qAsConst(m_localVirtualComponents)) {
- Component *virtualComponent = m_core->componentByName(componentName, m_core->components(PackageManagerCore::ComponentType::All));
- if (!virtualComponent)
- continue;
+ for (const QString &componentName : qAsConst(m_localVirtualComponents)) {
+ Component *virtualComponent = m_core->componentByName(componentName, m_core->components(PackageManagerCore::ComponentType::All));
+ if (!virtualComponent)
+ continue;
- if (virtualComponent->isInstalled() && !m_componentsToUninstall.contains(virtualComponent)) {
- // Components with auto dependencies were handled in the previous step
- if (!virtualComponent->autoDependencies().isEmpty() || virtualComponent->forcedInstallation())
- continue;
+ if (virtualComponent->isInstalled() && !m_componentsToUninstall.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);
- m_virtualComponentsForReverse.append(virtualComponent);
- insertUninstallReason(virtualComponent, UninstallerCalculator::VirtualDependent);
- }
- }
+ if (!isRequiredVirtualPackage(virtualComponent)) {
+ unneededVirtualList.append(virtualComponent);
+ m_virtualComponentsForReverse.append(virtualComponent);
+ insertUninstallReason(virtualComponent, UninstallerCalculator::VirtualDependent);
+ }
}
}
if (!unneededVirtualList.isEmpty())
- appendComponentsToUninstall(unneededVirtualList, reverse);
+ appendComponentsToUninstall(unneededVirtualList);
}
bool UninstallerCalculator::isRequiredVirtualPackage(Component *component)
diff --git a/src/libs/installer/uninstallercalculator.h b/src/libs/installer/uninstallercalculator.h
index 57f2f926a..74207e005 100644
--- a/src/libs/installer/uninstallercalculator.h
+++ b/src/libs/installer/uninstallercalculator.h
@@ -53,28 +53,26 @@ public:
AutoDependent // "Removed as autodependency component is removed"
};
- UninstallerCalculator(const QList<Component *> &installedComponents, PackageManagerCore *core,
+ UninstallerCalculator(PackageManagerCore *core,
const AutoDependencyHash &autoDependencyComponentHash,
const LocalDependencyHash &localDependencyComponentHash,
const QStringList &localVirtualComponents);
QSet<Component*> componentsToUninstall() const;
- void appendComponentsToUninstall(const QList<Component*> &components, const bool reverse = false);
- void removeComponentsFromUnInstall(const QList<Component*> &components);
+ void 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;
- QString uninstallReasonReferencedComponent(Component *component) const;
- bool isRequiredVirtualPackage(Component *component);
- void appendVirtualComponentsToUninstall(const bool reverse);
private:
- void appendComponentToUninstall(Component *component, const bool reverse);
+ QString uninstallReasonReferencedComponent(Component *component) const;
+ bool isRequiredVirtualPackage(Component *component);
+ void appendComponentToUninstall(Component *component);
+ void appendVirtualComponentsToUninstall();
- QList<Component *> m_installedComponents;
QSet<Component *> m_componentsToUninstall;
PackageManagerCore *m_core;
QHash<QString, QPair<UninstallReasonType, QString> > m_toUninstallComponentIdReasonHash;
diff --git a/tests/auto/installer/solver/tst_solver.cpp b/tests/auto/installer/solver/tst_solver.cpp
index bdfc4d3df..ee05cc7f4 100644
--- a/tests/auto/installer/solver/tst_solver.cpp
+++ b/tests/auto/installer/solver/tst_solver.cpp
@@ -248,7 +248,6 @@ private slots:
{
QTest::addColumn<PackageManagerCore *>("core");
QTest::addColumn<QList<Component *> >("selectedToUninstall");
- QTest::addColumn<QList<Component *> >("installedComponents");
QTest::addColumn<QSet<Component *> >("expectedResult");
QTest::addColumn<UninstallReasonList >("uninstallReasons");
QTest::addColumn<LocalDependencyHash >("dependencyHash");
@@ -277,7 +276,6 @@ private slots:
uninstallReasonList.append(qMakePair(componentB, UninstallerCalculator::Dependent));
QTest::newRow("Uninstaller resolved") << core
<< (QList<Component *>() << componentAB)
- << (QList<Component *>() << componentA << componentB)
<< (QSet<Component *>() << componentAB << componentB)
<< uninstallReasonList
<< dependencyComponentHash;
@@ -303,7 +301,6 @@ private slots:
uninstallReasonList.append(qMakePair(compB, UninstallerCalculator::Dependent));
QTest::newRow("Cascade dependencies") << core
<< (QList<Component *>() << compA)
- << (QList<Component *>() << compB)
<< (QSet<Component *>() << compA << compB)
<< (uninstallReasonList)
<< dependencyComponentHash;
@@ -313,12 +310,11 @@ private slots:
{
QFETCH(PackageManagerCore *, core);
QFETCH(QList<Component *> , selectedToUninstall);
- QFETCH(QList<Component *> , installedComponents);
QFETCH(QSet<Component *> , expectedResult);
QFETCH(UninstallReasonList, uninstallReasons);
QFETCH(LocalDependencyHash, dependencyHash);
- UninstallerCalculator calc(installedComponents, core, QHash<QString, QStringList>(), dependencyHash, QStringList());
+ UninstallerCalculator calc(core, QHash<QString, QStringList>(), dependencyHash, QStringList());
calc.appendComponentsToUninstall(selectedToUninstall);
QSet<Component *> result = calc.componentsToUninstall();
for (auto pair : uninstallReasons) {