diff options
20 files changed, 255 insertions, 45 deletions
diff --git a/doc/installerfw.qdoc b/doc/installerfw.qdoc index 3b33b77a4..dad50ce87 100644 --- a/doc/installerfw.qdoc +++ b/doc/installerfw.qdoc @@ -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 diff --git a/examples/doc/hidecheckbox.qdoc b/examples/doc/hidecheckbox.qdoc new file mode 100644 index 000000000..cdcc506c1 --- /dev/null +++ b/examples/doc/hidecheckbox.qdoc @@ -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 +*/ diff --git a/examples/doc/images/qtifw-examples-hidecheckbox.png b/examples/doc/images/qtifw-examples-hidecheckbox.png Binary files differnew file mode 100644 index 000000000..58b0a1848 --- /dev/null +++ b/examples/doc/images/qtifw-examples-hidecheckbox.png diff --git a/examples/hidecheckbox/README b/examples/hidecheckbox/README new file mode 100644 index 000000000..22619bf9c --- /dev/null +++ b/examples/hidecheckbox/README @@ -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 + diff --git a/examples/hidecheckbox/config/config.xml b/examples/hidecheckbox/config/config.xml new file mode 100644 index 000000000..db756799f --- /dev/null +++ b/examples/hidecheckbox/config/config.xml @@ -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> diff --git a/examples/hidecheckbox/disabletoplevel.pro b/examples/hidecheckbox/disabletoplevel.pro new file mode 100644 index 000000000..415df49d5 --- /dev/null +++ b/examples/hidecheckbox/disabletoplevel.pro @@ -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 diff --git a/examples/hidecheckbox/packages/componentF.subcomponent1.subsubcomponent1/data/testF_sub1_sub1.txt b/examples/hidecheckbox/packages/componentF.subcomponent1.subsubcomponent1/data/testF_sub1_sub1.txt new file mode 100644 index 000000000..0478bd970 --- /dev/null +++ b/examples/hidecheckbox/packages/componentF.subcomponent1.subsubcomponent1/data/testF_sub1_sub1.txt @@ -0,0 +1 @@ +test sub sub versio3 diff --git a/examples/hidecheckbox/packages/componentF.subcomponent1.subsubcomponent1/meta/package.xml b/examples/hidecheckbox/packages/componentF.subcomponent1.subsubcomponent1/meta/package.xml new file mode 100644 index 000000000..b613022a0 --- /dev/null +++ b/examples/hidecheckbox/packages/componentF.subcomponent1.subsubcomponent1/meta/package.xml @@ -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> diff --git a/examples/hidecheckbox/packages/componentF.subcomponent1/data/testF_sub1.txt b/examples/hidecheckbox/packages/componentF.subcomponent1/data/testF_sub1.txt new file mode 100644 index 000000000..c34214bb9 --- /dev/null +++ b/examples/hidecheckbox/packages/componentF.subcomponent1/data/testF_sub1.txt @@ -0,0 +1 @@ +test sub1 versio3 diff --git a/examples/hidecheckbox/packages/componentF.subcomponent1/meta/package.xml b/examples/hidecheckbox/packages/componentF.subcomponent1/meta/package.xml new file mode 100644 index 000000000..58bbab370 --- /dev/null +++ b/examples/hidecheckbox/packages/componentF.subcomponent1/meta/package.xml @@ -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> diff --git a/examples/hidecheckbox/packages/componentF/data/testF.txt b/examples/hidecheckbox/packages/componentF/data/testF.txt new file mode 100644 index 000000000..c34214bb9 --- /dev/null +++ b/examples/hidecheckbox/packages/componentF/data/testF.txt @@ -0,0 +1 @@ +test sub1 versio3 diff --git a/examples/hidecheckbox/packages/componentF/meta/package.xml b/examples/hidecheckbox/packages/componentF/meta/package.xml new file mode 100644 index 000000000..96d7cbc21 --- /dev/null +++ b/examples/hidecheckbox/packages/componentF/meta/package.xml @@ -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> diff --git a/src/libs/installer/component.cpp b/src/libs/installer/component.cpp index 688a5b928..4ffefe384 100644 --- a/src/libs/installer/component.cpp +++ b/src/libs/installer/component.cpp @@ -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); diff --git a/src/libs/installer/constants.h b/src/libs/installer/constants.h index 0550b94f8..ecb998361 100644 --- a/src/libs/installer/constants.h +++ b/src/libs/installer/constants.h @@ -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"); diff --git a/src/libs/installer/packagemanagercore_p.cpp b/src/libs/installer/packagemanagercore_p.cpp index 51ea4df38..ce6bc8cd4 100644 --- a/src/libs/installer/packagemanagercore_p.cpp +++ b/src/libs/installer/packagemanagercore_p.cpp @@ -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(); diff --git a/src/libs/kdtools/localpackagehub.cpp b/src/libs/kdtools/localpackagehub.cpp index 6172de853..0510d8a38 100644 --- a/src/libs/kdtools/localpackagehub.cpp +++ b/src/libs/kdtools/localpackagehub.cpp @@ -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); } diff --git a/src/libs/kdtools/localpackagehub.h b/src/libs/kdtools/localpackagehub.h index 0a7b8513c..0ea3a95c0 100644 --- a/src/libs/kdtools/localpackagehub.h +++ b/src/libs/kdtools/localpackagehub.h @@ -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(); diff --git a/tests/auto/installer/componentmodel/data/updates.xml b/tests/auto/installer/componentmodel/data/updates.xml index cfd756a5c..2341866ee 100644 --- a/tests/auto/installer/componentmodel/data/updates.xml +++ b/tests/auto/installer/componentmodel/data/updates.xml @@ -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> diff --git a/tests/auto/installer/componentmodel/tst_componentmodel.cpp b/tests/auto/installer/componentmodel/tst_componentmodel.cpp index ea76bb2e6..5d86103a9 100644 --- a/tests/auto/installer/componentmodel/tst_componentmodel.cpp +++ b/tests/auto/installer/componentmodel/tst_componentmodel.cpp @@ -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) diff --git a/tools/common/repositorygen.cpp b/tools/common/repositorygen.cpp index 40caf388b..316f26022 100644 --- a/tools/common/repositorygen.cpp +++ b/tools/common/repositorygen.cpp @@ -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")); |