summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/installerfw.qdoc2
-rw-r--r--examples/dependencies/packages/componentA/data/installcontentA.txt2
-rw-r--r--examples/dependencies/packages/componentB/data/installcontentB.txt2
-rw-r--r--examples/dependencies/packages/componentC/data/installcontentC.txt2
-rw-r--r--examples/dependencies/packages/componentD/data/installcontentD.txt2
-rw-r--r--examples/dependencies/packages/componentE/data/installcontentE.txt2
-rw-r--r--examples/dependencies/packages/componentF.subcomponent1.subsubcomponent1/data/installcontentF_1_1.txt2
-rw-r--r--examples/dependencies/packages/componentF.subcomponent1.subsubcomponent2/data/installcontentF_1_2.txt2
-rw-r--r--examples/dependencies/packages/componentF.subcomponent1/data/installcontentF_1.txt2
-rw-r--r--examples/dependencies/packages/componentF.subcomponent2.subsubcomponent1/data/installcontentF_2_1.txt2
-rw-r--r--examples/dependencies/packages/componentF.subcomponent2.subsubcomponent2/data/installcontentF_2_2.txt2
-rw-r--r--examples/dependencies/packages/componentF.subcomponent2/data/installcontentF_2.txt2
-rw-r--r--examples/dependencies/packages/componentF/data/installcontentF.txt2
-rw-r--r--examples/dependencies/packages/componentG/data/installcontentG.txt2
-rw-r--r--src/libs/installer/component_p.h3
-rw-r--r--src/libs/installer/componentmodel.cpp8
-rw-r--r--src/libs/installer/metadatajob.cpp67
-rw-r--r--src/libs/installer/metadatajob.h5
-rw-r--r--src/libs/installer/packagemanagercore_p.cpp4
-rw-r--r--src/libs/installer/uninstallercalculator.cpp16
20 files changed, 103 insertions, 28 deletions
diff --git a/doc/installerfw.qdoc b/doc/installerfw.qdoc
index e65deb055..669fc66f4 100644
--- a/doc/installerfw.qdoc
+++ b/doc/installerfw.qdoc
@@ -758,7 +758,7 @@
You can also create hybrid installers that store some components locally
and receive others via a network connection. For more information, see
- ###TODO insert link here.
+ \l {Reducing Installer Size}.
For information about how to implement data integration into the
installer binary, see QInstaller::BinaryContent.
diff --git a/examples/dependencies/packages/componentA/data/installcontentA.txt b/examples/dependencies/packages/componentA/data/installcontentA.txt
new file mode 100644
index 000000000..f40001983
--- /dev/null
+++ b/examples/dependencies/packages/componentA/data/installcontentA.txt
@@ -0,0 +1,2 @@
+This file will be installed into the target directory....
+
diff --git a/examples/dependencies/packages/componentB/data/installcontentB.txt b/examples/dependencies/packages/componentB/data/installcontentB.txt
new file mode 100644
index 000000000..f40001983
--- /dev/null
+++ b/examples/dependencies/packages/componentB/data/installcontentB.txt
@@ -0,0 +1,2 @@
+This file will be installed into the target directory....
+
diff --git a/examples/dependencies/packages/componentC/data/installcontentC.txt b/examples/dependencies/packages/componentC/data/installcontentC.txt
new file mode 100644
index 000000000..f40001983
--- /dev/null
+++ b/examples/dependencies/packages/componentC/data/installcontentC.txt
@@ -0,0 +1,2 @@
+This file will be installed into the target directory....
+
diff --git a/examples/dependencies/packages/componentD/data/installcontentD.txt b/examples/dependencies/packages/componentD/data/installcontentD.txt
new file mode 100644
index 000000000..f40001983
--- /dev/null
+++ b/examples/dependencies/packages/componentD/data/installcontentD.txt
@@ -0,0 +1,2 @@
+This file will be installed into the target directory....
+
diff --git a/examples/dependencies/packages/componentE/data/installcontentE.txt b/examples/dependencies/packages/componentE/data/installcontentE.txt
new file mode 100644
index 000000000..f40001983
--- /dev/null
+++ b/examples/dependencies/packages/componentE/data/installcontentE.txt
@@ -0,0 +1,2 @@
+This file will be installed into the target directory....
+
diff --git a/examples/dependencies/packages/componentF.subcomponent1.subsubcomponent1/data/installcontentF_1_1.txt b/examples/dependencies/packages/componentF.subcomponent1.subsubcomponent1/data/installcontentF_1_1.txt
new file mode 100644
index 000000000..f40001983
--- /dev/null
+++ b/examples/dependencies/packages/componentF.subcomponent1.subsubcomponent1/data/installcontentF_1_1.txt
@@ -0,0 +1,2 @@
+This file will be installed into the target directory....
+
diff --git a/examples/dependencies/packages/componentF.subcomponent1.subsubcomponent2/data/installcontentF_1_2.txt b/examples/dependencies/packages/componentF.subcomponent1.subsubcomponent2/data/installcontentF_1_2.txt
new file mode 100644
index 000000000..f40001983
--- /dev/null
+++ b/examples/dependencies/packages/componentF.subcomponent1.subsubcomponent2/data/installcontentF_1_2.txt
@@ -0,0 +1,2 @@
+This file will be installed into the target directory....
+
diff --git a/examples/dependencies/packages/componentF.subcomponent1/data/installcontentF_1.txt b/examples/dependencies/packages/componentF.subcomponent1/data/installcontentF_1.txt
new file mode 100644
index 000000000..f40001983
--- /dev/null
+++ b/examples/dependencies/packages/componentF.subcomponent1/data/installcontentF_1.txt
@@ -0,0 +1,2 @@
+This file will be installed into the target directory....
+
diff --git a/examples/dependencies/packages/componentF.subcomponent2.subsubcomponent1/data/installcontentF_2_1.txt b/examples/dependencies/packages/componentF.subcomponent2.subsubcomponent1/data/installcontentF_2_1.txt
new file mode 100644
index 000000000..f40001983
--- /dev/null
+++ b/examples/dependencies/packages/componentF.subcomponent2.subsubcomponent1/data/installcontentF_2_1.txt
@@ -0,0 +1,2 @@
+This file will be installed into the target directory....
+
diff --git a/examples/dependencies/packages/componentF.subcomponent2.subsubcomponent2/data/installcontentF_2_2.txt b/examples/dependencies/packages/componentF.subcomponent2.subsubcomponent2/data/installcontentF_2_2.txt
new file mode 100644
index 000000000..f40001983
--- /dev/null
+++ b/examples/dependencies/packages/componentF.subcomponent2.subsubcomponent2/data/installcontentF_2_2.txt
@@ -0,0 +1,2 @@
+This file will be installed into the target directory....
+
diff --git a/examples/dependencies/packages/componentF.subcomponent2/data/installcontentF_2.txt b/examples/dependencies/packages/componentF.subcomponent2/data/installcontentF_2.txt
new file mode 100644
index 000000000..f40001983
--- /dev/null
+++ b/examples/dependencies/packages/componentF.subcomponent2/data/installcontentF_2.txt
@@ -0,0 +1,2 @@
+This file will be installed into the target directory....
+
diff --git a/examples/dependencies/packages/componentF/data/installcontentF.txt b/examples/dependencies/packages/componentF/data/installcontentF.txt
new file mode 100644
index 000000000..f40001983
--- /dev/null
+++ b/examples/dependencies/packages/componentF/data/installcontentF.txt
@@ -0,0 +1,2 @@
+This file will be installed into the target directory....
+
diff --git a/examples/dependencies/packages/componentG/data/installcontentG.txt b/examples/dependencies/packages/componentG/data/installcontentG.txt
new file mode 100644
index 000000000..f40001983
--- /dev/null
+++ b/examples/dependencies/packages/componentG/data/installcontentG.txt
@@ -0,0 +1,2 @@
+This file will be installed into the target directory....
+
diff --git a/src/libs/installer/component_p.h b/src/libs/installer/component_p.h
index b9f50b557..05b169d4b 100644
--- a/src/libs/installer/component_p.h
+++ b/src/libs/installer/component_p.h
@@ -100,7 +100,8 @@ public:
Install,
Uninstall,
KeepInstalled,
- KeepUninstalled
+ KeepUninstalled,
+ AutodependUninstallation
};
enum Column {
diff --git a/src/libs/installer/componentmodel.cpp b/src/libs/installer/componentmodel.cpp
index 8becdb191..8201248f8 100644
--- a/src/libs/installer/componentmodel.cpp
+++ b/src/libs/installer/componentmodel.cpp
@@ -584,9 +584,13 @@ QSet<QModelIndex> ComponentModel::updateCheckedState(const ComponentSet &compone
if (node->value(scCheckable, scTrue).toLower() == scFalse) {
checkable = false;
}
-
- if ((!node->isCheckable() && checkable) || !node->isEnabled() || !node->autoDependencies().isEmpty())
+ // Let the check state to be checked up if the node is installed even if the component is not
+ // selectable/enabled or is installed as autodependency. Otherwise the node might not be selected
+ // and installer thinks it should be uninstalled.
+ if (!node->isInstalled() &&
+ ((!node->isCheckable() && checkable) || !node->isEnabled() || !node->autoDependencies().isEmpty())) {
continue;
+ }
Qt::CheckState newState = state;
const Qt::CheckState recentState = node->checkState();
diff --git a/src/libs/installer/metadatajob.cpp b/src/libs/installer/metadatajob.cpp
index 0c674e313..bd577fecf 100644
--- a/src/libs/installer/metadatajob.cpp
+++ b/src/libs/installer/metadatajob.cpp
@@ -37,6 +37,7 @@
#include "testrepository.h"
#include <QTemporaryDir>
+#include <QtMath>
namespace QInstaller {
@@ -52,6 +53,8 @@ MetadataJob::MetadataJob(QObject *parent)
: Job(parent)
, m_core(0)
, m_addCompressedPackages(false)
+ , m_downloadableChunkSize(1000)
+ , m_taskNumber(0)
{
setCapabilities(Cancelable);
connect(&m_xmlTask, &QFutureWatcherBase::finished, this, &MetadataJob::xmlTaskFinished);
@@ -325,12 +328,7 @@ void MetadataJob::xmlTaskFinished()
return;
if (status == XmlDownloadSuccess) {
- setProcessedAmount(0);
- DownloadFileTask *const metadataTask = new DownloadFileTask(m_packages);
- metadataTask->setProxyFactory(m_core->proxyFactory());
- m_metadataTask.setFuture(QtConcurrent::run(&DownloadFileTask::doTask, metadataTask));
- setProgressTotalAmount(100);
- emit infoMessage(this, tr("Retrieving meta information from remote repository..."));
+ fetchMetaDataPackages();
} else if (status == XmlDownloadRetry) {
QMetaObject::invokeMethod(this, "doStart", Qt::QueuedConnection);
} else {
@@ -379,21 +377,23 @@ void MetadataJob::metadataTaskFinished()
{
try {
m_metadataTask.waitForFinished();
- QFuture<FileTaskResult> future = m_metadataTask.future();
- if (future.resultCount() > 0) {
- emit infoMessage(this, tr("Extracting meta information..."));
- foreach (const FileTaskResult &result, future.results()) {
- const FileTaskItem item = result.value(TaskRole::TaskItem).value<FileTaskItem>();
- UnzipArchiveTask *task = new UnzipArchiveTask(result.target(),
- item.value(TaskRole::UserRole).toString());
-
- QFutureWatcher<void> *watcher = new QFutureWatcher<void>();
- m_unzipTasks.insert(watcher, qobject_cast<QObject*> (task));
- connect(watcher, &QFutureWatcherBase::finished, this, &MetadataJob::unzipTaskFinished);
- watcher->setFuture(QtConcurrent::run(&UnzipArchiveTask::doTask, task));
+ m_metadataResult.append(m_metadataTask.future().results());
+ if (!fetchMetaDataPackages()) {
+ if (m_metadataResult.count() > 0) {
+ emit infoMessage(this, tr("Extracting meta information..."));
+ foreach (const FileTaskResult &result, m_metadataResult) {
+ const FileTaskItem item = result.value(TaskRole::TaskItem).value<FileTaskItem>();
+ UnzipArchiveTask *task = new UnzipArchiveTask(result.target(),
+ item.value(TaskRole::UserRole).toString());
+
+ QFutureWatcher<void> *watcher = new QFutureWatcher<void>();
+ m_unzipTasks.insert(watcher, qobject_cast<QObject*> (task));
+ connect(watcher, &QFutureWatcherBase::finished, this, &MetadataJob::unzipTaskFinished);
+ watcher->setFuture(QtConcurrent::run(&UnzipArchiveTask::doTask, task));
+ }
+ } else {
+ emitFinished();
}
- } else {
- emitFinished();
}
} catch (const TaskException &e) {
reset();
@@ -410,6 +410,30 @@ void MetadataJob::metadataTaskFinished()
// -- private
+bool MetadataJob::fetchMetaDataPackages()
+{
+ //Download files in chunks. QtConcurrent will choke if too many task is given to it
+ int chunkSize = qMin(m_packages.length(), m_downloadableChunkSize);
+ QList<FileTaskItem> tempPackages = m_packages.mid(0, chunkSize);
+ m_packages = m_packages.mid(chunkSize, m_packages.length());
+ if (tempPackages.length() > 0) {
+ m_taskNumber++;
+ setProcessedAmount(0);
+ DownloadFileTask *const metadataTask = new DownloadFileTask(tempPackages);
+ metadataTask->setProxyFactory(m_core->proxyFactory());
+ m_metadataTask.setFuture(QtConcurrent::run(&DownloadFileTask::doTask, metadataTask));
+ setProgressTotalAmount(100);
+ QString metaInformation;
+ if (m_totalTaskCount > 1)
+ metaInformation = tr("Retrieving meta information from remote repository... %1/%2 ").arg(m_taskNumber).arg(m_totalTaskCount);
+ else
+ metaInformation = tr("Retrieving meta information from remote repository... ");
+ emit infoMessage(this, metaInformation);
+ return true;
+ }
+ return false;
+}
+
void MetadataJob::reset()
{
m_packages.clear();
@@ -615,6 +639,9 @@ MetadataJob::Status MetadataJob::parseUpdatesXml(const QList<FileTaskResult> &re
}
}
}
+ double taskCount = m_packages.length()/static_cast<double>(m_downloadableChunkSize);
+ m_totalTaskCount = qCeil(taskCount);
+
return XmlDownloadSuccess;
}
diff --git a/src/libs/installer/metadatajob.h b/src/libs/installer/metadatajob.h
index c6d5ad353..f3f480f6c 100644
--- a/src/libs/installer/metadatajob.h
+++ b/src/libs/installer/metadatajob.h
@@ -79,6 +79,7 @@ private slots:
void startXMLTask(const QList<FileTaskItem> items);
private:
+ bool fetchMetaDataPackages();
void startUnzipRepositoryTask(const Repository &repo);
void reset();
void resetCompressedFetch();
@@ -96,6 +97,10 @@ private:
QHash<QFutureWatcher<void> *, QObject*> m_unzipRepositoryTasks;
bool m_addCompressedPackages;
QList<FileTaskItem> m_unzipRepositoryitems;
+ QList<FileTaskResult> m_metadataResult;
+ int m_downloadableChunkSize;
+ int m_taskNumber;
+ int m_totalTaskCount;
};
} // namespace QInstaller
diff --git a/src/libs/installer/packagemanagercore_p.cpp b/src/libs/installer/packagemanagercore_p.cpp
index 57f430778..2577f09fc 100644
--- a/src/libs/installer/packagemanagercore_p.cpp
+++ b/src/libs/installer/packagemanagercore_p.cpp
@@ -378,11 +378,15 @@ bool PackageManagerCorePrivate::buildComponentTree(QHash<QString, Component*> &c
// now we can preselect components in the tree
foreach (QInstaller::Component *component, components) {
// set the checked state for all components without child (means without tristate)
+ // set checked state also for installed virtual tristate componets as otherwise
+ // those will be uninstalled
if (component->isCheckable() && !component->isTristate()) {
if (component->isDefault() && isInstaller())
component->setCheckState(Qt::Checked);
else if (component->isInstalled())
component->setCheckState(Qt::Checked);
+ } else if (component->isVirtual() && component->isInstalled() && component->isTristate()) {
+ component->setCheckState(Qt::Checked);
}
}
diff --git a/src/libs/installer/uninstallercalculator.cpp b/src/libs/installer/uninstallercalculator.cpp
index 9e669c8cf..20ad3c049 100644
--- a/src/libs/installer/uninstallercalculator.cpp
+++ b/src/libs/installer/uninstallercalculator.cpp
@@ -99,13 +99,21 @@ void UninstallerCalculator::appendComponentsToUninstall(const QList<Component*>
const QString replaces = c->value(scReplaces);
const QStringList possibleNames = replaces.split(QInstaller::commaRegExp(),
QString::SkipEmptyParts) << c->name();
- foreach (const QString &possibleName, possibleNames)
- autoDependencies.removeAll(possibleName);
+ foreach (const QString &possibleName, possibleNames) {
+
+ Component *cc = PackageManagerCore::componentByName(possibleName, m_installedComponents);
+ if (cc && (cc->installAction() != ComponentModelHelper::AutodependUninstallation)) {
+ autoDependencies.removeAll(possibleName);
+
+ }
+ }
}
- // A component requested auto installation, keep it to resolve their dependencies as well.
- if (!autoDependencies.isEmpty())
+ // A component requested auto uninstallation, keep it to resolve their dependencies as well.
+ if (!autoDependencies.isEmpty()) {
autoDependOnList.append(component);
+ component->setInstallAction(ComponentModelHelper::AutodependUninstallation);
+ }
}
}