Allow defining non-checkable items

This change will introduce new element 'Checkable' for package.
Setting checkable to false will hide checkbox. Useful if use case
is to install one sub item instead of all sub items.

Change-Id: I8c731e77353b6da539dddcecdc8495b28ef5f7ea
Task-number: QTIFW-773
Reviewed-by: Niels Weber <niels.weber@theqtcompany.com>
Reviewed-by: Iikka Eklund <iikka.eklund@theqtcompany.com>
This commit is contained in:
Katja Marttila 2015-12-01 10:50:22 +02:00
parent 8b344748b7
commit ba1209000a
20 changed files with 255 additions and 45 deletions

View File

@ -678,6 +678,12 @@
\li RequiresAdminRights
\li Set to \c true if the package needs to be installed with elevated permissions.
Optional.
\row
\li Checkable
\li Set to \c false if you want to hide the checkbox for an item. This is useful
when only a few subcomponents should be selected instead of all. Optional.
\note The content from the data directory is not installed if \c Checkable
is \c false unless \c ForcedInstallation is set to \c true.
\endtable
\section2 Component Dependencies

View File

@ -0,0 +1,60 @@
/****************************************************************************
**
** Copyright (C) 2015 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the Qt Installer Framework.
**
** $QT_BEGIN_LICENSE:FDL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see http://qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Free Documentation License Usage
** Alternatively, this file may be used under the terms of the GNU Free
** Documentation License version 1.3 as published by the Free Software
** Foundation and appearing in the file included in the packaging of
** this file. Please review the following information to ensure
** the GNU Free Documentation License version 1.3 requirements
** will be met: http://www.gnu.org/copyleft/fdl.html.
** $QT_END_LICENSE$
**
****************************************************************************/
/*!
\example hidecheckbox
\ingroup qtifwexamples
\title Hide Checkbox Example
\brief Using components' package.xml files to hide checkboxes for items.
\image qtifw-examples-hidecheckbox.png
\e{Hide Checkbox} illustrates how to hide the checkbox for an item.
\include installerfw-examples-configuring.qdocinc
\quotefile hidecheckbox/config/config.xml
\include installerfw-examples-packaging.qdocinc
\list
\li The \c <Checkable> element specifies whether a checkbox is displayed next to an item.
Set to \c false to hide the checkbox for the item.
\endlist
This example attempts to install three components, so we create a package.xml file in each
component directory: componentF, componentF.subcomponent1, and
componentF.subcomponent1.subcomponent1. We also specify the component name and description
in each of them. The top level item, componentF, has \c <Checkable> set to \c false,
so it cannot be selected. It also does not install the package, for that
you will need to set \c <ForceInstallation> to \c true.
\quotefile hidecheckbox/packages/componentF/meta/package.xml
\include installerfw-examples-generating.qdocinc
*/

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

View File

@ -0,0 +1,6 @@
Shows how to disable top level item, allowing the installation of child items.
Generate installer with
binarycreator --offline-only -c config/config.xml -p packages installer

View File

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<Installer>
<Name>Hide item checkbox</Name>
<Version>1.0.0</Version>
<Title>Hide checkbox</Title>
<Publisher>The Qt Company</Publisher>
<StartMenuDir>Qt IFW Examples</StartMenuDir>
<TargetDir>@HomeDir@/IfwExamples/disabletoplevel</TargetDir>
</Installer>

View File

@ -0,0 +1,13 @@
TEMPLATE = aux
INSTALLER = installer
INPUT = $$PWD/config/config.xml $$PWD/packages
example.input = INPUT
example.output = $$INSTALLER
example.commands = ../../bin/binarycreator -c $$PWD/config/config.xml -p $$PWD/packages ${QMAKE_FILE_OUT}
example.CONFIG += target_predeps no_link combine
QMAKE_EXTRA_COMPILERS += example
OTHER_FILES = README

View File

