2011-02-21 16:30:31 +01:00
|
|
|
/**************************************************************************
|
|
|
|
**
|
|
|
|
** This file is part of Qt SDK**
|
|
|
|
**
|
|
|
|
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).*
|
|
|
|
**
|
|
|
|
** Contact: Nokia Corporation qt-info@nokia.com**
|
|
|
|
**
|
|
|
|
** No Commercial Usage
|
|
|
|
**
|
|
|
|
** This file contains pre-release code and may not be distributed.
|
|
|
|
** You may use this file in accordance with the terms and conditions
|
|
|
|
** contained in the Technology Preview License Agreement accompanying
|
|
|
|
** this package.
|
|
|
|
**
|
|
|
|
** GNU Lesser General Public License Usage
|
|
|
|
**
|
|
|
|
** This file may be used under the terms of the GNU Lesser General Public
|
|
|
|
** License version 2.1 as published by the Free Software Foundation and
|
|
|
|
** appearing in the file LICENSE.LGPL included in the packaging of this file.
|
|
|
|
** Please review the following information to ensure the GNU Lesser General
|
|
|
|
** Public License version 2.1 requirements will be met:
|
|
|
|
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
|
|
|
**
|
|
|
|
** In addition, as a special exception, Nokia gives you certain additional
|
|
|
|
** rights. These rights are described in the Nokia Qt LGPL Exception version
|
|
|
|
** 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
|
|
|
**
|
|
|
|
** If you are unsure which license is appropriate for your use, please contact
|
|
|
|
** (qt-info@nokia.com).
|
|
|
|
**
|
|
|
|
**************************************************************************/
|
|
|
|
#include "qinstallercomponent.h"
|
|
|
|
|
|
|
|
#include "common/errors.h"
|
2011-03-10 18:36:07 +01:00
|
|
|
#include "common/fileutils.h"
|
2011-03-09 12:45:22 +01:00
|
|
|
#include "common/utils.h"
|
|
|
|
#include "fsengineclient.h"
|
2011-02-21 16:30:31 +01:00
|
|
|
#include "lib7z_facade.h"
|
2011-03-09 12:45:22 +01:00
|
|
|
#include "qinstaller.h"
|
2011-03-23 21:09:14 +01:00
|
|
|
#include "qinstallercomponent_p.h"
|
2011-03-09 12:45:22 +01:00
|
|
|
#include "qinstallerglobal.h"
|
|
|
|
#include "messageboxhandler.h"
|
2011-02-21 16:30:31 +01:00
|
|
|
|
|
|
|
#include <KDUpdater/Update>
|
2011-03-10 18:36:07 +01:00
|
|
|
#include <KDUpdater/UpdateSourcesInfo>
|
2011-02-21 16:30:31 +01:00
|
|
|
#include <KDUpdater/UpdateOperation>
|
|
|
|
#include <KDUpdater/UpdateOperationFactory>
|
2011-03-10 18:36:07 +01:00
|
|
|
#include <KDUpdater/PackagesInfo>
|
2011-02-21 16:30:31 +01:00
|
|
|
|
2011-03-09 12:45:22 +01:00
|
|
|
#include <QtCore/QDirIterator>
|
|
|
|
#include <QtCore/QTranslator>
|
2011-03-23 21:09:14 +01:00
|
|
|
|
|
|
|
#include <QtGui/QApplication>
|
|
|
|
|
2011-03-09 12:45:22 +01:00
|
|
|
#include <QtUiTools/QUiLoader>
|
2011-02-21 16:30:31 +01:00
|
|
|
|
2011-04-01 10:20:07 +02:00
|
|
|
#include <algorithm>
|
|
|
|
|
2011-02-21 16:30:31 +01:00
|
|
|
using namespace QInstaller;
|
|
|
|
|
2011-03-17 15:13:11 +01:00
|
|
|
static const QLatin1String skName("Name");
|
|
|
|
static const QLatin1String skDisplayName("DisplayName");
|
|
|
|
static const QLatin1String skDescription("Description");
|
|
|
|
static const QLatin1String skCompressedSize("CompressedSize");
|
|
|
|
static const QLatin1String skUncompressedSize("UncompressedSize");
|
|
|
|
static const QLatin1String skVersion("Version");
|
|
|
|
static const QLatin1String skDependencies("Dependencies");
|
|
|
|
static const QLatin1String skReleaseDate("ReleaseDate");
|
|
|
|
static const QLatin1String skReplaces("Replaces");
|
|
|
|
static const QLatin1String skVirtual("Virtual");
|
|
|
|
static const QLatin1String skSortingPriority("SortingPriority");
|
|
|
|
static const QLatin1String skInstallPriority("InstallPriority");
|
|
|
|
static const QLatin1String skAutoSelectOn("AutoSelectOn");
|
|
|
|
static const QLatin1String skImportant("Important");
|
|
|
|
static const QLatin1String skForcedInstallation("ForcedInstallation");
|
|
|
|
static const QLatin1String skUpdateText("UpdateText");
|
|
|
|
static const QLatin1String skRequiresAdminRights("RequiresAdminRights");
|
|
|
|
static const QLatin1String skNewComponent("NewComponent");
|
|
|
|
static const QLatin1String skScript("Script");
|
2011-04-01 13:55:31 +02:00
|
|
|
static const QLatin1String skInstalledVersion("InstalledVersion");
|
2011-03-17 15:13:11 +01:00
|
|
|
|
2011-04-12 15:57:21 +02:00
|
|
|
static const QLatin1String skTrue("true");
|
|
|
|
static const QLatin1String skFalse("false");
|
|
|
|
|
2011-04-12 15:32:46 +02:00
|
|
|
static const QLatin1String skInstalled("Installed");
|
|
|
|
static const QLatin1String skUninstalled("Uninstalled");
|
|
|
|
static const QLatin1String skCurrentState("CurrentState");
|
|
|
|
|
2011-02-21 16:30:31 +01:00
|
|
|
/*
|
2011-03-09 12:45:22 +01:00
|
|
|
TRANSLATOR QInstaller::Component
|
2011-02-21 16:30:31 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
/*!
|
2011-03-09 12:45:22 +01:00
|
|
|
\class QInstaller::Component
|
|
|
|
Component describes a component within the installer.
|
2011-02-21 16:30:31 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
/*!
|
2011-03-09 12:45:22 +01:00
|
|
|
Constructor. Creates a new Component inside of \a installer.
|
2011-02-21 16:30:31 +01:00
|
|
|
*/
|
|
|
|
Component::Component(Installer *installer)
|
2011-03-23 21:09:14 +01:00
|
|
|
: d(new ComponentPrivate(installer, this))
|
2011-02-21 16:30:31 +01:00
|
|
|
{
|
|
|
|
d->init();
|
2011-03-23 22:30:29 +01:00
|
|
|
setPrivate(d);
|
2011-04-01 13:55:31 +02:00
|
|
|
|
|
|
|
connect(this, SIGNAL(valueChanged(QString, QString)), this, SLOT(updateModelData(QString, QString)));
|
2011-02-21 16:30:31 +01:00
|
|
|
}
|
|
|
|
|
2011-03-09 12:45:22 +01:00
|
|
|
Component::Component(KDUpdater::Update* update, Installer* installer)
|
2011-03-23 21:09:14 +01:00
|
|
|
: d(new ComponentPrivate(installer, this))
|
2011-03-09 12:45:22 +01:00
|
|
|
{
|
|
|
|
Q_ASSERT(update);
|
2011-03-21 13:28:55 +01:00
|
|
|
|
2011-02-21 16:30:31 +01:00
|
|
|
d->init();
|
2011-03-23 22:30:29 +01:00
|
|
|
setPrivate(d);
|
2011-04-01 13:55:31 +02:00
|
|
|
connect(this, SIGNAL(valueChanged(QString, QString)), this, SLOT(updateModelData(QString, QString)));
|
|
|
|
|
2011-03-21 13:28:55 +01:00
|
|
|
loadDataFromUpdate(update);
|
2011-02-21 16:30:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
2011-03-09 12:45:22 +01:00
|
|
|
Destroys the Component.
|
2011-02-21 16:30:31 +01:00
|
|
|
*/
|
|
|
|
Component::~Component()
|
|
|
|
{
|
2011-03-09 12:45:22 +01:00
|
|
|
if (parentComponent() != 0)
|
2011-04-13 11:06:16 +02:00
|
|
|
d->m_parentComponent->d->m_allComponents.removeAll(this);
|
2011-02-21 16:30:31 +01:00
|
|
|
|
|
|
|
if (!d->m_newlyInstalled)
|
2011-04-13 11:06:16 +02:00
|
|
|
qDeleteAll(d->m_operations);
|
2011-02-21 16:30:31 +01:00
|
|
|
|
2011-04-01 10:20:07 +02:00
|
|
|
qDeleteAll(d->m_allComponents);
|
2011-02-21 16:30:31 +01:00
|
|
|
delete d;
|
|
|
|
}
|
|
|
|
|
2011-03-10 18:36:07 +01:00
|
|
|
//package info is that what is saved inside the packagemanager on harddisk
|
|
|
|
void Component::loadDataFromPackageInfo(const KDUpdater::PackageInfo &packageInfo)
|
|
|
|
{
|
2011-03-17 15:13:11 +01:00
|
|
|
setValue(skName, packageInfo.name);
|
|
|
|
setValue(skDisplayName, packageInfo.title);
|
|
|
|
setValue(skDescription, packageInfo.description);
|
|
|
|
setValue(skUncompressedSize, QString::number(packageInfo.uncompressedSize));
|
|
|
|
setValue(skVersion, packageInfo.version);
|
2011-04-12 15:57:21 +02:00
|
|
|
setValue(skVirtual, packageInfo.virtualComp ? skTrue : skFalse);
|
2011-03-11 12:39:45 +01:00
|
|
|
|
2011-03-10 18:36:07 +01:00
|
|
|
QString dependstr = QLatin1String("");
|
|
|
|
foreach (const QString& val, packageInfo.dependencies)
|
2011-03-11 12:39:45 +01:00
|
|
|
dependstr += val + QLatin1String(",");
|
|
|
|
|
2011-03-10 18:36:07 +01:00
|
|
|
if (packageInfo.dependencies.count() > 0)
|
|
|
|
dependstr.chop(1);
|
2011-03-17 15:13:11 +01:00
|
|
|
setValue(skDependencies, dependstr);
|
2011-03-11 12:39:45 +01:00
|
|
|
|
2011-04-12 15:57:21 +02:00
|
|
|
setValue(skForcedInstallation, packageInfo.forcedInstallation ? skTrue : skFalse);
|
2011-03-16 10:22:13 +01:00
|
|
|
if (packageInfo.forcedInstallation) {
|
2011-04-12 11:21:20 +02:00
|
|
|
setEnabled(false);
|
|
|
|
setCheckable(false);
|
|
|
|
setCheckState(Qt::Checked);
|
2011-03-16 10:22:13 +01:00
|
|
|
}
|
2011-03-10 18:36:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
//update means it is the packageinfo from server
|
|
|
|
void Component::loadDataFromUpdate(KDUpdater::Update* update)
|
|
|
|
{
|
|
|
|
Q_ASSERT(update);
|
|
|
|
Q_ASSERT(!update->name().isEmpty());
|
|
|
|
|
2011-03-17 15:13:11 +01:00
|
|
|
setValue(skName, update->data(skName).toString());
|
|
|
|
setValue(skDisplayName, update->data(skDisplayName).toString());
|
|
|
|
setValue(skDescription, update->data(skDescription).toString());
|
|
|
|
setValue(skCompressedSize, QString::number(update->compressedSize()));
|
|
|
|
setValue(skUncompressedSize, QString::number(update->uncompressedSize()));
|
|
|
|
setValue(skVersion, update->data(skVersion).toString());
|
|
|
|
setValue(skDependencies, update->data(skDependencies).toString());
|
|
|
|
setValue(skVirtual, update->data(skVirtual).toString());
|
|
|
|
setValue(skSortingPriority, update->data(skSortingPriority).toString());
|
|
|
|
setValue(skInstallPriority, update->data(skInstallPriority).toString());
|
|
|
|
setValue(skAutoSelectOn, update->data(skAutoSelectOn).toString());
|
|
|
|
|
|
|
|
setValue(skImportant, update->data(skImportant).toString());
|
|
|
|
setValue(skUpdateText, update->data(skUpdateText).toString());
|
|
|
|
setValue(skNewComponent, update->data(skNewComponent).toString());
|
|
|
|
setValue(skRequiresAdminRights, update->data(skRequiresAdminRights).toString());
|
|
|
|
|
|
|
|
setValue(skScript, update->data(skScript).toString());
|
|
|
|
setValue(skReplaces, update->data(skReplaces).toString());
|
|
|
|
setValue(skReleaseDate, update->data(skReleaseDate).toString());
|
|
|
|
|
2011-04-12 15:57:21 +02:00
|
|
|
QString forced = update->data(skForcedInstallation, skFalse).toString().toLower();
|
2011-03-15 19:48:38 +01:00
|
|
|
if (qApp->arguments().contains(QLatin1String("--no-force-installations")))
|
2011-04-12 15:57:21 +02:00
|
|
|
forced = skFalse;
|
2011-03-17 15:13:11 +01:00
|
|
|
setValue(skForcedInstallation, forced);
|
2011-04-12 15:57:21 +02:00
|
|
|
if (forced == skTrue) {
|
2011-04-12 11:21:20 +02:00
|
|
|
setEnabled(false);
|
|
|
|
setCheckable(false);
|
|
|
|
setCheckState(Qt::Checked);
|
|
|
|
}
|
2011-03-10 18:36:07 +01:00
|
|
|
|
2011-03-17 15:13:11 +01:00
|
|
|
setLocalTempPath(QInstaller::pathFromUrl(update->sourceInfo().url));
|
2011-03-10 18:36:07 +01:00
|
|
|
const QStringList uis = update->data(QLatin1String("UserInterfaces")).toString()
|
|
|
|
.split(QString::fromLatin1(","), QString::SkipEmptyParts);
|
2011-03-17 15:13:11 +01:00
|
|
|
if (!uis.isEmpty())
|
|
|
|
loadUserInterfaces(QDir(QString::fromLatin1("%1/%2").arg(localTempPath(), name())), uis);
|
2011-03-10 18:36:07 +01:00
|
|
|
|
|
|
|
const QStringList qms = update->data(QLatin1String("Translations")).toString()
|
|
|
|
.split(QString::fromLatin1(","), QString::SkipEmptyParts);
|
2011-03-17 15:13:11 +01:00
|
|
|
if (!qms.isEmpty())
|
|
|
|
loadTranslations(QDir(QString::fromLatin1("%1/%2").arg(localTempPath(), name())), qms);
|
2011-03-10 18:36:07 +01:00
|
|
|
|
|
|
|
QHash<QString, QVariant> licenseHash = update->data(QLatin1String("Licenses")).toHash();
|
2011-03-17 15:13:11 +01:00
|
|
|
if (!licenseHash.isEmpty())
|
|
|
|
loadLicenses(QString::fromLatin1("%1/%2/").arg(localTempPath(), name()), licenseHash);
|
2011-03-10 18:36:07 +01:00
|
|
|
}
|
|
|
|
|
2011-04-01 12:07:50 +02:00
|
|
|
QString Component::uncompressedSize() const
|
|
|
|
{
|
|
|
|
double size = value(skUncompressedSize).toDouble();
|
|
|
|
if (size < 10000.0)
|
|
|
|
return tr("%L1 Bytes").arg(size);
|
|
|
|
size /= 1024.0;
|
|
|
|
if (size < 10000.0)
|
|
|
|
return tr("%L1 kBytes").arg(size, 0, 'f', 1);
|
|
|
|
size /= 1024.0;
|
|
|
|
if (size < 10000.0)
|
|
|
|
return tr("%L1 MBytes").arg(size, 0, 'f', 1);
|
|
|
|
size /= 1024.0;
|
|
|
|
return tr("%L1 GBytes").arg(size, 0, 'f', 1);
|
|
|
|
}
|
|
|
|
|
2011-02-21 16:30:31 +01:00
|
|
|
void Component::markAsPerformedInstallation()
|
|
|
|
{
|
|
|
|
d->m_newlyInstalled = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
2011-03-09 12:45:22 +01:00
|
|
|
\property Component::removeBeforeUpdate
|
|
|
|
Specifies wheter this component gets removed by the installer system before it gets updated.
|
|
|
|
Get this property's value by using %removeBeforeUpdate(), and set it
|
|
|
|
using %setRemoveBeforeUpdate(). The default value is true.
|
|
|
|
*/
|
2011-02-21 16:30:31 +01:00
|
|
|
bool Component::removeBeforeUpdate() const
|
|
|
|
{
|
2011-04-13 11:06:16 +02:00
|
|
|
return d->m_removeBeforeUpdate;
|
2011-02-21 16:30:31 +01:00
|
|
|
}
|
|
|
|
|
2011-03-09 12:45:22 +01:00
|
|
|
void Component::setRemoveBeforeUpdate(bool removeBeforeUpdate)
|
2011-02-21 16:30:31 +01:00
|
|
|
{
|
2011-04-13 11:06:16 +02:00
|
|
|
d->m_removeBeforeUpdate = removeBeforeUpdate;
|
2011-02-21 16:30:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
QList<Component*> Component::dependees() const
|
|
|
|
{
|
2011-03-09 12:45:22 +01:00
|
|
|
return d->m_installer->dependees(this);
|
2011-02-21 16:30:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2011-03-09 12:45:22 +01:00
|
|
|
Returns a key/value based hash of all variables set for this component.
|
|
|
|
*/
|
2011-02-21 16:30:31 +01:00
|
|
|
QHash<QString,QString> Component::variables() const
|
|
|
|
{
|
|
|
|
return d->m_vars;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
2011-03-09 12:45:22 +01:00
|
|
|
Returns the value of variable name \a key.
|
|
|
|
If \a key is not known yet, \a defaultValue is returned.
|
|
|
|
*/
|
|
|
|
QString Component::value(const QString &key, const QString &defaultValue) const
|
2011-02-21 16:30:31 +01:00
|
|
|
{
|
|
|
|
return d->m_vars.value(key, defaultValue);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
2011-03-09 12:45:22 +01:00
|
|
|
Sets the value of the variable with \a key to \a value.
|
2011-02-21 16:30:31 +01:00
|
|
|
*/
|
|
|
|
void Component::setValue(const QString &key, const QString &value)
|
|
|
|
{
|
2011-04-12 09:50:34 +02:00
|
|
|
if (d->m_vars.value(key) == value)
|
2011-02-21 16:30:31 +01:00
|
|
|
return;
|
|
|
|
|
2011-03-09 12:45:22 +01:00
|
|
|
d->m_vars[key] = value;
|
|
|
|
emit valueChanged(key, value);
|
2011-02-21 16:30:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
2011-03-09 12:45:22 +01:00
|
|
|
Returnst the installer this component belongs to.
|
2011-02-21 16:30:31 +01:00
|
|
|
*/
|
|
|
|
Installer* Component::installer() const
|
|
|
|
{
|
|
|
|
return d->m_installer;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
2011-03-09 12:45:22 +01:00
|
|
|
Returns the parent of this component. If this component is com.nokia.sdk.qt, its
|
|
|
|
parent is com.nokia.sdk, as far as this exists.
|
|
|
|
*/
|
2011-04-13 11:06:16 +02:00
|
|
|
Component* Component::parentComponent() const
|
2011-02-21 16:30:31 +01:00
|
|
|
{
|
2011-04-13 11:06:16 +02:00
|
|
|
return d->m_parentComponent;
|
2011-02-21 16:30:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Appends \a component as a child of this component. If \a component already has a parent,
|
|
|
|
it is removed from the previous parent.
|
2011-03-09 12:45:22 +01:00
|
|
|
*/
|
|
|
|
void Component::appendComponent(Component* component)
|
2011-02-21 16:30:31 +01:00
|
|
|
{
|
2011-04-12 15:57:21 +02:00
|
|
|
if (component->value(skVirtual).toLower() != skTrue) {
|
2011-04-01 10:20:07 +02:00
|
|
|
d->m_components.append(component);
|
|
|
|
std::sort(d->m_components.begin(), d->m_components.end(), Component::SortingPriorityLessThan());
|
|
|
|
} else {
|
|
|
|
d->m_virtualComponents.append(component);
|
|
|
|
}
|
|
|
|
|
|
|
|
d->m_allComponents = d->m_components + d->m_virtualComponents;
|
|
|
|
if (Component *parent = component->parentComponent())
|
|
|
|
parent->removeComponent(component);
|
2011-04-13 11:06:16 +02:00
|
|
|
component->d->m_parentComponent = this;
|
2011-04-01 13:55:31 +02:00
|
|
|
setTristate(childCount() > 0);
|
2011-02-21 16:30:31 +01:00
|
|
|
}
|
|
|
|
|
2011-04-01 10:21:34 +02:00
|
|
|
/*!
|
|
|
|
Removes \a component if it is a child of this component. The component object still exists after the
|
|
|
|
function returns. It's up to the caller to delete the passed component.
|
|
|
|
*/
|
|
|
|
void Component::removeComponent(Component *component)
|
|
|
|
{
|
|
|
|
if (component->parentComponent() == this) {
|
2011-04-13 11:06:16 +02:00
|
|
|
component->d->m_parentComponent = 0;
|
2011-04-01 10:21:34 +02:00
|
|
|
d->m_components.removeAll(component);
|
|
|
|
d->m_virtualComponents.removeAll(component);
|
|
|
|
d->m_allComponents = d->m_components + d->m_virtualComponents;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-02-21 16:30:31 +01:00
|
|
|
/*!
|
2011-03-09 12:45:22 +01:00
|
|
|
Returns a list of child components. If \a recursive is set to true, the returned list
|
|
|
|
contains not only the direct children, but all ancestors.
|
|
|
|
*/
|
2011-04-12 10:10:52 +02:00
|
|
|
QList<Component*> Component::childComponents(bool recursive, RunMode runMode) const
|
2011-03-09 12:45:22 +01:00
|
|
|
{
|
2011-04-13 11:30:05 +02:00
|
|
|
QList<Component*> result;
|
2011-03-09 12:45:22 +01:00
|
|
|
if (runMode == UpdaterMode)
|
2011-04-13 11:30:05 +02:00
|
|
|
return result;
|
2011-03-09 12:45:22 +01:00
|
|
|
|
|
|
|
if (!recursive)
|
2011-04-01 10:20:07 +02:00
|
|
|
return d->m_allComponents;
|
2011-02-21 16:30:31 +01:00
|
|
|
|
2011-04-01 10:20:07 +02:00
|
|
|
foreach (Component *component, d->m_allComponents) {
|
2011-03-09 12:45:22 +01:00
|
|
|
result.append(component);
|
2011-04-13 11:30:05 +02:00
|
|
|
result += component->childComponents(true, runMode);
|
2011-02-21 16:30:31 +01:00
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
2011-03-09 12:45:22 +01:00
|
|
|
Contains this component's name (unique identifier).
|
|
|
|
*/
|
2011-02-21 16:30:31 +01:00
|
|
|
QString Component::name() const
|
|
|
|
{
|
2011-03-17 15:13:11 +01:00
|
|
|
return value(skName);
|
2011-02-21 16:30:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
2011-03-09 12:45:22 +01:00
|
|
|
Contains this component's display name (as visible to the user).
|
|
|
|
*/
|
2011-02-21 16:30:31 +01:00
|
|
|
QString Component::displayName() const
|
|
|
|
{
|
2011-03-17 15:13:11 +01:00
|
|
|
return value(skDisplayName);
|
2011-02-21 16:30:31 +01:00
|
|
|
}
|
|
|
|
|
2011-03-15 18:17:20 +01:00
|
|
|
void Component::loadComponentScript()
|
|
|
|
{
|
2011-03-17 15:13:11 +01:00
|
|
|
const QString script = value(skScript);
|
|
|
|
if (!localTempPath().isEmpty() && !script.isEmpty())
|
|
|
|
loadComponentScript(QString::fromLatin1("%1/%2/%3").arg(localTempPath(), name(), script));
|
2011-03-15 18:17:20 +01:00
|
|
|
}
|
|
|
|
|
2011-02-21 16:30:31 +01:00
|
|
|
/*!
|
2011-03-09 12:45:22 +01:00
|
|
|
Loads the script at \a fileName into this component's script engine. The installer and all its
|
|
|
|
components as well as other useful stuff are being exported into the script.
|
|
|
|
Read \link componentscripting Component Scripting \endlink for details.
|
|
|
|
\throws Error when either the script at \a fileName couldn't be opened, or the QScriptEngine
|
|
|
|
couldn't evaluate the script.
|
|
|
|
*/
|
|
|
|
void Component::loadComponentScript(const QString &fileName)
|
|
|
|
{
|
|
|
|
QFile file(fileName);
|
|
|
|
if (!file.open(QIODevice::ReadOnly)) {
|
|
|
|
throw Error(QObject::tr("Could not open the requested script file at %1: %2").arg(fileName,
|
|
|
|
file.errorString()));
|
2011-02-21 16:30:31 +01:00
|
|
|
}
|
|
|
|
|
2011-04-13 11:06:16 +02:00
|
|
|
d->m_scriptEngine.evaluate(QLatin1String(file.readAll()), fileName);
|
|
|
|
if (d->m_scriptEngine.hasUncaughtException()) {
|
2011-03-09 12:45:22 +01:00
|
|
|
throw Error(QObject::tr("Exception while loading the component script %1")
|
2011-04-13 11:06:16 +02:00
|
|
|
.arg(uncaughtExceptionString(&(d->m_scriptEngine)/*, QFileInfo(file).absoluteFilePath()*/)));
|
2011-02-21 16:30:31 +01:00
|
|
|
}
|
|
|
|
|
2011-03-16 17:05:03 +01:00
|
|
|
const QList<Component*> components = d->m_installer->components(true, d->m_installer->runMode());
|
2011-04-13 11:06:16 +02:00
|
|
|
QScriptValue comps = d->m_scriptEngine.newArray(components.count());
|
2011-03-09 12:45:22 +01:00
|
|
|
for (int i = 0; i < components.count(); ++i)
|
2011-04-13 11:06:16 +02:00
|
|
|
comps.setProperty(i, d->m_scriptEngine.newQObject(components[i]));
|
2011-03-09 12:45:22 +01:00
|
|
|
|
2011-04-13 11:06:16 +02:00
|
|
|
d->m_scriptEngine.globalObject().property(QLatin1String("installer"))
|
2011-03-09 12:45:22 +01:00
|
|
|
.setProperty(QLatin1String("components"), comps);
|
|
|
|
|
2011-04-13 11:06:16 +02:00
|
|
|
QScriptValue comp = d->m_scriptEngine.evaluate(QLatin1String("Component"));
|
|
|
|
if (!d->m_scriptEngine.hasUncaughtException()) {
|
|
|
|
d->m_scriptComponent = comp;
|
|
|
|
d->m_scriptComponent.construct();
|
2011-02-21 16:30:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
emit loaded();
|
|
|
|
languageChanged();
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
2011-03-09 12:45:22 +01:00
|
|
|
\internal
|
|
|
|
Calls the script method \link retranslateUi() \endlink, if any. This is done whenever a
|
|
|
|
QTranslator file is being loaded.
|
|
|
|
*/
|
2011-02-21 16:30:31 +01:00
|
|
|
void Component::languageChanged()
|
|
|
|
{
|
2011-03-09 12:45:22 +01:00
|
|
|
callScriptMethod(QLatin1String("retranslateUi"));
|
2011-02-21 16:30:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
2011-03-09 12:45:22 +01:00
|
|
|
Tries to call the method with \a name within the script and returns the result. If the method
|
|
|
|
doesn't exist, an invalid result is returned. If the method has an uncaught exception, its
|
|
|
|
string representation is thrown as an Error exception.
|
|
|
|
|
|
|
|
\note The method is not called, if the current script context is the same method, to avoid
|
|
|
|
infinite recursion.
|
|
|
|
*/
|
|
|
|
QScriptValue Component::callScriptMethod(const QString &methodName, const QScriptValueList& arguments)
|
|
|
|
{
|
2011-04-13 11:06:16 +02:00
|
|
|
if (!d->m_unexistingScriptMethods.value(methodName, true))
|
2011-02-21 16:30:31 +01:00
|
|
|
return QScriptValue();
|
|
|
|
|
|
|
|
// don't allow such a recursion
|
2011-04-13 11:06:16 +02:00
|
|
|
if (d->m_scriptEngine.currentContext()->backtrace().first().startsWith(methodName))
|
2011-02-21 16:30:31 +01:00
|
|
|
return QScriptValue();
|
|
|
|
|
2011-04-13 11:06:16 +02:00
|
|
|
QScriptValue method = d->m_scriptComponent.property(QString::fromLatin1("prototype"))
|
2011-03-09 12:45:22 +01:00
|
|
|
.property(methodName);
|
|
|
|
if (!method.isValid()) // this marks the method to be called not any longer
|
2011-04-13 11:06:16 +02:00
|
|
|
d->m_unexistingScriptMethods[methodName] = false;
|
2011-02-21 16:30:31 +01:00
|
|
|
|
2011-04-13 11:06:16 +02:00
|
|
|
const QScriptValue result = method.call(d->m_scriptComponent, arguments);
|
2011-03-09 12:45:22 +01:00
|
|
|
if (!result.isValid())
|
2011-02-21 16:30:31 +01:00
|
|
|
return result;
|
|
|
|
|
2011-04-13 11:06:16 +02:00
|
|
|
if (d->m_scriptEngine.hasUncaughtException())
|
|
|
|
throw Error(uncaughtExceptionString(&(d->m_scriptEngine)/*, name()*/));
|
2011-02-21 16:30:31 +01:00
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
2011-03-09 12:45:22 +01:00
|
|
|
Loads the translations matching the name filters \a qms inside \a directory. Only translations
|
|
|
|
with a \link QFileInfo::baseName() baseName \endlink matching the current locales \link
|
|
|
|
QLocale::name() name \endlink are loaded.
|
|
|
|
Read \ref componenttranslation for details.
|
|
|
|
*/
|
|
|
|
void Component::loadTranslations(const QDir& directory, const QStringList& qms)
|
|
|
|
{
|
|
|
|
QDirIterator it(directory.path(), qms, QDir::Files);
|
|
|
|
while (it.hasNext()) {
|
2011-02-21 16:30:31 +01:00
|
|
|
const QString filename = it.next();
|
2011-03-09 12:45:22 +01:00
|
|
|
if (QFileInfo(filename).baseName().toLower() != QLocale().name().toLower())
|
2011-02-21 16:30:31 +01:00
|
|
|
continue;
|
|
|
|
|
2011-03-09 12:45:22 +01:00
|
|
|
QScopedPointer<QTranslator> translator(new QTranslator(this));
|
|
|
|
if (!translator->load(filename))
|
|
|
|
throw Error(tr("Could not open the requested translation file at %1").arg(filename));
|
|
|
|
qApp->installTranslator(translator.take());
|
2011-02-21 16:30:31 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
2011-03-09 12:45:22 +01:00
|
|
|
Loads the user interface files matching the name filters \a uis inside \a directory. The loaded
|
|
|
|
interface can be accessed via userInterfaces by using the class name set in the ui file.
|
|
|
|
Read \ref componentuserinterfaces for details.
|
|
|
|
*/
|
|
|
|
void Component::loadUserInterfaces(const QDir& directory, const QStringList& uis)
|
2011-02-21 16:30:31 +01:00
|
|
|
{
|
2011-03-09 12:45:22 +01:00
|
|
|
if (QApplication::type() == QApplication::Tty)
|
2011-02-21 16:30:31 +01:00
|
|
|
return;
|
|
|
|
|
2011-03-09 12:45:22 +01:00
|
|
|
QDirIterator it(directory.path(), uis, QDir::Files);
|
|
|
|
while (it.hasNext()) {
|
|
|
|
QFile file(it.next());
|
|
|
|
if (!file.open(QIODevice::ReadOnly)) {
|
|
|
|
throw Error(tr("Could not open the requested UI file at %1: %2").arg(it.fileName(),
|
|
|
|
file.errorString()));
|
|
|
|
}
|
2011-02-21 16:30:31 +01:00
|
|
|
|
|
|
|
static QUiLoader loader;
|
2011-03-09 12:45:22 +01:00
|
|
|
loader.setTranslationEnabled(true);
|
|
|
|
loader.setLanguageChangeEnabled(true);
|
|
|
|
QWidget* const w = loader.load(&file);
|
2011-04-13 11:06:16 +02:00
|
|
|
d->m_userInterfaces.insert(w->objectName(), w);
|
2011-02-21 16:30:31 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Component::loadLicenses(const QString &directory, const QHash<QString, QVariant> &licenseHash)
|
|
|
|
{
|
|
|
|
QHash<QString, QVariant>::const_iterator it;
|
|
|
|
for (it = licenseHash.begin(); it != licenseHash.end(); ++it) {
|
|
|
|
const QString &fileName = it.value().toString();
|
|
|
|
QFile file(directory + fileName);
|
2011-03-09 12:45:22 +01:00
|
|
|
if (!file.open(QIODevice::ReadOnly)) {
|
|
|
|
throw Error(tr("Could not open the requested license file at %1: %2").arg(fileName,
|
2011-02-21 16:30:31 +01:00
|
|
|
file.errorString()));
|
|
|
|
}
|
|
|
|
d->m_licenses.insert(it.key(), qMakePair(fileName, QTextStream(&file).readAll()));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
2011-03-09 12:45:22 +01:00
|
|
|
Contains a list of all user interface class names known to this component.
|
|
|
|
*/
|
2011-02-21 16:30:31 +01:00
|
|
|
QStringList Component::userInterfaces() const
|
|
|
|
{
|
2011-04-13 11:06:16 +02:00
|
|
|
return d->m_userInterfaces.keys();
|
2011-02-21 16:30:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
QHash<QString, QPair<QString, QString> > Component::licenses() const
|
|
|
|
{
|
|
|
|
return d->m_licenses;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
2011-03-09 12:45:22 +01:00
|
|
|
Returns the QWidget created for class \a name.
|
|
|
|
*/
|
|
|
|
QWidget* Component::userInterface(const QString &name) const
|
2011-02-21 16:30:31 +01:00
|
|
|
{
|
2011-04-13 11:06:16 +02:00
|
|
|
return d->m_userInterfaces.value(name);
|
2011-02-21 16:30:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
2011-03-09 12:45:22 +01:00
|
|
|
Creates all operations needed to install this component's \a path. \a path is a full qualified
|
|
|
|
filename including the component's name. This metods gets called from
|
|
|
|
Component::createOperationsForArchive. You can override this method by providing a method with
|
|
|
|
the same name in the component script.
|
|
|
|
|
|
|
|
\note RSA signature files are omitted by this method.
|
|
|
|
\note If you call this method from a script, it won't call the scripts method with the same name.
|
2011-02-21 16:30:31 +01:00
|
|
|
|
2011-03-09 12:45:22 +01:00
|
|
|
The default implemention is recursively creating Copy and Mkdir operations for all files
|
|
|
|
and folders within \a path.
|
|
|
|
*/
|
|
|
|
void Component::createOperationsForPath(const QString &path)
|
2011-02-21 16:30:31 +01:00
|
|
|
{
|
2011-03-09 12:45:22 +01:00
|
|
|
const QFileInfo fi(path);
|
2011-02-21 16:30:31 +01:00
|
|
|
|
|
|
|
// don't copy over a signature
|
2011-03-09 12:45:22 +01:00
|
|
|
if (fi.suffix() == QLatin1String("sig") && QFileInfo(fi.dir(), fi.completeBaseName()).exists())
|
2011-02-21 16:30:31 +01:00
|
|
|
return;
|
|
|
|
|
|
|
|
// the script can override this method
|
2011-03-09 12:45:22 +01:00
|
|
|
if (callScriptMethod(QLatin1String("createOperationsForPath"), QScriptValueList() << path).isValid())
|
2011-02-21 16:30:31 +01:00
|
|
|
return;
|
|
|
|
|
|
|
|
QString target;
|
2011-03-09 12:45:22 +01:00
|
|
|
static const QString zipPrefix = QString::fromLatin1("7z://installer://");
|
|
|
|
// if the path is an archive, remove the archive file name from the target path
|
|
|
|
if (path.startsWith(zipPrefix)) {
|
|
|
|
target = path.mid(zipPrefix.length() + name().length() + 1); // + 1 for the /
|
|
|
|
const int nextSlash = target.indexOf(QLatin1Char('/'));
|
|
|
|
if (nextSlash != -1)
|
|
|
|
target = target.mid(nextSlash);
|
2011-02-21 16:30:31 +01:00
|
|
|
else
|
|
|
|
target.clear();
|
|
|
|
target.prepend(QLatin1String("@TargetDir@"));
|
2011-03-09 12:45:22 +01:00
|
|
|
} else {
|
|
|
|
static const QString prefix = QString::fromLatin1("installer://");
|
|
|
|
target = QString::fromLatin1("@TargetDir@%1").arg(path.mid(prefix.length() + name().length()));
|
2011-02-21 16:30:31 +01:00
|
|
|
}
|
2011-03-09 12:45:22 +01:00
|
|
|
|
|
|
|
if (fi.isFile()) {
|
|
|
|
static const QString copy = QString::fromLatin1("Copy");
|
|
|
|
addOperation(copy, fi.filePath(), target);
|
|
|
|
} else if (fi.isDir()) {
|
2011-02-21 16:30:31 +01:00
|
|
|
qApp->processEvents();
|
2011-03-09 12:45:22 +01:00
|
|
|
static const QString mkdir = QString::fromLatin1("Mkdir");
|
|
|
|
addOperation(mkdir, target);
|
2011-02-21 16:30:31 +01:00
|
|
|
|
2011-03-09 12:45:22 +01:00
|
|
|
QDirIterator it(fi.filePath());
|
|
|
|
while (it.hasNext())
|
|
|
|
createOperationsForPath(it.next());
|
|
|
|
}
|
2011-02-21 16:30:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
2011-03-09 12:45:22 +01:00
|
|
|
Creates all operations needed to install this component's \a archive. This metods gets called
|
|
|
|
from Component::createOperations. You can override this method by providing a method with the
|
|
|
|
same name in the component script.
|
|
|
|
|
|
|
|
\note If you call this method from a script, it won't call the scripts method with the same name.
|
|
|
|
|
|
|
|
The default implementation calls createOperationsForPath for everything contained in the archive.
|
|
|
|
If \a archive is a compressed archive known to the installer system, an Extract operation is
|
|
|
|
created, instead.
|
|
|
|
*/
|
|
|
|
void Component::createOperationsForArchive(const QString &archive)
|
2011-02-21 16:30:31 +01:00
|
|
|
{
|
|
|
|
// the script can override this method
|
2011-03-09 12:45:22 +01:00
|
|
|
if (callScriptMethod(QLatin1String("createOperationsForArchive"), QScriptValueList() << archive).isValid())
|
2011-02-21 16:30:31 +01:00
|
|
|
return;
|
|
|
|
|
2011-03-09 12:45:22 +01:00
|
|
|
const QFileInfo fi(QString::fromLatin1("installer://%1/%2").arg(name(), archive));
|
|
|
|
const bool isZip = Lib7z::isSupportedArchive(fi.filePath());
|
2011-02-21 16:30:31 +01:00
|
|
|
|
2011-03-09 12:45:22 +01:00
|
|
|
if (isZip) {
|
2011-02-21 16:30:31 +01:00
|
|
|
// archives get completely extracted per default (if the script isn't doing other stuff)
|
2011-03-09 12:45:22 +01:00
|
|
|
addOperation(QLatin1String("Extract"), fi.filePath(), QLatin1String("@TargetDir@"));
|
|
|
|
} else {
|
|
|
|
createOperationsForPath(fi.filePath());
|
|
|
|
}
|
2011-02-21 16:30:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
2011-03-09 12:45:22 +01:00
|
|
|
Creates all operations needed to install this component.
|
|
|
|
You can override this method by providing a method with the same name in the component script.
|
|
|
|
|
|
|
|
\note If you call this method from a script, it won't call the scripts method with the same name.
|
|
|
|
|
|
|
|
The default implementation calls createOperationsForArchive for all archives in this component.
|
2011-02-21 16:30:31 +01:00
|
|
|
*/
|
|
|
|
void Component::createOperations()
|
|
|
|
{
|
|
|
|
// the script can override this method
|
2011-03-09 12:45:22 +01:00
|
|
|
if (callScriptMethod(QLatin1String("createOperations")).isValid()) {
|
2011-04-13 11:06:16 +02:00
|
|
|
d->m_operationsCreated = true;
|
2011-02-21 16:30:31 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2011-03-09 12:45:22 +01:00
|
|
|
foreach (const QString &archive, archives())
|
|
|
|
createOperationsForArchive(archive);
|
2011-02-21 16:30:31 +01:00
|
|
|
|
2011-04-13 11:06:16 +02:00
|
|
|
d->m_operationsCreated = true;
|
2011-02-21 16:30:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
2011-03-09 12:45:22 +01:00
|
|
|
Registers the file or directory at \a path for being removed when this component gets uninstalled.
|
|
|
|
In case of a directory, this will be recursive. If \a wipe is set to true, the directory will
|
|
|
|
also be deleted if it contains changes done by the user after installation.
|
2011-02-21 16:30:31 +01:00
|
|
|
*/
|
2011-03-09 12:45:22 +01:00
|
|
|
void Component::registerPathForUninstallation(const QString &path, bool wipe)
|
2011-02-21 16:30:31 +01:00
|
|
|
{
|
2011-04-13 11:06:16 +02:00
|
|
|
d->m_pathesForUninstallation.append(qMakePair(path, wipe));
|
2011-02-21 16:30:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
2011-03-09 12:45:22 +01:00
|
|
|
Returns the list of pathes previously registered for uninstallation with
|
|
|
|
#registerPathForUninstallation.
|
2011-02-21 16:30:31 +01:00
|
|
|
*/
|
2011-03-09 12:45:22 +01:00
|
|
|
QList<QPair<QString, bool> > Component::pathesForUninstallation() const
|
2011-02-21 16:30:31 +01:00
|
|
|
{
|
2011-04-13 11:06:16 +02:00
|
|
|
return d->m_pathesForUninstallation;
|
2011-02-21 16:30:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
2011-03-09 12:45:22 +01:00
|
|
|
Contains the names of all archives known to this component. This does not contain archives added
|
|
|
|
with #addDownloadableArchive.
|
|
|
|
*/
|
2011-02-21 16:30:31 +01:00
|
|
|
QStringList Component::archives() const
|
|
|
|
{
|
2011-03-09 12:45:22 +01:00
|
|
|
return QDir(QString::fromLatin1("installer://%1/").arg(name())).entryList();
|
2011-02-21 16:30:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
2011-03-09 12:45:22 +01:00
|
|
|
Adds the archive \a path to this component. This can only be called when this component was
|
|
|
|
downloaded from an online repository. When adding \a path, it will be downloaded from the
|
|
|
|
repository when the installation starts.
|
|
|
|
|
|
|
|
Read \ref sec_repogen for details. \sa fromOnlineRepository
|
|
|
|
*/
|
|
|
|
void Component::addDownloadableArchive(const QString &path)
|
|
|
|
{
|
|
|
|
Q_ASSERT(isFromOnlineRepository());
|
|
|
|
|
2011-03-17 15:13:11 +01:00
|
|
|
const QString versionPrefix = value(skVersion);
|
2011-02-21 16:30:31 +01:00
|
|
|
verbose() << "addDownloadable " << path << std::endl;
|
2011-04-13 11:06:16 +02:00
|
|
|
d->m_downloadableArchives.append(versionPrefix + path);
|
2011-02-21 16:30:31 +01:00
|
|
|
}
|
2011-03-09 12:45:22 +01:00
|
|
|
|
2011-02-21 16:30:31 +01:00
|
|
|
/*!
|
2011-03-09 12:45:22 +01:00
|
|
|
Removes the archive \a path previously added via addDownloadableArchive from this component.
|
|
|
|
This can oly be called when this component was downloaded from an online repository.
|
|
|
|
|
|
|
|
Read \ref sec_repogen for details.
|
|
|
|
*/
|
|
|
|
void Component::removeDownloadableArchive(const QString &path)
|
2011-02-21 16:30:31 +01:00
|
|
|
{
|
2011-03-09 12:45:22 +01:00
|
|
|
Q_ASSERT(isFromOnlineRepository());
|
2011-04-13 11:06:16 +02:00
|
|
|
d->m_downloadableArchives.removeAll(path);
|
2011-02-21 16:30:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
2011-03-09 12:45:22 +01:00
|
|
|
Returns the archives to be downloaded from the online repository before installation.
|
|
|
|
*/
|
2011-02-21 16:30:31 +01:00
|
|
|
QStringList Component::downloadableArchives() const
|
|
|
|
{
|
2011-04-13 11:06:16 +02:00
|
|
|
return d->m_downloadableArchives;
|
2011-02-21 16:30:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
2011-03-09 12:45:22 +01:00
|
|
|
Adds a request for quitting the process @p process before installing/updating/uninstalling the
|
|
|
|
component.
|
|
|
|
*/
|
|
|
|
void Component::addStopProcessForUpdateRequest(const QString &process)
|
2011-02-21 16:30:31 +01:00
|
|
|
{
|
2011-04-13 11:06:16 +02:00
|
|
|
d->m_stopProcessForUpdateRequests.append(process);
|
2011-02-21 16:30:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
2011-03-09 12:45:22 +01:00
|
|
|
Removes the request for quitting the process @p process again.
|
2011-02-21 16:30:31 +01:00
|
|
|
*/
|
2011-03-09 12:45:22 +01:00
|
|
|
void Component::removeStopProcessForUpdateRequest(const QString &process)
|
2011-02-21 16:30:31 +01:00
|
|
|
{
|
2011-04-13 11:06:16 +02:00
|
|
|
d->m_stopProcessForUpdateRequests.removeAll(process);
|
2011-02-21 16:30:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
2011-03-09 12:45:22 +01:00
|
|
|
Convenience: Add/remove request depending on @p requested (add if @p true, remove if @p false).
|
2011-02-21 16:30:31 +01:00
|
|
|
*/
|
2011-03-09 12:45:22 +01:00
|
|
|
void Component::setStopProcessForUpdateRequest(const QString &process, bool requested)
|
2011-02-21 16:30:31 +01:00
|
|
|
{
|
2011-03-09 12:45:22 +01:00
|
|
|
if (requested)
|
|
|
|
addStopProcessForUpdateRequest(process);
|
2011-02-21 16:30:31 +01:00
|
|
|
else
|
2011-03-09 12:45:22 +01:00
|
|
|
removeStopProcessForUpdateRequest(process);
|
2011-02-21 16:30:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
2011-03-09 12:45:22 +01:00
|
|
|
The list of processes this component needs to be closed before installing/updating/uninstalling
|
|
|
|
*/
|
2011-02-21 16:30:31 +01:00
|
|
|
QStringList Component::stopProcessForUpdateRequests() const
|
|
|
|
{
|
2011-04-13 11:06:16 +02:00
|
|
|
return d->m_stopProcessForUpdateRequests;
|
2011-02-21 16:30:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
2011-03-09 12:45:22 +01:00
|
|
|
Returns the operations needed to install this component. If autoCreateOperations is true,
|
|
|
|
createOperations is called, if no operations have been auto-created yet.
|
|
|
|
*/
|
|
|
|
QList<KDUpdater::UpdateOperation*> Component::operations() const
|
2011-02-21 16:30:31 +01:00
|
|
|
{
|
2011-04-13 11:06:16 +02:00
|
|
|
if (d->m_autoCreateOperations && !d->m_operationsCreated) {
|
2011-03-09 12:45:22 +01:00
|
|
|
const_cast<Component*>(this)->createOperations();
|
2011-02-21 16:30:31 +01:00
|
|
|
|
2011-04-13 11:06:16 +02:00
|
|
|
if (!d->m_minimumProgressOperation) {
|
|
|
|
d->m_minimumProgressOperation = KDUpdater::UpdateOperationFactory::instance()
|
2011-02-21 16:30:31 +01:00
|
|
|
.create(QLatin1String("MinimumProgress"));
|
2011-04-13 11:06:16 +02:00
|
|
|
d->m_operations.append(d->m_minimumProgressOperation);
|
2011-02-21 16:30:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!d->m_licenses.isEmpty()) {
|
|
|
|
d->m_licenseOperation = KDUpdater::UpdateOperationFactory::instance()
|
|
|
|
.create(QLatin1String("License"));
|
|
|
|
d->m_licenseOperation->setValue(QLatin1String("installer"),
|
|
|
|
QVariant::fromValue(d->m_installer));
|
|
|
|
|
|
|
|
QVariantMap licenses;
|
|
|
|
const QList<QPair<QString, QString> > values = d->m_licenses.values();
|
|
|
|
for (int i = 0; i < values.count(); ++i)
|
|
|
|
licenses.insert(values.at(i).first, values.at(i).second);
|
|
|
|
d->m_licenseOperation->setValue(QLatin1String("licenses"), licenses);
|
2011-04-13 11:06:16 +02:00
|
|
|
d->m_operations.append(d->m_licenseOperation);
|
2011-02-21 16:30:31 +01:00
|
|
|
}
|
|
|
|
}
|
2011-04-13 11:06:16 +02:00
|
|
|
return d->m_operations;
|
2011-02-21 16:30:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
2011-03-09 12:45:22 +01:00
|
|
|
Adds \a operation to the list of operations needed to install this component.
|
|
|
|
*/
|
|
|
|
void Component::addOperation(KDUpdater::UpdateOperation* operation)
|
2011-02-21 16:30:31 +01:00
|
|
|
{
|
2011-04-13 11:06:16 +02:00
|
|
|
d->m_operations.append(operation);
|
2011-03-09 12:45:22 +01:00
|
|
|
if (FSEngineClientHandler::instance()->isActive())
|
|
|
|
operation->setValue(QLatin1String("admin"), true);
|
2011-02-21 16:30:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
2011-03-09 12:45:22 +01:00
|
|
|
Adds \a operation to the list of operations needed to install this component. \a operation
|
|
|
|
is executed with elevated rights.
|
|
|
|
*/
|
|
|
|
void Component::addElevatedOperation(KDUpdater::UpdateOperation* operation)
|
2011-02-21 16:30:31 +01:00
|
|
|
{
|
2011-03-09 12:45:22 +01:00
|
|
|
addOperation(operation);
|
|
|
|
operation->setValue(QLatin1String("admin"), true);
|
2011-02-21 16:30:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
bool Component::operationsCreatedSuccessfully() const
|
|
|
|
{
|
2011-04-13 11:06:16 +02:00
|
|
|
return d->m_operationsCreatedSuccessfully;
|
2011-02-21 16:30:31 +01:00
|
|
|
}
|
|
|
|
|
2011-03-09 12:45:22 +01:00
|
|
|
KDUpdater::UpdateOperation* Component::createOperation(const QString &operation,
|
|
|
|
const QString ¶meter1, const QString ¶meter2, const QString ¶meter3,
|
|
|
|
const QString ¶meter4, const QString ¶meter5, const QString ¶meter6,
|
|
|
|
const QString ¶meter7, const QString ¶meter8, const QString ¶meter9,
|
|
|
|
const QString ¶meter10)
|
|
|
|
{
|
|
|
|
KDUpdater::UpdateOperation* op = KDUpdater::UpdateOperationFactory::instance().create(operation);
|
|
|
|
if (op == 0) {
|
|
|
|
const QMessageBox::StandardButton button =
|
|
|
|
MessageBoxHandler::critical(MessageBoxHandler::currentBestSuitParent(),
|
|
|
|
QLatin1String("OperationDoesNotExistError"), tr("Error"),
|
|
|
|
tr("Error: Operation %1 does not exist").arg(operation),
|
|
|
|
QMessageBox::Abort | QMessageBox::Ignore);
|
|
|
|
if (button == QMessageBox::Abort)
|
2011-04-13 11:06:16 +02:00
|
|
|
d->m_operationsCreatedSuccessfully = false;
|
2011-03-09 12:45:22 +01:00
|
|
|
return op;
|
2011-02-21 16:30:31 +01:00
|
|
|
}
|
2011-03-09 12:45:22 +01:00
|
|
|
|
|
|
|
if (op->name() == QLatin1String("Delete"))
|
|
|
|
op->setValue(QLatin1String("performUndo"), false);
|
|
|
|
op->setValue(QLatin1String("installer"), qVariantFromValue(d->m_installer));
|
|
|
|
|
2011-02-21 16:30:31 +01:00
|
|
|
QStringList arguments;
|
2011-03-09 12:45:22 +01:00
|
|
|
if (!parameter1.isNull())
|
|
|
|
arguments.append(parameter1);
|
|
|
|
if (!parameter2.isNull())
|
|
|
|
arguments.append(parameter2);
|
|
|
|
if (!parameter3.isNull())
|
|
|
|
arguments.append(parameter3);
|
|
|
|
if (!parameter4.isNull())
|
|
|
|
arguments.append(parameter4);
|
|
|
|
if (!parameter5.isNull())
|
|
|
|
arguments.append(parameter5);
|
|
|
|
if (!parameter6.isNull())
|
|
|
|
arguments.append(parameter6);
|
|
|
|
if (!parameter7.isNull())
|
|
|
|
arguments.append(parameter7);
|
|
|
|
if (!parameter8.isNull())
|
|
|
|
arguments.append(parameter8);
|
|
|
|
if (!parameter9.isNull())
|
|
|
|
arguments.append(parameter9);
|
|
|
|
if (!parameter10.isNull())
|
|
|
|
arguments.append(parameter10);
|
|
|
|
op->setArguments(d->m_installer->replaceVariables(arguments));
|
|
|
|
|
|
|
|
return op;
|
2011-02-21 16:30:31 +01:00
|
|
|
}
|
|
|
|
/*!
|
2011-03-09 12:45:22 +01:00
|
|
|
Creates and adds an installation operation for \a operation. Add any number of \a parameter1,
|
|
|
|
\a parameter2, \a parameter3, \a parameter4, \a parameter5 and \a parameter6. The contents of
|
|
|
|
the parameters get variables like "@TargetDir@" replaced with their values, if contained.
|
|
|
|
\sa installeroperations
|
|
|
|
*/
|
|
|
|
bool Component::addOperation(const QString &operation, const QString ¶meter1,
|
|
|
|
const QString ¶meter2, const QString ¶meter3, const QString ¶meter4,
|
|
|
|
const QString ¶meter5, const QString ¶meter6, const QString ¶meter7,
|
|
|
|
const QString ¶meter8, const QString ¶meter9, const QString ¶meter10)
|
|
|
|
{
|
|
|
|
if (KDUpdater::UpdateOperation *op = createOperation(operation, parameter1, parameter2,
|
|
|
|
parameter3, parameter4, parameter5, parameter6, parameter7, parameter8, parameter9,
|
|
|
|
parameter10)) {
|
|
|
|
addOperation(op);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
2011-02-21 16:30:31 +01:00
|
|
|
}
|
|
|
|
|
2011-03-09 12:45:22 +01:00
|
|
|
/*!
|
|
|
|
Creates and adds an installation operation for \a operation. Add any number of \a parameter1,
|
|
|
|
\a parameter2, \a parameter3, \a parameter4, \a parameter5 and \a parameter6. The contents of
|
|
|
|
the parameters get variables like "@TargetDir@" replaced with their values, if contained.
|
|
|
|
\a operation is executed with elevated rights.
|
|
|
|
\sa installeroperations
|
|
|
|
*/
|
|
|
|
bool Component::addElevatedOperation(const QString &operation, const QString ¶meter1, const QString ¶meter2, const QString ¶meter3, const QString ¶meter4, const QString ¶meter5, const QString ¶meter6, const QString ¶meter7, const QString ¶meter8, const QString ¶meter9, const QString ¶meter10)
|
|
|
|
{
|
|
|
|
if (KDUpdater::UpdateOperation *op = createOperation(operation, parameter1, parameter2,
|
|
|
|
parameter3, parameter4, parameter5, parameter6, parameter7, parameter8, parameter9,
|
|
|
|
parameter10)) {
|
|
|
|
addElevatedOperation(op);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
2011-02-21 16:30:31 +01:00
|
|
|
|
|
|
|
/*!
|
2011-03-09 12:45:22 +01:00
|
|
|
Specifies wheter operations should be automatically created when the installation starts. This
|
|
|
|
would be done by calling #createOperations. If you set this to false, it's completely up to the
|
|
|
|
component's script to create all operations.
|
|
|
|
*/
|
2011-02-21 16:30:31 +01:00
|
|
|
bool Component::autoCreateOperations() const
|
|
|
|
{
|
2011-04-13 11:06:16 +02:00
|
|
|
return d->m_autoCreateOperations;
|
2011-02-21 16:30:31 +01:00
|
|
|
}
|
|
|
|
|
2011-03-09 12:45:22 +01:00
|
|
|
void Component::setAutoCreateOperations(bool autoCreateOperations)
|
2011-02-21 16:30:31 +01:00
|
|
|
{
|
2011-04-13 11:06:16 +02:00
|
|
|
d->m_autoCreateOperations = autoCreateOperations;
|
2011-02-21 16:30:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
2011-03-09 12:45:22 +01:00
|
|
|
\property Component::selected
|
|
|
|
Specifies wheter this component is selected for installation. Get this property's value by using
|
|
|
|
%isSelected(), and set it using %setSelected().
|
|
|
|
*/
|
2011-04-12 12:04:55 +02:00
|
|
|
bool Component::isSelected() const
|
2011-03-09 12:45:22 +01:00
|
|
|
{
|
2011-04-05 17:53:34 +02:00
|
|
|
return checkState() != Qt::Unchecked;
|
2011-02-21 16:30:31 +01:00
|
|
|
}
|
|
|
|
|
2011-03-09 12:45:22 +01:00
|
|
|
/*!
|
2011-04-12 12:04:55 +02:00
|
|
|
Marks the component for installation. Emits the selectedChanged() signal if the check state changes.
|
2011-03-09 12:45:22 +01:00
|
|
|
*/
|
2011-04-12 12:04:55 +02:00
|
|
|
void Component::setSelected(bool selected)
|
2011-02-21 16:30:31 +01:00
|
|
|
{
|
2011-04-12 12:04:55 +02:00
|
|
|
const Qt::CheckState previousState = checkState();
|
|
|
|
const Qt::CheckState newState = selected ? Qt::Checked : Qt::Unchecked;
|
|
|
|
|
2011-04-20 13:21:28 +02:00
|
|
|
if (newState != previousState && !isTristate()) {
|
|
|
|
setCheckState(newState);
|
2011-04-12 12:04:55 +02:00
|
|
|
QMetaObject::invokeMethod(this, "selectedChanged", Qt::QueuedConnection,
|
2011-04-20 13:21:28 +02:00
|
|
|
Q_ARG(bool, newState == Qt::Checked));
|
2011-04-12 12:04:55 +02:00
|
|
|
}
|
2011-02-21 16:30:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
2011-03-09 12:45:22 +01:00
|
|
|
Contains this component dependencies.
|
|
|
|
Read \ref componentdependencies for details.
|
|
|
|
*/
|
2011-02-21 16:30:31 +01:00
|
|
|
QStringList Component::dependencies() const
|
|
|
|
{
|
2011-03-17 15:13:11 +01:00
|
|
|
return value(skDependencies).split(QLatin1Char(','));
|
2011-02-21 16:30:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
2011-04-12 15:32:46 +02:00
|
|
|
Set's the components state to installed.
|
|
|
|
*/
|
|
|
|
void Component::setInstalled()
|
|
|
|
{
|
|
|
|
setValue(skCurrentState, skInstalled);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
Determines if the component is installed.
|
2011-03-09 12:45:22 +01:00
|
|
|
*/
|
2011-02-21 16:30:31 +01:00
|
|
|
bool Component::isInstalled() const
|
|
|
|
{
|
2011-04-12 15:32:46 +02:00
|
|
|
return skInstalled == value(skCurrentState);
|
2011-02-21 16:30:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
2011-03-09 12:45:22 +01:00
|
|
|
Determines if the user wants to install the component
|
|
|
|
*/
|
2011-02-21 16:30:31 +01:00
|
|
|
bool Component::installationRequested() const
|
|
|
|
{
|
2011-04-12 12:04:55 +02:00
|
|
|
return !isInstalled() && isSelected();
|
2011-02-21 16:30:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
2011-04-12 15:32:46 +02:00
|
|
|
Set's the components state to uninstalled.
|
2011-03-09 12:45:22 +01:00
|
|
|
*/
|
2011-04-12 15:32:46 +02:00
|
|
|
void Component::setUninstalled()
|
2011-02-21 16:30:31 +01:00
|
|
|
{
|
2011-04-12 15:32:46 +02:00
|
|
|
setValue(skCurrentState, skUninstalled);
|
2011-02-21 16:30:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
2011-04-12 15:32:46 +02:00
|
|
|
Determines if the component is uninstalled.
|
2011-03-09 12:45:22 +01:00
|
|
|
*/
|
2011-04-12 15:32:46 +02:00
|
|
|
bool Component::isUninstalled() const
|
2011-02-21 16:30:31 +01:00
|
|
|
{
|
2011-04-12 15:32:46 +02:00
|
|
|
return skUninstalled == value(skCurrentState);
|
2011-02-21 16:30:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
2011-04-12 15:32:46 +02:00
|
|
|
Determines if the user wants to uninstall the component.
|
2011-03-09 12:45:22 +01:00
|
|
|
*/
|
2011-04-12 15:32:46 +02:00
|
|
|
bool Component::uninstallationRequested() const
|
2011-02-21 16:30:31 +01:00
|
|
|
{
|
2011-04-12 15:32:46 +02:00
|
|
|
return isInstalled() && !isSelected();
|
2011-02-21 16:30:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
2011-03-09 12:45:22 +01:00
|
|
|
\property Component::fromOnlineRepository
|
|
|
|
|
|
|
|
Determines wheter this component has been loaded from an online repository. Get this property's
|
|
|
|
value by usinng %isFromOnlineRepository. \sa addDownloadableArchive
|
|
|
|
*/
|
2011-02-21 16:30:31 +01:00
|
|
|
bool Component::isFromOnlineRepository() const
|
|
|
|
{
|
|
|
|
return !repositoryUrl().isEmpty();
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
2011-03-09 12:45:22 +01:00
|
|
|
Contains the repository Url this component is downloaded from.
|
|
|
|
When this component is not downloaded from an online repository, returns an empty #QUrl.
|
|
|
|
*/
|
2011-02-21 16:30:31 +01:00
|
|
|
QUrl Component::repositoryUrl() const
|
|
|
|
{
|
2011-04-13 11:06:16 +02:00
|
|
|
return d->m_repositoryUrl;
|
2011-02-21 16:30:31 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
2011-03-09 12:45:22 +01:00
|
|
|
Sets this components #repositoryUrl.
|
2011-02-21 16:30:31 +01:00
|
|
|
*/
|
2011-03-09 12:45:22 +01:00
|
|
|
void Component::setRepositoryUrl(const QUrl& url)
|
2011-02-21 16:30:31 +01:00
|
|
|
{
|
2011-04-13 11:06:16 +02:00
|
|
|
d->m_repositoryUrl = url;
|
2011-02-21 16:30:31 +01:00
|
|
|
}
|
2011-03-15 18:17:20 +01:00
|
|
|
|
|
|
|
|
|
|
|
QString Component::localTempPath() const
|
|
|
|
{
|
2011-04-13 11:06:16 +02:00
|
|
|
return d->m_localTempPath;
|
2011-03-15 18:17:20 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void Component::setLocalTempPath(const QString &tempLocalPath)
|
|
|
|
{
|
2011-04-13 11:06:16 +02:00
|
|
|
d->m_localTempPath = tempLocalPath;
|
2011-03-15 18:17:20 +01:00
|
|
|
}
|
2011-04-01 13:55:31 +02:00
|
|
|
|
|
|
|
void Component::updateModelData(const QString &key, const QString &data)
|
|
|
|
{
|
|
|
|
if (key == skVirtual) {
|
2011-04-12 15:57:21 +02:00
|
|
|
if (data.toLower() == skTrue)
|
2011-04-01 13:55:31 +02:00
|
|
|
setData(installer()->virtualComponentsFont(), Qt::FontRole);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (key == skVersion)
|
|
|
|
setData(data, NewVersion);
|
|
|
|
|
|
|
|
if (key == skDisplayName)
|
|
|
|
setData(data, Qt::DisplayRole);
|
|
|
|
|
|
|
|
if (key == skInstalledVersion)
|
|
|
|
setData(data, InstalledVersion);
|
|
|
|
|
|
|
|
if (key == skUncompressedSize)
|
|
|
|
setData(uncompressedSize(), UncompressedSize);
|
|
|
|
|
|
|
|
setData(value(skDescription) + QLatin1String("<br><br>Update Info: ") + value(skUpdateText),
|
|
|
|
Qt::ToolTipRole);
|
|
|
|
}
|