summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/libs/installer/metadatajob.cpp155
-rw-r--r--src/libs/installer/metadatajob.h7
-rw-r--r--src/libs/installer/metadatajob_p.h2
-rw-r--r--src/libs/installer/packagemanagercore.cpp45
-rw-r--r--src/libs/installer/packagemanagercore.h7
-rw-r--r--src/libs/installer/packagemanagercore_p.cpp94
-rw-r--r--src/libs/installer/packagemanagercore_p.h7
-rw-r--r--src/libs/installer/packagemanagergui.cpp112
-rw-r--r--src/libs/installer/packagemanagergui.h1
-rw-r--r--src/libs/installer/repository.cpp35
-rw-r--r--src/libs/installer/repository.h7
-rw-r--r--src/libs/kdtools/task.cpp2
-rw-r--r--src/libs/kdtools/updatefinder.cpp11
-rw-r--r--src/libs/kdtools/updatefinder.h4
-rw-r--r--src/sdk/commandlineparser.cpp5
-rw-r--r--src/sdk/constants.h1
-rw-r--r--src/sdk/installerbase.cpp8
17 files changed, 438 insertions, 65 deletions
diff --git a/src/libs/installer/metadatajob.cpp b/src/libs/installer/metadatajob.cpp
index b010209c3..b3301c761 100644
--- a/src/libs/installer/metadatajob.cpp
+++ b/src/libs/installer/metadatajob.cpp
@@ -55,6 +55,7 @@ static QUrl resolveUrl(const FileTaskResult &result, const QString &url)
MetadataJob::MetadataJob(QObject *parent)
: Job(parent)
, m_core(0)
+ , m_addCompressedPackages(false)
{
setCapabilities(Cancelable);
connect(&m_xmlTask, &QFutureWatcherBase::finished, this, &MetadataJob::xmlTaskFinished);
@@ -77,48 +78,142 @@ Repository MetadataJob::repositoryForDirectory(const QString &directory) const
void MetadataJob::doStart()
{
- reset();
if (!m_core) {
emitFinishedWithError(Job::Canceled, tr("Missing package manager core engine."));
return; // We can't do anything here without core, so avoid tons of !m_core checks.
}
-
- emit infoMessage(this, tr("Preparing meta information download..."));
- const bool onlineInstaller = m_core->isInstaller() && !m_core->isOfflineOnly();
- if (onlineInstaller || m_core->isMaintainer()) {
- QList<FileTaskItem> items;
- const ProductKeyCheck *const productKeyCheck = ProductKeyCheck::instance();
- foreach (const Repository &repo, m_core->settings().repositories()) {
- if (repo.isEnabled() && productKeyCheck->isValidRepository(repo)) {
- QAuthenticator authenticator;
- authenticator.setUser(repo.username());
- authenticator.setPassword(repo.password());
-
- QString url = repo.url().toString() + QLatin1String("/Updates.xml?");
- if (!m_core->value(scUrlQueryString).isEmpty())
- url += m_core->value(scUrlQueryString) + QLatin1Char('&');
-
- // also append a random string to avoid proxy caches
- FileTaskItem item(url.append(QString::number(qrand() * qrand())));
- item.insert(TaskRole::UserRole, QVariant::fromValue(repo));
- item.insert(TaskRole::Authenticator, QVariant::fromValue(authenticator));
- items.append(item);
+ const ProductKeyCheck *const productKeyCheck = ProductKeyCheck::instance();
+ if (!m_addCompressedPackages) {
+ reset();
+ emit infoMessage(this, tr("Preparing meta information download..."));
+ const bool onlineInstaller = m_core->isInstaller() && !m_core->isOfflineOnly();
+
+ if (onlineInstaller || m_core->isMaintainer()) {
+ QList<FileTaskItem> items;
+ foreach (const Repository &repo, m_core->settings().repositories()) {
+ if (repo.isEnabled() &&
+ productKeyCheck->isValidRepository(repo)) {
+ QAuthenticator authenticator;
+ authenticator.setUser(repo.username());
+ authenticator.setPassword(repo.password());
+
+ if (!repo.isCompressed()) {
+ QString url = repo.url().toString() + QLatin1String("/Updates.xml?");
+ if (!m_core->value(scUrlQueryString).isEmpty())
+ url += m_core->value(scUrlQueryString) + QLatin1Char('&');
+
+ // also append a random string to avoid proxy caches
+ FileTaskItem item(url.append(QString::number(qrand() * qrand())));
+ item.insert(TaskRole::UserRole, QVariant::fromValue(repo));
+ item.insert(TaskRole::Authenticator, QVariant::fromValue(authenticator));
+ items.append(item);
+ }
+ else {
+ qDebug() << "Trying to parse compressed repo as normal repository."\
+ "Check repository syntax.";
+ }
+ }
+ }
+ if (items.count() > 0) {
+ startXMLTask(items);
+ } else {
+ emitFinished();
}
+ } else {
+ emitFinished();
}
- DownloadFileTask *const xmlTask = new DownloadFileTask(items);
- xmlTask->setProxyFactory(m_core->proxyFactory());
- m_xmlTask.setFuture(QtConcurrent::run(&DownloadFileTask::doTask, xmlTask));
} else {
- emitFinished();
+ m_packages.clear();
+ bool repositoriesFound = false;
+ foreach (const Repository &repo, m_core->settings().repositories()) {
+ if (repo.isCompressed() && repo.isEnabled() &&
+ productKeyCheck->isValidRepository(repo)) {
+ repositoriesFound = true;
+ startUnzipRepositoryTask(repo);
+ }
+ }
+ if (!repositoriesFound)
+ emitFinished();
+ else
+ emit infoMessage(this, tr("Unpacking compressed repositories..."));
}
}
+void MetadataJob::startXMLTask(const QList<FileTaskItem> items)
+{
+ DownloadFileTask *const xmlTask = new DownloadFileTask(items);
+ xmlTask->setProxyFactory(m_core->proxyFactory());
+ m_xmlTask.setFuture(QtConcurrent::run(&DownloadFileTask::doTask, xmlTask));
+}
+
void MetadataJob::doCancel()
{
reset();
emitFinishedWithError(Job::Canceled, tr("Meta data download canceled."));
}
+void MetadataJob::startUnzipRepositoryTask(const Repository &repo)
+{
+ QTemporaryDir tempRepoDir(QDir::tempPath() + QLatin1String("/compressedRepo-XXXXXX"));
+ if (!tempRepoDir.isValid()) {
+ qDebug() << "Cannot create unique temporary directory.";
+ return;
+ }
+ tempRepoDir.setAutoRemove(false);
+ m_tempDirDeleter.add(tempRepoDir.path());
+ QString url = repo.url().toLocalFile();
+ UnzipArchiveTask *task = new UnzipArchiveTask(url, tempRepoDir.path());
+ QFutureWatcher<void> *watcher = new QFutureWatcher<void>();
+ m_unzipRepositoryTasks.insert(watcher, qobject_cast<QObject*> (task));
+ connect(watcher, &QFutureWatcherBase::finished, this,
+ &MetadataJob::unzipRepositoryTaskFinished);
+ connect(watcher, &QFutureWatcherBase::progressValueChanged, this,
+ &MetadataJob::progressChanged);
+ watcher->setFuture(QtConcurrent::run(&UnzipArchiveTask::doTask, task));
+}
+
+void MetadataJob::unzipRepositoryTaskFinished()
+{
+ QFutureWatcher<void> *watcher = static_cast<QFutureWatcher<void> *>(sender());
+ try {
+ watcher->waitForFinished(); // trigger possible exceptions
+ } catch (const UnzipArchiveException &e) {
+ reset();
+ emitFinishedWithError(QInstaller::ExtractionError, e.message());
+ } catch (const QUnhandledException &e) {
+ reset();
+ emitFinishedWithError(QInstaller::DownloadError, QLatin1String(e.what()));
+ } catch (...) {
+ reset();
+ emitFinishedWithError(QInstaller::DownloadError, tr("Unknown exception during extracting."));
+ }
+
+ QHashIterator<QFutureWatcher<void> *, QObject*> i(m_unzipRepositoryTasks);
+ while (i.hasNext()) {
+ i.next();
+ if (i.key() == watcher) {
+ UnzipArchiveTask *task = qobject_cast<UnzipArchiveTask*> (i.value());
+ QString url = task->target();
+
+ QUrl targetUrl = targetUrl.fromLocalFile(url);
+ Repository repo(targetUrl, false, true);
+ url = repo.url().toString() + QLatin1String("/Updates.xml");
+ FileTaskItem item(url);
+ item.insert(TaskRole::UserRole, QVariant::fromValue(repo));
+ m_unzipRepositoryitems.append(item);
+ }
+ }
+
+ //One can specify many zipped repository items at once. As the repositories are
+ //unzipped one by one, we collect here all items before parsing xml files from those.
+ delete m_unzipRepositoryTasks.value(watcher);
+ m_unzipRepositoryTasks.remove(watcher);
+ delete watcher;
+
+ if (m_unzipRepositoryitems.count() > 0 && m_unzipRepositoryTasks.isEmpty())
+ startXMLTask(m_unzipRepositoryitems);
+}
+
void MetadataJob::xmlTaskFinished()
{
Status status = XmlDownloadFailure;
@@ -291,6 +386,14 @@ void MetadataJob::reset()
foreach (QObject *const object, m_unzipTasks)
object->deleteLater();
m_unzipTasks.clear();
+
+ foreach (QFutureWatcher<void> *const watcher, m_unzipRepositoryTasks.keys()) {
+ watcher->cancel();
+ watcher->deleteLater();
+ }
+ foreach (QObject *const object, m_unzipRepositoryTasks)
+ object->deleteLater();
+ m_unzipRepositoryTasks.clear();
} catch (...) {}
m_tempDirDeleter.releaseAndDeleteAll();
}
diff --git a/src/libs/installer/metadatajob.h b/src/libs/installer/metadatajob.h
index 10fffe172..e59029940 100644
--- a/src/libs/installer/metadatajob.h
+++ b/src/libs/installer/metadatajob.h
@@ -69,6 +69,7 @@ public:
QList<Metadata> metadata() const { return m_metadata.values(); }
Repository repositoryForDirectory(const QString &directory) const;
void setPackageManagerCore(PackageManagerCore *core) { m_core = core; }
+ void addCompressedPackages(bool addCompressPackage) { m_addCompressedPackages = addCompressPackage;}
private slots:
void doStart();
@@ -78,8 +79,11 @@ private slots:
void unzipTaskFinished();
void metadataTaskFinished();
void progressChanged(int progress);
+ void unzipRepositoryTaskFinished();
+ void startXMLTask(const QList<FileTaskItem> items);
private:
+ void startUnzipRepositoryTask(const Repository &repo);
void reset();
Status parseUpdatesXml(const QList<FileTaskResult> &results);
@@ -92,6 +96,9 @@ private:
QFutureWatcher<FileTaskResult> m_xmlTask;
QFutureWatcher<FileTaskResult> m_metadataTask;
QHash<QFutureWatcher<void> *, QObject*> m_unzipTasks;
+ QHash<QFutureWatcher<void> *, QObject*> m_unzipRepositoryTasks;
+ bool m_addCompressedPackages;
+ QList<FileTaskItem> m_unzipRepositoryitems;
};
} // namespace QInstaller
diff --git a/src/libs/installer/metadatajob_p.h b/src/libs/installer/metadatajob_p.h
index a07c7a80f..7839eacb5 100644
--- a/src/libs/installer/metadatajob_p.h
+++ b/src/libs/installer/metadatajob_p.h
@@ -69,7 +69,7 @@ public:
UnzipArchiveTask(const QString &arcive, const QString &target)
: m_archive(arcive), m_targetDir(target)
{}
-
+ QString target() { return m_targetDir; }
void doTask(QFutureInterface<void> &fi)
{
fi.reportStarted();
diff --git a/src/libs/installer/packagemanagercore.cpp b/src/libs/installer/packagemanagercore.cpp
index 731171f61..971ca694d 100644
--- a/src/libs/installer/packagemanagercore.cpp
+++ b/src/libs/installer/packagemanagercore.cpp
@@ -1153,8 +1153,37 @@ PackagesList PackageManagerCore::remotePackages()
}
/*!
+ Checks for compressed packages to install. Returns \c true if newer versions exist
+ and they can be installed.
+*/
+bool PackageManagerCore::fetchCompressedPackagesTree()
+{
+ const LocalPackagesHash installedPackages = d->localInstalledPackages();
+ if (!isInstaller() && status() == Failure)
+ return false;
+
+ if (!d->fetchMetaInformationFromCompressedRepositories())
+ return false;
+
+ if (!d->addUpdateResourcesFromRepositories(true, true)) {
+ return false;
+ }
+
+ PackagesList packages;
+ const PackagesList &compPackages = d->compressedPackages();
+ if (compPackages.isEmpty())
+ return false;
+ packages.append(compPackages);
+ const PackagesList &rPackages = d->remotePackages();
+ packages.append(rPackages);
+
+ return fetchPackagesTree(packages, installedPackages);
+}
+
+
+/*!
Checks for packages to install. Returns \c true if newer versions exist
- and they can be installed and sets the status of the update to \c Success.
+ and they can be installed.
*/
bool PackageManagerCore::fetchRemotePackagesTree()
{
@@ -1177,6 +1206,9 @@ bool PackageManagerCore::fetchRemotePackagesTree()
if (!d->fetchMetaInformationFromRepositories())
return false;
+ if (!d->fetchMetaInformationFromCompressedRepositories())
+ return false;
+
if (!d->addUpdateResourcesFromRepositories(true))
return false;
@@ -1184,6 +1216,11 @@ bool PackageManagerCore::fetchRemotePackagesTree()
if (packages.isEmpty())
return false;
+ return fetchPackagesTree(packages, installedPackages);
+}
+
+bool PackageManagerCore::fetchPackagesTree(const PackagesList &packages, const LocalPackagesHash installedPackages) {
+
bool success = false;
if (!isUpdater()) {
success = fetchAllPackages(packages, installedPackages);
@@ -1366,12 +1403,12 @@ void PackageManagerCore::addUserRepositories(const QStringList &repositories)
\sa {installer::setTemporaryRepositories}{installer.setTemporaryRepositories}
\sa addUserRepositories()
*/
-void PackageManagerCore::setTemporaryRepositories(const QStringList &repositories, bool replace)
+void PackageManagerCore::setTemporaryRepositories(const QStringList &repositories, bool replace,
+ bool compressed)
{
QSet<Repository> repositorySet;
foreach (const QString &repository, repositories)
- repositorySet.insert(Repository::fromUserInput(repository));
-
+ repositorySet.insert(Repository::fromUserInput(repository, compressed));
settings().setTemporaryRepositories(repositorySet, replace);
}
diff --git a/src/libs/installer/packagemanagercore.h b/src/libs/installer/packagemanagercore.h
index eebc33c4b..6b2a42ace 100644
--- a/src/libs/installer/packagemanagercore.h
+++ b/src/libs/installer/packagemanagercore.h
@@ -127,6 +127,7 @@ public:
PackagesList remotePackages();
bool fetchRemotePackagesTree();
+ bool fetchCompressedPackagesTree();
bool run();
void reset(const QHash<QString, QString> &params);
@@ -181,8 +182,8 @@ public:
void setTestChecksum(bool test);
Q_INVOKABLE void addUserRepositories(const QStringList &repositories);
- Q_INVOKABLE void setTemporaryRepositories(const QStringList &repositories, bool replace = false);
-
+ Q_INVOKABLE void setTemporaryRepositories(const QStringList &repositories,
+ bool replace = false, bool compressed = false);
Q_INVOKABLE void autoAcceptMessageBoxes();
Q_INVOKABLE void autoRejectMessageBoxes();
Q_INVOKABLE void setMessageBoxAutomaticAnswer(const QString &identifier, int button);
@@ -340,6 +341,8 @@ private:
ComponentModel *componentModel(PackageManagerCore *core, const QString &objectName) const;
QList<Component *> componentsMarkedForInstallation() const;
+ bool fetchPackagesTree(const PackagesList &packages, const LocalPackagesHash installedPackages);
+
private:
PackageManagerCorePrivate *const d;
friend class PackageManagerCorePrivate;
diff --git a/src/libs/installer/packagemanagercore_p.cpp b/src/libs/installer/packagemanagercore_p.cpp
index b972545ce..58847dfec 100644
--- a/src/libs/installer/packagemanagercore_p.cpp
+++ b/src/libs/installer/packagemanagercore_p.cpp
@@ -185,6 +185,7 @@ static void deferredRename(const QString &oldName, const QString &newName, bool
PackageManagerCorePrivate::PackageManagerCorePrivate(PackageManagerCore *core)
: m_updateFinder(0)
+ , m_compressedFinder(0)
, m_localPackageHub(std::make_shared<LocalPackageHub>())
, m_core(core)
, m_updates(false)
@@ -206,6 +207,7 @@ PackageManagerCorePrivate::PackageManagerCorePrivate(PackageManagerCore *core)
PackageManagerCorePrivate::PackageManagerCorePrivate(PackageManagerCore *core, qint64 magicInstallerMaker,
const QList<OperationBlob> &performedOperations)
: m_updateFinder(0)
+ , m_compressedFinder(0)
, m_localPackageHub(std::make_shared<LocalPackageHub>())
, m_status(PackageManagerCore::Unfinished)
, m_needsHardRestart(false)
@@ -2131,6 +2133,29 @@ PackagesList PackageManagerCorePrivate::remotePackages()
return m_updateFinder->updates();
}
+PackagesList PackageManagerCorePrivate::compressedPackages()
+{
+ if (m_compressedUpdates && m_compressedFinder)
+ return m_compressedFinder->updates();
+ m_compressedUpdates = false;
+ delete m_compressedFinder;
+
+ m_compressedFinder = new KDUpdater::UpdateFinder;
+ m_compressedFinder->setAutoDelete(false);
+ m_compressedFinder->addCompressedPackage(true);
+ m_compressedFinder->setPackageSources(m_compressedPackageSources);
+
+ m_compressedFinder->setLocalPackageHub(m_localPackageHub);
+ m_compressedFinder->run();
+ if (m_compressedFinder->updates().isEmpty()) {
+ setStatus(PackageManagerCore::Failure, tr("Cannot retrieve remote tree %1.")
+ .arg(m_compressedFinder->errorString()));
+ return PackagesList();
+ }
+ m_compressedUpdates = true;
+ return m_compressedFinder->updates();
+}
+
/*!
Returns a hash containing the installed package name and it's associated package information. If
the application is running in installer mode or the local components file could not be parsed, the
@@ -2200,9 +2225,44 @@ bool PackageManagerCorePrivate::fetchMetaInformationFromRepositories()
return m_repoFetched;
}
-bool PackageManagerCorePrivate::addUpdateResourcesFromRepositories(bool parseChecksum)
+bool PackageManagerCorePrivate::fetchMetaInformationFromCompressedRepositories()
+{
+ bool compressedRepoFetched = false;
+
+ m_compressedUpdates = false;
+ m_updateSourcesAdded = false;
+
+ try {
+ //Tell MetadataJob that only compressed packages needed to be fetched and not all.
+ //We cannot do this in general fetch meta method as the compressed packages might be
+ //installed after components tree is generated
+ m_metadataJob.addCompressedPackages(true);
+ m_metadataJob.start();
+ m_metadataJob.waitForFinished();
+ m_metadataJob.addCompressedPackages(false);
+ } catch (Error &error) {
+ setStatus(PackageManagerCore::Failure, tr("Cannot retrieve meta information: %1")
+ .arg(error.message()));
+ return compressedRepoFetched;
+ }
+
+ if (m_metadataJob.error() != Job::NoError) {
+ switch (m_metadataJob.error()) {
+ case QInstaller::UserIgnoreError:
+ break; // we can simply ignore this error, the user knows about it
+ default:
+ setStatus(PackageManagerCore::Failure, m_metadataJob.errorString());
+ return compressedRepoFetched;
+ }
+ }
+
+ compressedRepoFetched = true;
+ return compressedRepoFetched;
+}
+
+bool PackageManagerCorePrivate::addUpdateResourcesFromRepositories(bool parseChecksum, bool compressedRepository)
{
- if (m_updateSourcesAdded)
+ if (!compressedRepository && m_updateSourcesAdded)
return m_updateSourcesAdded;
const QList<Metadata> metadata = m_metadataJob.metadata();
@@ -2210,15 +2270,21 @@ bool PackageManagerCorePrivate::addUpdateResourcesFromRepositories(bool parseChe
m_updateSourcesAdded = true;
return m_updateSourcesAdded;
}
-
- m_packageSources.clear();
- if (isInstaller())
- m_packageSources.insert(PackageSource(QUrl(QLatin1String("resource://metadata/")), 0));
-
- m_updates = false;
- m_updateSourcesAdded = false;
+ if (compressedRepository) {
+ m_compressedPackageSources.clear();
+ }
+ else {
+ m_packageSources.clear();
+ m_updates = false;
+ m_updateSourcesAdded = false;
+ if (isInstaller())
+ m_packageSources.insert(PackageSource(QUrl(QLatin1String("resource://metadata/")), 0));
+ }
foreach (const Metadata &data, metadata) {
+ if (compressedRepository && !data.repository.isCompressed()) {
+ continue;
+ }
if (statusCanceledOrFailed())
return false;
@@ -2251,11 +2317,15 @@ bool PackageManagerCorePrivate::addUpdateResourcesFromRepositories(bool parseChe
if (!checksum.isNull())
m_core->setTestChecksum(checksum.toElement().text().toLower() == scTrue);
}
- m_packageSources.insert(PackageSource(QUrl::fromLocalFile(data.directory), 1));
+ if (compressedRepository)
+ m_compressedPackageSources.insert(PackageSource(QUrl::fromLocalFile(data.directory), 1));
+ else
+ m_packageSources.insert(PackageSource(QUrl::fromLocalFile(data.directory), 1));
+
ProductKeyCheck::instance()->addPackagesFromXml(data.directory + QLatin1String("/Updates.xml"));
}
-
- if (m_packageSources.count() == 0) {
+ if ((compressedRepository && m_compressedPackageSources.count() == 0 ) ||
+ (!compressedRepository && m_packageSources.count() == 0)) {
setStatus(PackageManagerCore::Failure, tr("Cannot find any update source information."));
return false;
}
diff --git a/src/libs/installer/packagemanagercore_p.h b/src/libs/installer/packagemanagercore_p.h
index d78bd3e69..7377feff4 100644
--- a/src/libs/installer/packagemanagercore_p.h
+++ b/src/libs/installer/packagemanagercore_p.h
@@ -175,7 +175,9 @@ signals:
public:
UpdateFinder *m_updateFinder;
+ UpdateFinder *m_compressedFinder;
QSet<PackageSource> m_packageSources;
+ QSet<PackageSource> m_compressedPackageSources;
std::shared_ptr<LocalPackageHub> m_localPackageHub;
QStringList m_filesForDelayedDeletion;
@@ -227,9 +229,11 @@ private:
bool adminRightsGained, bool deleteOperation);
PackagesList remotePackages();
+ PackagesList compressedPackages();
LocalPackagesHash localInstalledPackages();
bool fetchMetaInformationFromRepositories();
- bool addUpdateResourcesFromRepositories(bool parseChecksum);
+ bool fetchMetaInformationFromCompressedRepositories();
+ bool addUpdateResourcesFromRepositories(bool parseChecksum, bool compressedRepository = false);
void processFilesForDelayedDeletion();
private:
@@ -237,6 +241,7 @@ private:
MetadataJob m_metadataJob;
bool m_updates;
+ bool m_compressedUpdates;
bool m_repoFetched;
bool m_updateSourcesAdded;
qint64 m_magicBinaryMarker;
diff --git a/src/libs/installer/packagemanagergui.cpp b/src/libs/installer/packagemanagergui.cpp
index ec558a7ab..18f8849f9 100644
--- a/src/libs/installer/packagemanagergui.cpp
+++ b/src/libs/installer/packagemanagergui.cpp
@@ -75,6 +75,7 @@
#include <QTreeView>
#include <QVBoxLayout>
#include <QShowEvent>
+#include <QFileDialog>
#ifdef Q_OS_WIN
# include <qt_windows.h>
@@ -1858,6 +1859,7 @@ public:
, m_allModel(m_core->defaultComponentModel())
, m_updaterModel(m_core->updaterComponentModel())
, m_currentModel(m_allModel)
+ , m_compressedButtonVisible(false)
{
m_treeView->setObjectName(QLatin1String("ComponentsTreeView"));
@@ -1873,17 +1875,21 @@ public:
m_descriptionLabel->setWordWrap(true);
m_descriptionLabel->setObjectName(QLatin1String("ComponentDescriptionLabel"));
- QVBoxLayout *vlayout = new QVBoxLayout;
- vlayout->addWidget(m_descriptionLabel);
+ m_vlayout = new QVBoxLayout;
+ m_vlayout->setObjectName(QLatin1String("VerticalLayout"));
+ m_vlayout->addWidget(m_descriptionLabel);
m_sizeLabel = new QLabel(q);
m_sizeLabel->setWordWrap(true);
- vlayout->addWidget(m_sizeLabel);
+ m_vlayout->addWidget(m_sizeLabel);
m_sizeLabel->setObjectName(QLatin1String("ComponentSizeLabel"));
- vlayout->addSpacerItem(new QSpacerItem(1, 1, QSizePolicy::MinimumExpanding,
+#ifdef INSTALLCOMPRESSED
+ allowCompressedRepositoryInstall();
+#endif
+ m_vlayout->addSpacerItem(new QSpacerItem(1, 1, QSizePolicy::MinimumExpanding,
QSizePolicy::MinimumExpanding));
- hlayout->addLayout(vlayout, 2);
+ hlayout->addLayout(m_vlayout, 2);
QVBoxLayout *layout = new QVBoxLayout(q);
layout->addLayout(hlayout, 1);
@@ -1929,6 +1935,40 @@ public:
layout->addLayout(hlayout);
}
+ void allowCompressedRepositoryInstall()
+ {
+ if (m_compressedButtonVisible) {
+ return;
+ }
+
+ connect(m_core, SIGNAL(metaJobProgress(int)), this, SLOT(onProgressChanged(int)));
+ connect(m_core, SIGNAL(metaJobInfoMessage(QString)), this, SLOT(setMessage(QString)));
+
+ m_bspLabel = new QLabel(ComponentSelectionPage::tr("To install new "\
+ "compressed repository, browse the repositories from your computer"),q);
+ m_bspLabel->setWordWrap(true);
+ m_bspLabel->setObjectName(QLatin1String("CompressedButtonLabel"));
+
+ m_vlayout->addSpacing(50);
+ m_vlayout->addWidget(m_bspLabel);
+
+
+ m_progressBar = new QProgressBar();
+ m_progressBar->setRange(0, 0);
+ m_progressBar->hide();
+ m_vlayout->addWidget(m_progressBar);
+ m_progressBar->setObjectName(QLatin1String("CompressedInstallProgressBar"));
+
+
+ m_installCompressButton = new QPushButton;
+ connect(m_installCompressButton, &QAbstractButton::clicked,
+ this, &ComponentSelectionPage::Private::selectCompressedPackage);
+ m_installCompressButton->setObjectName(QLatin1String("InstallCompressedPackageButton"));
+ m_installCompressButton->setText(ComponentSelectionPage::tr("&Browse BSP or 7z files..."));
+ m_vlayout->addWidget(m_installCompressButton);
+ m_compressedButtonVisible = true;
+ }
+
void updateTreeView()
{
m_checkDefault->setVisible(m_core->isInstaller() || m_core->isPackageManager());
@@ -2012,6 +2052,58 @@ public slots:
m_currentModel->setCheckedState(ComponentModel::AllUnchecked);
}
+ void selectCompressedPackage()
+ {
+ QString defaultDownloadDirectory =
+ QStandardPaths::writableLocation(QStandardPaths::DownloadLocation);
+ QStringList fileNames = QFileDialog::getOpenFileNames(NULL,
+ ComponentSelectionPage::tr("Open File"),defaultDownloadDirectory,
+ QLatin1String("QtBSP or 7z Files (*.qtbsp *.7z)"));
+
+ QSet<Repository> set;
+ foreach (QString fileName, fileNames) {
+ Repository repository = Repository::fromUserInput(fileName, true);
+ set.insert(repository);
+ }
+ if (set.count() > 0) {
+ m_progressBar->show();
+ m_installCompressButton->setEnabled(false);
+ QPushButton *const b = qobject_cast<QPushButton *>(q->gui()->button(QWizard::NextButton));
+ b->setEnabled(false);
+ m_core->settings().addTemporaryRepositories(set, false);
+ m_core->fetchCompressedPackagesTree();
+ updateTreeView();
+
+ m_progressBar->hide();
+ m_bspLabel->setText(ComponentSelectionPage::tr("To install new "\
+ "compressed repository, browse the repositories from your computer"));
+ m_installCompressButton->setEnabled(true);
+ b->setEnabled(true);
+ }
+ }
+
+ /*!
+ Updates the value of \a progress on the progress bar.
+ */
+ void onProgressChanged(int progress)
+ {
+ m_progressBar->setValue(progress);
+ }
+
+ /*!
+ Displays the message \a msg on the page.
+ */
+ void setMessage(const QString &msg)
+ {
+ if (m_progressBar->isVisible()) {
+ m_bspLabel->setText(msg);
+ }
+ else {
+ m_bspLabel->setText(ComponentSelectionPage::tr("To install new "\
+ "compressed repository, browse the repositories from your computer"));
+ }
+ }
+
void selectDefault()
{
m_currentModel->setCheckedState(ComponentModel::DefaultChecked);
@@ -2049,6 +2141,11 @@ public:
QPushButton *m_checkAll;
QPushButton *m_uncheckAll;
QPushButton *m_checkDefault;
+ QPushButton *m_installCompressButton;
+ QLabel *m_bspLabel;
+ QProgressBar *m_progressBar;
+ QVBoxLayout *m_vlayout;
+ bool m_compressedButtonVisible;
};
@@ -2167,6 +2264,11 @@ void ComponentSelectionPage::deselectComponent(const QString &id)
d->m_currentModel->setData(idx, Qt::Unchecked, Qt::CheckStateRole);
}
+void ComponentSelectionPage::allowCompressedRepositoryInstall()
+{
+ d->allowCompressedRepositoryInstall();
+}
+
void ComponentSelectionPage::setModified(bool modified)
{
setComplete(modified);
diff --git a/src/libs/installer/packagemanagergui.h b/src/libs/installer/packagemanagergui.h
index 2940df052..63d00b941 100644
--- a/src/libs/installer/packagemanagergui.h
+++ b/src/libs/installer/packagemanagergui.h
@@ -314,6 +314,7 @@ public:
Q_INVOKABLE void selectDefault();
Q_INVOKABLE void selectComponent(const QString &id);
Q_INVOKABLE void deselectComponent(const QString &id);
+ Q_INVOKABLE void allowCompressedRepositoryInstall();
protected:
void entering();
diff --git a/src/libs/installer/repository.cpp b/src/libs/installer/repository.cpp
index 9a501fdfe..280ff1c75 100644
--- a/src/libs/installer/repository.cpp
+++ b/src/libs/installer/repository.cpp
@@ -46,6 +46,7 @@ namespace QInstaller {
Repository::Repository()
: m_default(false)
, m_enabled(false)
+ , m_compressed(false)
{
registerMetaType();
}
@@ -60,28 +61,31 @@ Repository::Repository(const Repository &other)
, m_username(other.m_username)
, m_password(other.m_password)
, m_displayname(other.m_displayname)
+ , m_compressed(other.m_compressed)
{
registerMetaType();
}
/*!
- Constructs a new repository by setting its address to \a url and its default state.
+ Constructs a new repository by setting its address to \a url
+ and its default and \a compressed states.
*/
-Repository::Repository(const QUrl &url, bool isDefault)
+Repository::Repository(const QUrl &url, bool isDefault, bool compressed)
: m_url(url)
, m_default(isDefault)
, m_enabled(true)
+ , m_compressed(compressed)
{
registerMetaType();
}
/*!
- Constructs a new repository by setting its address to \a repositoryUrl as string and its
- default state.
+ Constructs a new repository by setting its address to \a repositoryUrl as
+ string and its \a compressed state.
Note: user and password can be inside the \a repositoryUrl string: http://user:password@repository.url
*/
-Repository Repository::fromUserInput(const QString &repositoryUrl)
+Repository Repository::fromUserInput(const QString &repositoryUrl, bool compressed)
{
QUrl url = QUrl::fromUserInput(repositoryUrl);
const QStringList supportedSchemes = KDUpdater::FileDownloaderFactory::supportedSchemes();
@@ -93,7 +97,7 @@ Repository Repository::fromUserInput(const QString &repositoryUrl)
url.setUserName(QString());
url.setPassword(QString());
- Repository repository(url, false);
+ Repository repository(url, false, compressed);
repository.setUsername(userName);
repository.setPassword(password);
return repository;
@@ -200,6 +204,22 @@ void Repository::setDisplayName(const QString &displayname)
}
/*!
+ Returns true if repository is compressed
+*/
+bool Repository::isCompressed() const
+{
+ return m_compressed;
+}
+
+/*!
+ Sets this repository to \a compressed state to know weather the repository
+ needs to be uncompressed before use.
+*/
+void Repository::setCompressed(bool compressed)
+{
+ m_compressed = compressed;
+}
+/*!
Compares the values of this repository to \a other and returns true if they are equal (same server,
default state, enabled state as well as username and password). \sa operator!=()
*/
@@ -232,6 +252,7 @@ const Repository &Repository::operator=(const Repository &other)
m_username = other.m_username;
m_password = other.m_password;
m_displayname = other.m_displayname;
+ m_compressed = other.m_compressed;
return *this;
}
@@ -244,7 +265,7 @@ void Repository::registerMetaType()
QDataStream &operator>>(QDataStream &istream, Repository &repository)
{
- QByteArray url, username, password, displayname;
+ QByteArray url, username, password, displayname, compressed;
istream >> url >> repository.m_default >> repository.m_enabled >> username >> password >> displayname;
repository.setUrl(QUrl::fromEncoded(QByteArray::fromBase64(url)));
repository.setUsername(QString::fromUtf8(QByteArray::fromBase64(username)));
diff --git a/src/libs/installer/repository.h b/src/libs/installer/repository.h
index 96e41d311..785b452fb 100644
--- a/src/libs/installer/repository.h
+++ b/src/libs/installer/repository.h
@@ -46,10 +46,10 @@ class INSTALLER_EXPORT Repository
public:
explicit Repository();
Repository(const Repository &other);
- explicit Repository(const QUrl &url, bool isDefault);
+ explicit Repository(const QUrl &url, bool isDefault, bool compressed = false);
static void registerMetaType();
- static Repository fromUserInput(const QString &repositoryUrl);
+ static Repository fromUserInput(const QString &repositoryUrl, bool compressed = false);
bool isValid() const;
bool isDefault() const;
@@ -69,6 +69,8 @@ public:
QString displayname() const;
void setDisplayName(const QString &displayname);
+ bool isCompressed() const;
+ void setCompressed(bool compressed);
bool operator==(const Repository &other) const;
bool operator!=(const Repository &other) const;
@@ -85,6 +87,7 @@ private:
QString m_username;
QString m_password;
QString m_displayname;
+ bool m_compressed;
};
inline uint qHash(const Repository &repository)
diff --git a/src/libs/kdtools/task.cpp b/src/libs/kdtools/task.cpp
index 14b774ea9..64e999ba2 100644
--- a/src/libs/kdtools/task.cpp
+++ b/src/libs/kdtools/task.cpp
@@ -183,7 +183,7 @@ void Task::run()
return;
}
- if (m_finished || m_stopped) {
+ if (m_stopped) {
qDebug("Trying to start a finished or canceled task");
return;
}
diff --git a/src/libs/kdtools/updatefinder.cpp b/src/libs/kdtools/updatefinder.cpp
index 25e587b17..8553fea2c 100644
--- a/src/libs/kdtools/updatefinder.cpp
+++ b/src/libs/kdtools/updatefinder.cpp
@@ -173,7 +173,8 @@ void UpdateFinder::Private::computeUpdates()
// 1. Downloading Update XML files from all the update sources
// 2. Matching updates with Package XML and figuring out available updates
- clear();
+ if (!q->isCompressedPackage())
+ clear();
cancel = false;
// First do some quick sanity checks on the packages info
@@ -399,7 +400,8 @@ void UpdateFinder::Private::createUpdateObjects(const PackageSource &source,
delete updates.take(name);
// Create and register the update
- updates.insert(name, new Update(source, info));
+ if (!q->isCompressedPackage() || value == Resolution::AddPackage)
+ updates.insert(name, new Update(source, info));
}
}
@@ -439,6 +441,10 @@ UpdateFinder::Private::Resolution UpdateFinder::Private::checkPriorityAndVersion
<< ", Source: " << QFileInfo(source.url.toLocalFile()).fileName() << "'";
return Resolution::RemoveExisting;
}
+ if (q->isCompressedPackage() && match == 0 && source.priority == existingPackage->packageSource().priority) {
+ //Same package with the same priority and version already exists
+ return Resolution::RemoveExisting;
+ }
return Resolution::KeepExisting; // otherwise keep existing
}
return Resolution::AddPackage;
@@ -453,6 +459,7 @@ UpdateFinder::Private::Resolution UpdateFinder::Private::checkPriorityAndVersion
*/
UpdateFinder::UpdateFinder()
: Task(QLatin1String("UpdateFinder"), Stoppable),
+ m_compressedPackage(false),
d(new Private(this))
{
}
diff --git a/src/libs/kdtools/updatefinder.h b/src/libs/kdtools/updatefinder.h
index 1fbebdd9a..ed943789f 100644
--- a/src/libs/kdtools/updatefinder.h
+++ b/src/libs/kdtools/updatefinder.h
@@ -58,7 +58,8 @@ public:
void setLocalPackageHub(std::weak_ptr<LocalPackageHub> hub);
void setPackageSources(const QSet<QInstaller::PackageSource> &sources);
-
+ void addCompressedPackage(bool add) { m_compressedPackage = add; }
+ bool isCompressedPackage() { return m_compressedPackage; }
private:
void doRun();
bool doStop();
@@ -66,6 +67,7 @@ private:
bool doResume();
private:
+ bool m_compressedPackage;
Private *d;
Q_PRIVATE_SLOT(d, void slotDownloadDone())
};
diff --git a/src/sdk/commandlineparser.cpp b/src/sdk/commandlineparser.cpp
index 6da318806..1dc7ca168 100644
--- a/src/sdk/commandlineparser.cpp
+++ b/src/sdk/commandlineparser.cpp
@@ -114,7 +114,10 @@ CommandLineParser::CommandLineParser()
"a value is omitted, the client will use a default instead. Note: The server process is "
"not started by the client application in that case, you need to start it on your own."),
QLatin1String("socketname,key")));
-
+ m_parser.addOption(QCommandLineOption(QLatin1String(CommandLineOptions::InstallCompressedRepository),
+ QLatin1String("Installs QtBSP or 7z file. The QtBSP (Board Support Package) file must be a .7z "
+ "file which contains a valid repository."),
+ QLatin1String("URI,...")));
m_parser.addPositionalArgument(QLatin1String(CommandLineOptions::KeyValue),
QLatin1String("Key Value pair to be set."));
}
diff --git a/src/sdk/constants.h b/src/sdk/constants.h
index a322df09b..763377a08 100644
--- a/src/sdk/constants.h
+++ b/src/sdk/constants.h
@@ -56,6 +56,7 @@ const char AddTmpRepository[] = "addTempRepository";
const char SetTmpRepository[] = "setTempRepository";
const char StartServer[] = "startserver";
const char StartClient[] = "startclient";
+const char InstallCompressedRepository[] = "installCompressedRepository";
} // namespace CommandLineOptions
diff --git a/src/sdk/installerbase.cpp b/src/sdk/installerbase.cpp
index c99a48aa8..ec3a87a8d 100644
--- a/src/sdk/installerbase.cpp
+++ b/src/sdk/installerbase.cpp
@@ -217,6 +217,14 @@ int InstallerBase::run()
m_core->setTemporaryRepositories(repoList, true);
}
+ if (parser.isSet(QLatin1String(CommandLineOptions::InstallCompressedRepository))) {
+ const QStringList repoList = repositories(parser
+ .value(QLatin1String(CommandLineOptions::InstallCompressedRepository)));
+ if (repoList.isEmpty())
+ throw QInstaller::Error(QLatin1String("Empty repository list for option 'installCompressedRepository'."));
+ m_core->setTemporaryRepositories(repoList, false, true);
+ }
+
QInstaller::PackageManagerCore::setNoForceInstallation(parser
.isSet(QLatin1String(CommandLineOptions::NoForceInstallation)));
QInstaller::PackageManagerCore::setCreateLocalRepositoryFromBinary(parser