@ -0,0 +1,7 @@
<?xml version="1.0"?>
<Package>
<DisplayName>Subsubcomponent 1</DisplayName>
<Description>This component does not depend on any other component.</Description>
<Version>1.0.2</Version>
<ReleaseDate>2015-12-01</ReleaseDate>
</Package>

View File

@ -0,0 +1 @@
test sub1 versio3

View File

@ -0,0 +1,9 @@
<?xml version="1.0"?>
<Package>
<DisplayName>Subcomponent 1</DisplayName>
<Description>This component contains sub component.</Description>
<Version>1.0.2</Version>
<ReleaseDate>2015-12-01</ReleaseDate>
<SortingPriority>100</SortingPriority>
<Checkable>true</Checkable>
</Package>

View File

@ -0,0 +1 @@
test sub1 versio3

View File

@ -0,0 +1,9 @@
<?xml version="1.0"?>
<Package>
<DisplayName>Uncheckable component</DisplayName>
<Description>This component is uncheckable.</Description>
<Version>1.0.0</Version>
<ReleaseDate>2015-12-01</ReleaseDate>
<SortingPriority>40</SortingPriority>
<Checkable>false</Checkable>
</Package>

View File

@ -66,6 +66,7 @@ static const QLatin1String scUpdateText("UpdateText");
static const QLatin1String scUninstalled("Uninstalled");
static const QLatin1String scCurrentState("CurrentState");
static const QLatin1String scForcedInstallation("ForcedInstallation");
static const QLatin1String scCheckable("Checkable");
/*!
\inmodule QtInstallerFramework
@ -261,6 +262,7 @@ void Component::loadDataFromPackage(const KDUpdater::LocalPackage &package)
}
setValue(scVirtual, package.virtualComp ? scTrue : scFalse);
setValue(scCurrentState, scInstalled);
setValue(scCheckable, package.checkable ? scTrue : scFalse);
}
/*!
@ -293,6 +295,7 @@ void Component::loadDataFromPackage(const Package &package)
setValue(scScriptTag, package.data(scScriptTag).toString());
setValue(scReplaces, package.data(scReplaces).toString());
setValue(scReleaseDate, package.data(scReleaseDate).toString());
setValue(scCheckable, package.data(scCheckable).toString());
QString forced = package.data(scForcedInstallation, scFalse).toString().toLower();
if (PackageManagerCore::noForceInstallation())
@ -384,6 +387,8 @@ void Component::setValue(const QString &key, const QString &value)
if (key == scName)
d->m_componentName = normalizedValue;
if (key == scCheckable)
this->setCheckable(normalizedValue.toLower() == scTrue);
d->m_vars[key] = normalizedValue;
emit valueChanged(key, normalizedValue);

View File

@ -70,6 +70,7 @@ static const QLatin1String scRequiresAdminRights("RequiresAdminRights");
// constants used throughout the components class
static const QLatin1String scVirtual("Virtual");
static const QLatin1String scSortingPriority("SortingPriority");
static const QLatin1String scCheckable("Checkable");
// constants used throughout the settings and package manager core class
static const QLatin1String scTitle("Title");

View File

@ -1924,7 +1924,8 @@ void PackageManagerCorePrivate::installComponent(Component *component, double pr
component->forcedInstallation(),
component->isVirtual(),
component->value(scUncompressedSize).toULongLong(),
component->value(scInheritVersion));
component->value(scInheritVersion),
component->isCheckable());
m_localPackageHub->writeToDisk();
component->setInstalled();

View File

@ -315,7 +315,8 @@ void LocalPackageHub::refresh()
\a forcedInstallation,
\a virtualComp,
\a uncompressedSize,
and \a inheritVersionFrom for the package.
\a inheritVersionFrom,
and \a checkable for the package.
*/
void LocalPackageHub::addPackage(const QString &name,
const QString &version,
@ -326,7 +327,8 @@ void LocalPackageHub::addPackage(const QString &name,
bool forcedInstallation,
bool virtualComp,
quint64 uncompressedSize,
const QString &inheritVersionFrom)
const QString &inheritVersionFrom,
bool checkable)
{
// TODO: This somewhat unexpected, remove?
if (d->m_packageInfoMap.contains(name)) {
@ -346,6 +348,7 @@ void LocalPackageHub::addPackage(const QString &name,
info.forcedInstallation = forcedInstallation;
info.virtualComp = virtualComp;
info.uncompressedSize = uncompressedSize;
info.checkable = checkable;
d->m_packageInfoMap.insert(name, info);
}
d->modified = true;
@ -417,6 +420,8 @@ void LocalPackageHub::writeToDisk()
addTextChildHelper(&package, QLatin1String("ForcedInstallation"), QLatin1String("true"));
if (info.virtualComp)
addTextChildHelper(&package, QLatin1String("Virtual"), QLatin1String("true"));
if (info.checkable)
addTextChildHelper(&package, QLatin1String("Checkable"), QLatin1String("true"));
root.appendChild(package);
}
@ -444,6 +449,7 @@ void LocalPackageHub::PackagesInfoData::addPackageFrom(const QDomElement &packag
LocalPackage info;
info.forcedInstallation = false;
info.virtualComp = false;
info.checkable = false;
for (int i = 0; i < childNodes.count(); i++) {
QDomNode childNode = childNodes.item(i);
QDomElement childNodeE = childNode.toElement();
@ -476,6 +482,8 @@ void LocalPackageHub::PackagesInfoData::addPackageFrom(const QDomElement &packag
info.lastUpdateDate = QDate::fromString(childNodeE.text(), Qt::ISODate);
else if (childNodeE.tagName() == QLatin1String("InstallDate"))
info.installDate = QDate::fromString(childNodeE.text(), Qt::ISODate);
else if (childNodeE.tagName() == QLatin1String("Checkable"))
info.checkable = childNodeE.text().toLower() == QLatin1String("true") ? true : false;
}
m_packageInfoMap.insert(info.name, info);
}

View File

@ -58,6 +58,7 @@ struct KDTOOLS_EXPORT LocalPackage
bool forcedInstallation;
bool virtualComp;
quint64 uncompressedSize;
bool checkable;
};
class KDTOOLS_EXPORT LocalPackageHub
@ -108,7 +109,8 @@ public:
bool forcedInstallation,
bool virtualComp,
quint64 uncompressedSize,
const QString &inheritVersionFrom);
const QString &inheritVersionFrom,
bool checkable);
bool removePackage(const QString &pkgName);
void refresh();

