diff options
Diffstat (limited to 'src/libs/installer')
-rw-r--r-- | src/libs/installer/component_p.h | 3 | ||||
-rw-r--r-- | src/libs/installer/componentmodel.cpp | 8 | ||||
-rw-r--r-- | src/libs/installer/metadatajob.cpp | 67 | ||||
-rw-r--r-- | src/libs/installer/metadatajob.h | 5 | ||||
-rw-r--r-- | src/libs/installer/packagemanagercore_p.cpp | 4 | ||||
-rw-r--r-- | src/libs/installer/uninstallercalculator.cpp | 16 |
6 files changed, 76 insertions, 27 deletions
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); + } } } |