summaryrefslogtreecommitdiffstats
path: root/src/libs/installer
diff options
context:
space:
mode:
authorKatja Marttila <katja.marttila@qt.io>2019-05-28 12:50:13 +0300
committerKatja Marttila <katja.marttila@qt.io>2021-02-11 09:41:19 +0200
commit4abb9cd9b360278f5c8984a9fd2e62677e7c940c (patch)
tree5b7721b82eefe103dc9f148f4323ef31de28731b /src/libs/installer
parent5aee36b74eb1d7613ea0108971e8a22f8dca8101 (diff)
Add possibility to move component in component tree
Setting <TreeName> -tag to component.xml will overwrite the default location of component in installer's tree view. This way we can define the component location without a complete repo build. Updates.xml can be directly modified by adding <TreeName> -tag for easy relocation of components. TreeName must be an unique name - it cannot conflict with existing tree name or name. Task-number: QTIFW-594 Change-Id: Ie69f90f1303d932369d566d0d7b4bc0e354505c6 Reviewed-by: Arttu Tarkiainen <arttu.tarkiainen@qt.io>
Diffstat (limited to 'src/libs/installer')
-rw-r--r--src/libs/installer/component.cpp12
-rw-r--r--src/libs/installer/component.h4
-rw-r--r--src/libs/installer/componentmodel.cpp20
-rw-r--r--src/libs/installer/componentselectionpage_p.cpp4
-rw-r--r--src/libs/installer/constants.h1
-rw-r--r--src/libs/installer/packagemanagercore.cpp77
-rw-r--r--src/libs/installer/packagemanagercore_p.cpp4
7 files changed, 87 insertions, 35 deletions
diff --git a/src/libs/installer/component.cpp b/src/libs/installer/component.cpp
index 2e797944b..ff01e4251 100644
--- a/src/libs/installer/component.cpp
+++ b/src/libs/installer/component.cpp
@@ -274,6 +274,7 @@ void Component::loadDataFromPackage(const KDUpdater::LocalPackage &package)
{
setValue(scName, package.name);
setValue(scDisplayName, package.title);
+ setValue(scTreeName, package.treeName);
setValue(scDescription, package.description);
setValue(scVersion, package.version);
setValue(scInheritVersion, package.inheritVersionFrom);
@@ -301,6 +302,7 @@ void Component::loadDataFromPackage(const Package &package)
setValue(scName, package.data(scName).toString());
setValue(scDisplayName, package.data(scDisplayName).toString());
+ setValue(scTreeName, package.data(scTreeName).toString());
setValue(scDescription, package.data(scDescription).toString());
setValue(scDefault, package.data(scDefault).toString());
setValue(scAutoDependOn, package.data(scAutoDependOn).toString());
@@ -523,6 +525,16 @@ QString Component::displayName() const
}
/*!
+ Returns this component's location in the tree view. If the tree name is not
+ set, returns the component name. The tree name must be unique, it must not
+ conflict with other tree names or component names.
+*/
+QString Component::treeName() const
+{
+ return d->m_vars.value(scTreeName, name());
+}
+
+/*!
Loads the component script into the script engine.
*/
void Component::loadComponentScript()
diff --git a/src/libs/installer/component.h b/src/libs/installer/component.h
index f7f03391f..d042bfe6a 100644
--- a/src/libs/installer/component.h
+++ b/src/libs/installer/component.h
@@ -1,6 +1,6 @@
/**************************************************************************
**
-** Copyright (C) 2020 The Qt Company Ltd.
+** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Installer Framework.
@@ -62,6 +62,7 @@ class INSTALLER_EXPORT Component : public QObject, public ComponentModelHelper
Q_PROPERTY(bool installed READ isInstalled)
Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled)
Q_PROPERTY(bool unstable READ isUnstable)
+ Q_PROPERTY(QString treeName READ treeName)
public:
explicit Component(PackageManagerCore *core);
@@ -157,6 +158,7 @@ public:
QString name() const;
QString displayName() const;
+ QString treeName() const;
quint64 updateUncompressedSize();
QUrl repositoryUrl() const;
diff --git a/src/libs/installer/componentmodel.cpp b/src/libs/installer/componentmodel.cpp
index 45e27ba4a..aab487b45 100644
--- a/src/libs/installer/componentmodel.cpp
+++ b/src/libs/installer/componentmodel.cpp
@@ -1,6 +1,6 @@
/**************************************************************************
**
-** Copyright (C) 2017 The Qt Company Ltd.
+** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Installer Framework.
@@ -159,7 +159,7 @@ QModelIndex ComponentModel::parent(const QModelIndex &child) const
if (Component *childComponent = componentFromIndex(child)) {
if (Component *parent = childComponent->parentComponent())
- return indexFromComponentName(parent->name());
+ return indexFromComponentName(parent->treeName());
}
return QModelIndex();
}
@@ -513,18 +513,18 @@ void ComponentModel::updateAndEmitModelState()
emit checkStateChanged(m_modelState);
foreach (const Component *component, m_rootComponentList) {
- emit dataChanged(indexFromComponentName(component->name()),
- indexFromComponentName(component->name()));
+ emit dataChanged(indexFromComponentName(component->treeName()),
+ indexFromComponentName(component->treeName()));
QList<Component *> children = component->childItems();
foreach (const Component *child, children)
- emit dataChanged(indexFromComponentName(child->name()),
- indexFromComponentName(child->name()));
+ emit dataChanged(indexFromComponentName(child->treeName()),
+ indexFromComponentName(child->treeName()));
}
}
void ComponentModel::collectComponents(Component *const component, const QModelIndex &parent) const
{
- m_indexByNameCache.insert(component->name(), parent);
+ m_indexByNameCache.insert(component->treeName(), parent);
for (int i = 0; i < component->childCount(); ++i)
collectComponents(component->childAt(i), index(i, 0, parent));
}
@@ -568,8 +568,8 @@ QSet<QModelIndex> ComponentModel::updateCheckedState(const ComponentSet &compone
// get all parent nodes for the components we're going to update
QMap<QString, Component *> sortedNodesMap;
foreach (Component *component, components) {
- while (component && !sortedNodesMap.values(component->name()).contains(component)) {
- sortedNodesMap.insertMulti(component->name(), component);
+ while (component && !sortedNodesMap.values(component->treeName()).contains(component)) {
+ sortedNodesMap.insertMulti(component->treeName(), component);
component = component->parentComponent();
}
}
@@ -596,7 +596,7 @@ QSet<QModelIndex> ComponentModel::updateCheckedState(const ComponentSet &compone
continue;
node->setCheckState(newState);
- changed.insert(indexFromComponentName(node->name()));
+ changed.insert(indexFromComponentName(node->treeName()));
m_currentCheckedState[Qt::Checked].remove(node);
m_currentCheckedState[Qt::Unchecked].remove(node);
diff --git a/src/libs/installer/componentselectionpage_p.cpp b/src/libs/installer/componentselectionpage_p.cpp
index 31c4dbedc..a9f4ba134 100644
--- a/src/libs/installer/componentselectionpage_p.cpp
+++ b/src/libs/installer/componentselectionpage_p.cpp
@@ -1,6 +1,6 @@
/**************************************************************************
**
-** Copyright (C) 2020 The Qt Company Ltd.
+** Copyright (C) 2021 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt Installer Framework.
@@ -274,7 +274,7 @@ void ComponentSelectionPagePrivate::updateTreeView()
m_treeView->setExpanded(m_currentModel->index(0, 0), true);
foreach (Component *component, m_core->components(PackageManagerCore::ComponentType::All)) {
if (component->isExpandedByDefault()) {
- const QModelIndex index = m_currentModel->indexFromComponentName(component->name());
+ const QModelIndex index = m_currentModel->indexFromComponentName(component->treeName());
m_treeView->setExpanded(index, true);
}
}
diff --git a/src/libs/installer/constants.h b/src/libs/installer/constants.h
index feee73fad..42b14ce63 100644
--- a/src/libs/installer/constants.h
+++ b/src/libs/installer/constants.h
@@ -55,6 +55,7 @@ static const QLatin1String scTargetDir("TargetDir");
static const QLatin1String scReleaseDate("ReleaseDate");
static const QLatin1String scDescription("Description");
static const QLatin1String scDisplayName("DisplayName");
+static const QLatin1String scTreeName("TreeName");
static const QLatin1String scDependencies("Dependencies");
static const QLatin1String scAutoDependOn("AutoDependOn");
static const QLatin1String scNewComponent("NewComponent");
diff --git a/src/libs/installer/packagemanagercore.cpp b/src/libs/installer/packagemanagercore.cpp
index 7eaae7b33..41744ff96 100644
--- a/src/libs/installer/packagemanagercore.cpp
+++ b/src/libs/installer/packagemanagercore.cpp
@@ -1372,11 +1372,11 @@ bool PackageManagerCore::fetchLocalPackagesTree()
foreach (const QString &key, keys) {
QScopedPointer<QInstaller::Component> component(new QInstaller::Component(this));
component->loadDataFromPackage(installedPackages.value(key));
- const QString &name = component->name();
+ const QString &name = component->treeName();
if (components.contains(name)) {
- qCritical("Cannot register component! Component with identifier %s already registered.",
- qPrintable(name));
- continue;
+ d->setStatus(Failure, tr("Cannot register component! Component with identifier %1 "
+ "already exists.").arg(name));
+ return false;
}
components.insert(name, component.take());
}
@@ -2210,7 +2210,7 @@ bool PackageManagerCore::componentUninstallableFromCommandLine(const QString &co
return false;
}
ComponentModel *model = defaultComponentModel();
- const QModelIndex &idx = model->indexFromComponentName(componentName);
+ const QModelIndex &idx = model->indexFromComponentName(component->treeName());
if (model->data(idx, Qt::CheckStateRole) == QVariant::Invalid) {
// Component cannot be unselected, check why
if (component->forcedInstallation()) {
@@ -2246,9 +2246,13 @@ bool PackageManagerCore::checkComponentsForInstallation(const QStringList &compo
ComponentModel *model = defaultComponentModel();
foreach (const QString &name, components) {
- const QModelIndex &idx = model->indexFromComponentName(name);
Component *component = componentByName(name);
- if (component && idx.isValid()) {
+ if (!component) {
+ errorMessage.append(tr("Cannot install %1. Component not found.\n").arg(name));
+ continue;
+ }
+ const QModelIndex &idx = model->indexFromComponentName(component->treeName());
+ if (idx.isValid()) {
if ((model->data(idx, Qt::CheckStateRole) == QVariant::Invalid) && !component->forcedInstallation()) {
// User cannot select the component, check why
if (component->autoDependencies().count() > 0) {
@@ -2265,7 +2269,7 @@ bool PackageManagerCore::checkComponentsForInstallation(const QStringList &compo
installComponentsFound = true;
}
} else { // idx is invalid and component valid when we have invisible virtual component
- component && component->isVirtual()
+ component->isVirtual()
? errorMessage.append(tr("Cannot install %1. Component is virtual.\n").arg(name))
: errorMessage.append(tr("Cannot install %1. Component not found.\n").arg(name));
}
@@ -2330,7 +2334,7 @@ PackageManagerCore::Status PackageManagerCore::updateComponentsSilently(const QS
QList<Component*> componentsToBeUpdated;
//Mark components to be updated
foreach (Component *comp, componentList) {
- const QModelIndex &idx = model->indexFromComponentName(comp->name());
+ const QModelIndex &idx = model->indexFromComponentName(comp->treeName());
if (!userSelectedComponents) { // No components given, update all
model->setData(idx, Qt::Checked, Qt::CheckStateRole);
} else {
@@ -2350,7 +2354,7 @@ PackageManagerCore::Status PackageManagerCore::updateComponentsSilently(const QS
return PackageManagerCore::Success;
}
foreach (Component *componentToUpdate, componentsToBeUpdated) {
- const QModelIndex &idx = model->indexFromComponentName(componentToUpdate->name());
+ const QModelIndex &idx = model->indexFromComponentName(componentToUpdate->treeName());
model->setData(idx, Qt::Checked, Qt::CheckStateRole);
}
}
@@ -2434,11 +2438,11 @@ PackageManagerCore::Status PackageManagerCore::uninstallComponentsSilently(const
bool uninstallComponentFound = false;
foreach (const QString &componentName, components){
- const QModelIndex &idx = model->indexFromComponentName(componentName);
Component *component = componentByName(componentName);
if (component) {
- if (componentUninstallableFromCommandLine(componentName)) {
+ const QModelIndex &idx = model->indexFromComponentName(component->treeName());
+ if (componentUninstallableFromCommandLine(component->name())) {
model->setData(idx, Qt::Unchecked, Qt::CheckStateRole);
uninstallComponentFound = true;
}
@@ -3516,14 +3520,17 @@ QString PackageManagerCore::maintenanceToolName() const
bool PackageManagerCore::updateComponentData(struct Data &data, Component *component)
{
try {
- // check if we already added the component to the available components list
- const QString name = data.package->data(scName).toString();
+ // Check if we already added the component to the available components list.
+ // Component treenames and names must be unique.
+ QString name = data.package->data(scTreeName).toString();
+ if (name.isEmpty())
+ name = data.package->data(scName).toString();
if (data.components->contains(name)) {
- qCritical("Cannot register component! Component with identifier %s already registered.",
- qPrintable(name));
+ d->setStatus(Failure, tr("Cannot register component! Component with identifier %1 "
+ "already exists.").arg(name));
return false;
}
-
+ name = data.package->data(scName).toString();
if (settings().allowUnstableComponents()) {
// Check if there are sha checksum mismatch. Component will still show in install tree
// but is unselectable.
@@ -3643,6 +3650,7 @@ bool PackageManagerCore::fetchAllPackages(const PackagesList &remotes, const Loc
data.components = &components;
data.installedPackages = &locals;
+ QMap<QString, QString> treeNameComponents;
foreach (Package *const package, remotes) {
if (d->statusCanceledOrFailed())
return false;
@@ -3654,17 +3662,42 @@ bool PackageManagerCore::fetchAllPackages(const PackagesList &remotes, const Loc
data.package = package;
component->loadDataFromPackage(*package);
if (updateComponentData(data, component.data())) {
- const QString name = component->name();
+ // Create a list where is name and treename. Repo can contain a package with
+ // a different treename of component which is already installed. We don't want
+ // to move already installed local packages.
+ const QString treeName = component->value(scTreeName);
+ if (!treeName.isEmpty())
+ treeNameComponents.insert(component->name(), treeName);
+ QString name = component->treeName();
components.insert(name, component.take());
+ } else {
+ return false;
}
}
foreach (const QString &key, locals.keys()) {
QScopedPointer<QInstaller::Component> component(new QInstaller::Component(this));
component->loadDataFromPackage(locals.value(key));
- const QString &name = component->name();
- if (!components.contains(name))
- components.insert(name, component.take());
+ QString treeName = component->treeName();
+
+ // 1. Component has a treename in local but not in remote
+ if (!treeNameComponents.contains(component->name()) && !component->value(scTreeName).isEmpty()) {
+ Component *comp = components.take(component->name());
+ delete comp;
+ components.insert(treeName, component.take());
+ // 2. Component has different treename in local and remote, add with local treename
+ } else if (treeNameComponents.contains(component->name())) {
+ QString remoteTreeName = treeNameComponents.value(component->name());
+ QString componentTreeName = component->value(scTreeName);
+ if (remoteTreeName != componentTreeName) {
+ Component *comp = components.take(treeNameComponents.value(component->name()));
+ delete comp;
+ components.insert(treeName, component.take());
+ }
+ // 3. Component has same treename in local and remote, don't add the component again.
+ } else if (!components.contains(treeName)) {
+ components.insert(treeName, component.take());
+ }
}
// store all components that got a replacement
@@ -3750,6 +3783,8 @@ bool PackageManagerCore::fetchUpdaterPackages(const PackagesList &remotes, const
// this is not a dependency, it is a real update
components.insert(name, d->m_updaterComponentsDeps.takeLast());
+ } else {
+ return false;
}
}
diff --git a/src/libs/installer/packagemanagercore_p.cpp b/src/libs/installer/packagemanagercore_p.cpp
index 94e08018a..924de0de3 100644
--- a/src/libs/installer/packagemanagercore_p.cpp
+++ b/src/libs/installer/packagemanagercore_p.cpp
@@ -2233,6 +2233,7 @@ void PackageManagerCorePrivate::installComponent(Component *component, double pr
m_localPackageHub->addPackage(component->name(),
component->value(scVersion),
component->value(scDisplayName),
+ component->value(scTreeName),
component->value(scDescription),
component->dependencies(),
component->autoDependencies(),
@@ -2273,7 +2274,8 @@ bool PackageManagerCorePrivate::runningProcessesFound()
void PackageManagerCorePrivate::setComponentSelection(const QString &id, Qt::CheckState state)
{
ComponentModel *model = m_core->isUpdater() ? m_core->updaterComponentModel() : m_core->defaultComponentModel();
- const QModelIndex &idx = model->indexFromComponentName(id);
+ Component *component = m_core->componentByName(id);
+ const QModelIndex &idx = model->indexFromComponentName(component->treeName());
if (idx.isValid())
model->setData(idx, state, Qt::CheckStateRole);
}