View File

@ -131,4 +131,50 @@
file="license.txt"/>
</Licenses>
</PackageUpdate>
<PackageUpdate>
<Name>com.vendor.fourth.product.checkable</Name>
<DisplayName>A checkable root component</DisplayName>
<Description>Install this example.</Description>
<Version>0.1.0-1</Version>
<ReleaseDate>2010-09-21</ReleaseDate>
<Checkable>true</Checkable>
<Default>false</Default>
<Script>installscript.qs</Script>
<UpdateFile UncompressedSize="61"
CompressedSize="61"/>
<Licenses>
<License name="Beer Public License Agreement"
file="license.txt"/>
</Licenses>
</PackageUpdate>
<PackageUpdate>
<Name>com.vendor.fifth.product.noncheckable</Name>
<DisplayName>A non-checkable root component</DisplayName>
<Description>Install this example.</Description>
<Version>0.1.0-1</Version>
<ReleaseDate>2010-09-21</ReleaseDate>
<Script>installscript.qs</Script>
<Checkable>false</Checkable>
<UpdateFile UncompressedSize="61"
CompressedSize="61"/>
<Licenses>
<License name="Beer Public License Agreement"
file="license.txt"/>
</Licenses>
</PackageUpdate>
<PackageUpdate>
<Name>com.vendor.fifth.product.noncheckable.sub</Name>
<DisplayName>A sub component for non-checkable root component</DisplayName>
<Description>Install this example.</Description>
<Version>0.1.0-1</Version>
<ReleaseDate>2010-09-21</ReleaseDate>
<Script>installscript.qs</Script>
<SortingPriority>0</SortingPriority>
<UpdateFile UncompressedSize="61"
CompressedSize="61"/>
<Licenses>
<License name="Beer Public License Agreement"
file="license.txt"/>
</Licenses>
</PackageUpdate>
</Updates>

View File

@ -9,8 +9,8 @@
using namespace KDUpdater;
using namespace QInstaller;
#define EXPECTED_COUNT_VIRTUALS_VISIBLE 8
#define EXPECTED_COUNT_VIRTUALS_INVISIBLE 7
#define EXPECTED_COUNT_VIRTUALS_VISIBLE 11
#define EXPECTED_COUNT_VIRTUALS_INVISIBLE 10
static const char vendorProduct[] = "com.vendor.product";
static const char vendorSecondProduct[] = "com.vendor.second.product";
@ -20,6 +20,9 @@ static const char vendorSecondProductVirtual[] = "com.vendor.second.product.virt
static const char vendorSecondProductSubnode[] = "com.vendor.second.product.subnode";
static const char vendorSecondProductSubnodeSub[] = "com.vendor.second.product.subnode.sub";
static const char vendorThirdProductVirtual[] = "com.vendor.third.product.virtual";
static const char vendorFourthProductCheckable[] = "com.vendor.fourth.product.checkable";
static const char vendorFifthProductNonCheckable[] = "com.vendor.fifth.product.noncheckable";
static const char vendorFifthProductSub[] = "com.vendor.fifth.product.noncheckable.sub";
static const QMap<QString, QString> rootComponentDisplayNames = {
{"", QLatin1String("The root component")},
@ -45,7 +48,9 @@ private slots:
m_defaultChecked << vendorProduct << vendorSecondProductSub;
m_defaultPartially << vendorSecondProduct;
m_defaultUnchecked << vendorSecondProductSub1 << vendorSecondProductSubnode
<< vendorSecondProductSubnodeSub;
<< vendorSecondProductSubnodeSub << vendorFourthProductCheckable
<< vendorFifthProductSub;
m_uncheckable << vendorFifthProductNonCheckable;
}
void testNameToIndexAndIndexToName()
@ -61,7 +66,7 @@ private slots:
// all names should be resolvable, virtual components are not indexed if they are not visible
QStringList all;
all << m_defaultChecked << m_defaultPartially << m_defaultUnchecked;
all << m_defaultChecked << m_defaultPartially << m_defaultUnchecked << m_uncheckable;
foreach (const QString &name, all) {
QVERIFY(model.indexFromComponentName(name).isValid());
QVERIFY(model.componentFromIndex(model.indexFromComponentName(name)) != 0);
@ -85,8 +90,8 @@ private slots:
// all names should be resolvable, including virtual components
QStringList all;
all << m_defaultChecked << m_defaultPartially << m_defaultUnchecked << vendorSecondProductVirtual
<< vendorThirdProductVirtual;
all << m_defaultChecked << m_defaultPartially << m_defaultUnchecked << m_uncheckable
<< vendorSecondProductVirtual << vendorThirdProductVirtual;
foreach (const QString &name, all) {
QVERIFY(model.indexFromComponentName(name).isValid());
QVERIFY(model.componentFromIndex(model.indexFromComponentName(name)) != 0);
@ -111,7 +116,8 @@ private slots:
QCOMPARE(model.core(), &m_core);
QCOMPARE(model.checkedState(), ComponentModel::DefaultChecked);
testModelState(&model, m_defaultChecked, m_defaultPartially, m_defaultUnchecked);
testModelState(&model, m_defaultChecked, m_defaultPartially, m_defaultUnchecked
+ m_uncheckable);
foreach (Component *const component, rootComponents)
delete component;
@ -130,9 +136,10 @@ private slots:
testDefaultInheritedModelBehavior(&model, 1);
QCOMPARE(model.checkedState(), ComponentModel::DefaultChecked);
// the virtual components are not checked
testModelState(&model, m_defaultChecked, m_defaultPartially, m_defaultUnchecked
+ QStringList(vendorSecondProductVirtual) << vendorThirdProductVirtual);
// the virtual and non-checkable components are not checked
testModelState(&model, m_defaultChecked, m_defaultPartially,
m_defaultUnchecked + m_uncheckable
+ QStringList(vendorSecondProductVirtual) << vendorThirdProductVirtual);
foreach (Component *const component, rootComponents)
delete component;
@ -151,7 +158,8 @@ private slots:
testDefaultInheritedModelBehavior(&model, 1);
QCOMPARE(model.checkedState(), ComponentModel::DefaultChecked);
testModelState(&model, m_defaultChecked, m_defaultPartially, m_defaultUnchecked);
testModelState(&model, m_defaultChecked, m_defaultPartially, m_defaultUnchecked
+ m_uncheckable);
foreach (Component *const component, rootComponents)
delete component;
@ -171,7 +179,8 @@ private slots:
QCOMPARE(model.checkedState(), ComponentModel::DefaultChecked);
// the virtual components are not checked
testModelState(&model, m_defaultChecked, m_defaultPartially, m_defaultUnchecked
testModelState(&model, m_defaultChecked, m_defaultPartially,
m_defaultUnchecked + m_uncheckable
+ QStringList(vendorSecondProductVirtual) << vendorThirdProductVirtual);
foreach (Component *const component, rootComponents)
@ -190,23 +199,24 @@ private slots:
model.setRootComponents(rootComponents);
testDefaultInheritedModelBehavior(&model, 1);
// select all possible components
// select all possible components. As one is uncheckable should result in partial check.
model.setCheckedState(ComponentModel::AllChecked);
QCOMPARE(model.checkedState(), ComponentModel::AllChecked);
testModelState(&model, m_defaultChecked + m_defaultPartially + m_defaultUnchecked, QStringList()
, QStringList());
QCOMPARE(model.checkedState(), ComponentModel::PartiallyChecked);
testModelState(&model, m_defaultChecked + m_defaultPartially + m_defaultUnchecked,
QStringList(), m_uncheckable);
// deselect all possible components
// as the first root is a forced install, should result in partially checked state
model.setCheckedState(ComponentModel::AllUnchecked);
QCOMPARE(model.checkedState(), ComponentModel::PartiallyChecked);
testModelState(&model, QStringList() << vendorProduct, QStringList(), m_defaultPartially
+ m_defaultUnchecked + QStringList(vendorSecondProductSub));
+ m_defaultUnchecked + QStringList(vendorSecondProductSub) + m_uncheckable);
// reset all possible components
model.setCheckedState(ComponentModel::DefaultChecked);
QCOMPARE(model.checkedState(), ComponentModel::DefaultChecked);
testModelState(&model, m_defaultChecked, m_defaultPartially, m_defaultUnchecked);
testModelState(&model, m_defaultChecked, m_defaultPartially,
m_defaultUnchecked + m_uncheckable);
foreach (Component *const component, rootComponents)
delete component;
@ -224,25 +234,26 @@ private slots:
model.setRootComponents(rootComponents);
testDefaultInheritedModelBehavior(&model, 1);
// select all possible components
// select all possible components. As one is uncheckable should result to partially check
model.setCheckedState(ComponentModel::AllChecked);
QCOMPARE(model.checkedState(), ComponentModel::AllChecked);
QCOMPARE(model.checkedState(), ComponentModel::PartiallyChecked);
testModelState(&model, m_defaultChecked + m_defaultPartially + m_defaultUnchecked
+ QStringList(vendorSecondProductVirtual) << vendorThirdProductVirtual, QStringList(),
QStringList());
m_uncheckable);
// deselect all possible components
// as the first root is a forced install, should result in partially checked state
model.setCheckedState(ComponentModel::AllUnchecked);
QCOMPARE(model.checkedState(), ComponentModel::PartiallyChecked);
testModelState(&model, QStringList() << vendorProduct, QStringList(), m_defaultPartially
+ m_defaultUnchecked + QStringList(vendorSecondProductSub) << vendorSecondProductVirtual
<< vendorThirdProductVirtual);
+ m_defaultUnchecked + m_uncheckable + QStringList(vendorSecondProductSub)
<< vendorSecondProductVirtual << vendorThirdProductVirtual);
// reset all possible components
model.setCheckedState(ComponentModel::DefaultChecked);
QCOMPARE(model.checkedState(), ComponentModel::DefaultChecked);
testModelState(&model, m_defaultChecked, m_defaultPartially, m_defaultUnchecked
testModelState(&model, m_defaultChecked, m_defaultPartially,
m_defaultUnchecked + m_uncheckable
+ QStringList(vendorSecondProductVirtual) << vendorThirdProductVirtual);
foreach (Component *const component, rootComponents)
@ -261,22 +272,24 @@ private slots:
model.setRootComponents(rootComponents);
testDefaultInheritedModelBehavior(&model, 1);
// select all possible components
// select all possible components. As one is uncheckable should result to partially check
model.setCheckedState(ComponentModel::AllChecked);
QCOMPARE(model.checkedState(), ComponentModel::AllChecked);
testModelState(&model, m_defaultChecked + m_defaultPartially + m_defaultUnchecked, QStringList()
, QStringList());
QCOMPARE(model.checkedState(), ComponentModel::PartiallyChecked);
testModelState(&model, m_defaultChecked + m_defaultPartially + m_defaultUnchecked,
QStringList(), m_uncheckable);
// deselect all possible components
model.setCheckedState(ComponentModel::AllUnchecked);
QCOMPARE(model.checkedState(), ComponentModel::AllUnchecked);
testModelState(&model, QStringList(), QStringList(), m_defaultPartially + m_defaultUnchecked
testModelState(&model, QStringList(), QStringList(), m_defaultPartially
+ m_defaultUnchecked + m_uncheckable
+ QStringList(vendorSecondProductSub) << vendorProduct);
// reset all possible components
model.setCheckedState(ComponentModel::DefaultChecked);
QCOMPARE(model.checkedState(), ComponentModel::DefaultChecked);
testModelState(&model, m_defaultChecked, m_defaultPartially, m_defaultUnchecked);
testModelState(&model, m_defaultChecked, m_defaultPartially,
m_defaultUnchecked + m_uncheckable);
foreach (Component *const component, rootComponents)
delete component;
@ -294,25 +307,26 @@ private slots:
model.setRootComponents(rootComponents);
testDefaultInheritedModelBehavior(&model, 1);
// select all possible components
// select all possible components. As one is uncheckable should result to partially check
model.setCheckedState(ComponentModel::AllChecked);
QCOMPARE(model.checkedState(), ComponentModel::AllChecked);
QCOMPARE(model.checkedState(), ComponentModel::PartiallyChecked);
testModelState(&model, m_defaultChecked + m_defaultPartially + m_defaultUnchecked
+ QStringList(vendorSecondProductVirtual) << vendorThirdProductVirtual, QStringList(),
QStringList());
m_uncheckable);
// deselect all possible components
model.setCheckedState(ComponentModel::AllUnchecked);
QCOMPARE(model.checkedState(), ComponentModel::AllUnchecked);
testModelState(&model, QStringList(), QStringList(), m_defaultPartially + m_defaultUnchecked
+ QStringList(vendorSecondProductSub) << vendorSecondProductVirtual << vendorProduct
<< vendorThirdProductVirtual);
testModelState(&model, QStringList(), QStringList(), m_defaultPartially
+ m_defaultUnchecked + m_uncheckable + QStringList(vendorSecondProductSub)
<< vendorSecondProductVirtual << vendorProduct << vendorThirdProductVirtual);
// reset all possible components
model.setCheckedState(ComponentModel::DefaultChecked);
QCOMPARE(model.checkedState(), ComponentModel::DefaultChecked);
testModelState(&model, m_defaultChecked, m_defaultPartially, m_defaultUnchecked
+ QStringList(vendorSecondProductVirtual) << vendorThirdProductVirtual);
+ m_uncheckable + QStringList(vendorSecondProductVirtual)
<< vendorThirdProductVirtual);
foreach (Component *const component, rootComponents)
delete component;
@ -352,8 +366,8 @@ private:
void testComponentsLoaded(const QList<Component *> &rootComponents) const
{
// we need to have three root components
QCOMPARE(rootComponents.count(), 3);
// we need to have five root components
QCOMPARE(rootComponents.count(), 5);
QList<Component*> components = rootComponents;
foreach (Component *const component, rootComponents)
@ -368,9 +382,9 @@ private:
{
// row count with invalid model index should return:
if (m_core.virtualComponentsVisible())
QCOMPARE(model->rowCount(), 3); // 3 (2 non virtual and 1 virtual root component)
QCOMPARE(model->rowCount(), 5); // 5 (4 non virtual and 1 virtual root component)
else
QCOMPARE(model->rowCount(), 2); // 2 (the 2 non virtual root components)
QCOMPARE(model->rowCount(), 4); // 4 (the 4 non virtual root components)
QCOMPARE(model->columnCount(), columnCount);
const QModelIndex firstParent = model->indexFromComponentName(vendorProduct);
@ -460,6 +474,7 @@ private:
component->setValue("Default", info.data.value("Default").toString());
component->setValue("Virtual", info.data.value("Virtual").toString());
component->setValue("DisplayName", info.data.value("DisplayName").toString());
component->setValue("Checkable", info.data.value("Checkable").toString());
QString forced = info.data.value("ForcedInstallation", scFalse).toString().toLower();
if (m_core.noForceInstallation())
@ -499,6 +514,7 @@ private:
QStringList m_defaultChecked;
QStringList m_defaultPartially;
QStringList m_defaultUnchecked;
QStringList m_uncheckable;
};
Q_DECLARE_OPERATORS_FOR_FLAGS(tst_ComponentModel::Options)

View File

@ -190,6 +190,7 @@ void QInstallerTools::copyMetaData(const QString &_targetDir, const QString &met
bool foundVirtual = false;
bool foundDisplayName = false;
bool foundDownloadableArchives = false;
bool foundCheckable = false;
const QDomNode package = packageXml.firstChildElement(QLatin1String("Package"));
const QDomNodeList childNodes = package.childNodes();
for (int i = 0; i < childNodes.count(); ++i) {
@ -204,6 +205,8 @@ void QInstallerTools::copyMetaData(const QString &_targetDir, const QString &met
foundDisplayName = true;
if (key == QLatin1String("DownloadableArchives"))
foundDownloadableArchives = true;
if (key == QLatin1String("Checkable"))
foundCheckable = true;
if (node.isComment() || blackList.contains(key))
continue; // just skip comments and some tags...
@ -220,6 +223,12 @@ void QInstallerTools::copyMetaData(const QString &_targetDir, const QString &met
"mutually exclusive in file \"%1\".").arg(QDir::toNativeSeparators(packageXmlPath)));
}
if (foundDefault && foundCheckable) {
throw QInstaller::Error(QString::fromLatin1("Error: <Default> and <Checkable>"
"elements are mutually exclusive in file \"%1\".")
.arg(QDir::toNativeSeparators(packageXmlPath)));
}
if (!foundDisplayName) {
qWarning() << "No DisplayName tag found at" << info.name << ", using component Name instead.";
QDomElement displayNameElement = doc.createElement(QLatin1String("DisplayName"));