From 06ee3aee7f542a8c2ae7eb4e5c5240ff2359d9c8 Mon Sep 17 00:00:00 2001 From: dt <qtc-committer@nokia.com> Date: Mon, 21 Feb 2011 15:30:05 +0100 Subject: [PATCH] Qt4ProjectManager: New TargetSetupPage Rewrite the target setup page to look and baheve better. Noteable better at: - Disabling shadow building - Deselecting whole targets - Adding import directories Api-wise, Targets derived from Qt4BaseTarget have two ways to customize the targetsetuppage. a) Reimplement availableBuildConfigurations b) Leave createTargetSetupWidget and create(... Qt4TargetSetupWidget) in their default implementation. (Or only slightly customize like the desktop target does.) Or: a) Make a dummy implementation for availableBuildConfiguration b) Replace createTargetSetupWidget and return your own widget (It should match the look and feel from the other widgets.) It needs to be derived from Qt4TargetSetupWidget c) Also replace the create create(... Qt4TargetSetupWidget) function and set up the target anyway you want. --- .../qt4projectmanager/projectloadwizard.cpp | 7 +- .../qt-desktop/qt4desktoptargetfactory.cpp | 28 +- .../qt-desktop/qt4desktoptargetfactory.h | 8 +- .../qt-desktop/qt4simulatortargetfactory.cpp | 19 +- .../qt-desktop/qt4simulatortargetfactory.h | 7 +- .../qt-maemo/qt4maemotargetfactory.cpp | 25 +- .../qt-maemo/qt4maemotargetfactory.h | 10 +- .../qt-s60/qt4symbiantargetfactory.cpp | 41 +- .../qt-s60/qt4symbiantargetfactory.h | 8 +- .../qt-s60/s60symbiancertificate.cpp | 2 +- src/plugins/qt4projectmanager/qt4target.cpp | 558 +++++++++++++++ src/plugins/qt4projectmanager/qt4target.h | 141 +++- .../qt4projectmanager/qtversionmanager.cpp | 10 - .../qt4projectmanager/qtversionmanager.h | 1 - .../wizards/abstractmobileappwizard.cpp | 3 +- .../wizards/html5appwizard.cpp | 2 +- .../wizards/mobileappwizard.cpp | 2 +- .../wizards/qtquickappwizard.cpp | 16 +- .../qt4projectmanager/wizards/qtwizard.cpp | 20 +- .../qt4projectmanager/wizards/qtwizard.h | 3 - .../wizards/targetsetuppage.cpp | 633 +++--------------- .../wizards/targetsetuppage.h | 107 +-- .../wizards/targetsetuppage.ui | 67 +- 23 files changed, 934 insertions(+), 784 deletions(-) diff --git a/src/plugins/qt4projectmanager/projectloadwizard.cpp b/src/plugins/qt4projectmanager/projectloadwizard.cpp index 5797e99b174..6fbe43eb57c 100644 --- a/src/plugins/qt4projectmanager/projectloadwizard.cpp +++ b/src/plugins/qt4projectmanager/projectloadwizard.cpp @@ -89,14 +89,9 @@ void ProjectLoadWizard::setupTargetPage() if (m_targetSetupPage) return; - QList<TargetSetupPage::ImportInfo> importVersions = TargetSetupPage::scanDefaultProjectDirectories(m_project); - importVersions.append(TargetSetupPage::importInfosForKnownQtVersions(m_project->file()->fileName())); - m_targetSetupPage = new TargetSetupPage(this); m_targetSetupPage->setProFilePath(m_project->file()->fileName()); - m_targetSetupPage->setImportInfos(importVersions); - m_targetSetupPage->setImportDirectoryBrowsingEnabled(true); - m_targetSetupPage->setImportDirectoryBrowsingLocation(m_project->projectDirectory()); + m_targetSetupPage->setImportSearch(true); resize(900, 450); addPage(m_targetSetupPage); diff --git a/src/plugins/qt4projectmanager/qt-desktop/qt4desktoptargetfactory.cpp b/src/plugins/qt4projectmanager/qt-desktop/qt4desktoptargetfactory.cpp index b0dc98ca12d..776ace2b51f 100644 --- a/src/plugins/qt4projectmanager/qt-desktop/qt4desktoptargetfactory.cpp +++ b/src/plugins/qt4projectmanager/qt-desktop/qt4desktoptargetfactory.cpp @@ -42,8 +42,10 @@ #include <projectexplorer/customexecutablerunconfiguration.h> #include <projectexplorer/projectexplorerconstants.h> +#include <QtGui/QVBoxLayout> #include <QtGui/QApplication> #include <QtGui/QStyle> +#include <QtGui/QLabel> using namespace Qt4ProjectManager; using namespace Qt4ProjectManager::Internal; @@ -67,7 +69,7 @@ bool Qt4DesktopTargetFactory::supportsTargetId(const QString &id) const QStringList Qt4DesktopTargetFactory::supportedTargetIds(ProjectExplorer::Project *parent) const { - if (!qobject_cast<Qt4Project *>(parent)) + if (parent && !qobject_cast<Qt4Project *>(parent)) return QStringList(); if (!QtVersionManager::instance()->supportsTargetId(Constants::DESKTOP_TARGET_ID)) return QStringList(); @@ -126,23 +128,31 @@ QString Qt4DesktopTargetFactory::defaultShadowBuildDirectory(const QString &proj return projectLocation + QLatin1String("-desktop"); } -QList<BuildConfigurationInfo> Qt4DesktopTargetFactory::availableBuildConfigurations(const QString &proFilePath) +QList<BuildConfigurationInfo> Qt4DesktopTargetFactory::availableBuildConfigurations(const QString &id, const QString &proFilePath, const QtVersionNumber &minimumQtVersion) { + Q_ASSERT(id == Constants::DESKTOP_TARGET_ID); QList<BuildConfigurationInfo> infos; - QList<QtVersion *> knownVersions = QtVersionManager::instance()->versionsForTargetId(Constants::DESKTOP_TARGET_ID); + QList<QtVersion *> knownVersions = QtVersionManager::instance()->versionsForTargetId(id, minimumQtVersion); foreach (QtVersion *version, knownVersions) { if (!version->isValid()) continue; QtVersion::QmakeBuildConfigs config = version->defaultBuildConfig(); - QString dir = defaultShadowBuildDirectory(Qt4Project::defaultTopLevelBuildDirectory(proFilePath), Constants::DESKTOP_TARGET_ID); + QString dir = defaultShadowBuildDirectory(Qt4Project::defaultTopLevelBuildDirectory(proFilePath), id); infos.append(BuildConfigurationInfo(version, config, QString(), dir)); infos.append(BuildConfigurationInfo(version, config ^ QtVersion::DebugBuild, QString(), dir)); } return infos; } +Qt4TargetSetupWidget *Qt4DesktopTargetFactory::createTargetSetupWidget(const QString &id, const QString &proFilePath, const QtVersionNumber &number, bool importEnabled, QList<BuildConfigurationInfo> importInfos) +{ + Qt4DefaultTargetSetupWidget *widget = new Qt4DefaultTargetSetupWidget(this, id, proFilePath, number, importEnabled, importInfos); + widget->setShadowBuildCheckBoxVisible(true); + return widget; +} + Qt4BaseTarget *Qt4DesktopTargetFactory::create(ProjectExplorer::Project *parent, const QString &id) { if (!canCreate(parent, id)) @@ -162,10 +172,18 @@ Qt4BaseTarget *Qt4DesktopTargetFactory::create(ProjectExplorer::Project *parent, return create(parent, id, infos); } -Qt4BaseTarget *Qt4DesktopTargetFactory::create(ProjectExplorer::Project *parent, const QString &id, QList<BuildConfigurationInfo> infos) +bool Qt4DesktopTargetFactory::isMobileTarget(const QString &id) +{ + Q_UNUSED(id) + return false; +} + +Qt4BaseTarget *Qt4DesktopTargetFactory::create(ProjectExplorer::Project *parent, const QString &id, const QList<BuildConfigurationInfo> &infos) { if (!canCreate(parent, id)) return 0; + if (infos.isEmpty()) + return 0; Qt4DesktopTarget *t = new Qt4DesktopTarget(static_cast<Qt4Project *>(parent), id); foreach (const BuildConfigurationInfo &info, infos) diff --git a/src/plugins/qt4projectmanager/qt-desktop/qt4desktoptargetfactory.h b/src/plugins/qt4projectmanager/qt-desktop/qt4desktoptargetfactory.h index 2c99a7822bf..48f2778a7e5 100644 --- a/src/plugins/qt4projectmanager/qt-desktop/qt4desktoptargetfactory.h +++ b/src/plugins/qt4projectmanager/qt-desktop/qt4desktoptargetfactory.h @@ -56,11 +56,13 @@ public: virtual bool supportsTargetId(const QString &id) const; - QList<BuildConfigurationInfo> availableBuildConfigurations(const QString &proFilePath); + Qt4TargetSetupWidget *createTargetSetupWidget(const QString &id, const QString &proFilePath, const QtVersionNumber &minimumQtVersion, bool importEnabled, QList<BuildConfigurationInfo> importInfos); + bool isMobileTarget(const QString &id); + QList<BuildConfigurationInfo> availableBuildConfigurations(const QString &id, const QString &proFilePath, const QtVersionNumber &minimumQtVersion); Qt4BaseTarget *create(ProjectExplorer::Project *parent, const QString &id); - Qt4BaseTarget *create(ProjectExplorer::Project *parent, const QString &id, QList<BuildConfigurationInfo> infos); + Qt4BaseTarget *create(ProjectExplorer::Project *parent, const QString &id, const QList<BuildConfigurationInfo> &infos); + }; } } - #endif // QT4DESKTOPTARGETFACTORY_H diff --git a/src/plugins/qt4projectmanager/qt-desktop/qt4simulatortargetfactory.cpp b/src/plugins/qt4projectmanager/qt-desktop/qt4simulatortargetfactory.cpp index 3061a95d592..7a0c7a150c9 100644 --- a/src/plugins/qt4projectmanager/qt-desktop/qt4simulatortargetfactory.cpp +++ b/src/plugins/qt4projectmanager/qt-desktop/qt4simulatortargetfactory.cpp @@ -70,7 +70,7 @@ bool Qt4SimulatorTargetFactory::supportsTargetId(const QString &id) const QStringList Qt4SimulatorTargetFactory::supportedTargetIds(ProjectExplorer::Project *parent) const { - if (!qobject_cast<Qt4Project *>(parent)) + if (parent && !qobject_cast<Qt4Project *>(parent)) return QStringList(); if (!QtVersionManager::instance()->supportsTargetId(Constants::QT_SIMULATOR_TARGET_ID)) return QStringList(); @@ -128,22 +128,29 @@ QString Qt4SimulatorTargetFactory::defaultShadowBuildDirectory(const QString &pr return projectLocation + QLatin1String("-simulator"); } -QList<BuildConfigurationInfo> Qt4SimulatorTargetFactory::availableBuildConfigurations(const QString &proFilePath) +QList<BuildConfigurationInfo> Qt4SimulatorTargetFactory::availableBuildConfigurations(const QString &id, const QString &proFilePath, const QtVersionNumber &minimumQtVersion) { + Q_ASSERT(id == Constants::QT_SIMULATOR_TARGET_ID); QList<BuildConfigurationInfo> infos; - QList<QtVersion *> knownVersions = QtVersionManager::instance()->versionsForTargetId(Constants::QT_SIMULATOR_TARGET_ID); + QList<QtVersion *> knownVersions = QtVersionManager::instance()->versionsForTargetId(id, minimumQtVersion); foreach (QtVersion *version, knownVersions) { if (!version->isValid()) continue; QtVersion::QmakeBuildConfigs config = version->defaultBuildConfig(); - QString dir = defaultShadowBuildDirectory(Qt4Project::defaultTopLevelBuildDirectory(proFilePath), Constants::QT_SIMULATOR_TARGET_ID); + QString dir = defaultShadowBuildDirectory(Qt4Project::defaultTopLevelBuildDirectory(proFilePath), id); infos.append(BuildConfigurationInfo(version, config, QString(), dir)); infos.append(BuildConfigurationInfo(version, config ^ QtVersion::DebugBuild, QString(), dir)); } return infos; } +bool Qt4SimulatorTargetFactory::isMobileTarget(const QString &id) +{ + Q_UNUSED(id) + return true; +} + Qt4BaseTarget *Qt4SimulatorTargetFactory::create(ProjectExplorer::Project *parent, const QString &id) { if (!canCreate(parent, id)) @@ -162,10 +169,12 @@ Qt4BaseTarget *Qt4SimulatorTargetFactory::create(ProjectExplorer::Project *paren return create(parent, id, infos); } -Qt4BaseTarget *Qt4SimulatorTargetFactory::create(ProjectExplorer::Project *parent, const QString &id, QList<BuildConfigurationInfo> infos) +Qt4BaseTarget *Qt4SimulatorTargetFactory::create(ProjectExplorer::Project *parent, const QString &id, const QList<BuildConfigurationInfo> &infos) { if (!canCreate(parent, id)) return 0; + if (infos.isEmpty()) + return 0; Qt4SimulatorTarget *t = new Qt4SimulatorTarget(static_cast<Qt4Project *>(parent), id); foreach (const BuildConfigurationInfo &info, infos) diff --git a/src/plugins/qt4projectmanager/qt-desktop/qt4simulatortargetfactory.h b/src/plugins/qt4projectmanager/qt-desktop/qt4simulatortargetfactory.h index 0f560a6ee00..09fc6b12403 100644 --- a/src/plugins/qt4projectmanager/qt-desktop/qt4simulatortargetfactory.h +++ b/src/plugins/qt4projectmanager/qt-desktop/qt4simulatortargetfactory.h @@ -56,11 +56,12 @@ public: Qt4ProjectManager::Qt4BaseTarget *restore(ProjectExplorer::Project *parent, const QVariantMap &map); QString defaultShadowBuildDirectory(const QString &projectLocation, const QString &id); - virtual bool supportsTargetId(const QString &id) const; + bool supportsTargetId(const QString &id) const; - QList<BuildConfigurationInfo> availableBuildConfigurations(const QString &proFilePath); + QList<BuildConfigurationInfo> availableBuildConfigurations(const QString &id, const QString &proFilePath, const QtVersionNumber &minimumQtVersion); + bool isMobileTarget(const QString &id); Qt4BaseTarget *create(ProjectExplorer::Project *parent, const QString &id); - Qt4BaseTarget *create(ProjectExplorer::Project *parent, const QString &id, QList<BuildConfigurationInfo> infos); + Qt4BaseTarget *create(ProjectExplorer::Project *parent, const QString &id, const QList<BuildConfigurationInfo> &infos); }; } diff --git a/src/plugins/qt4projectmanager/qt-maemo/qt4maemotargetfactory.cpp b/src/plugins/qt4projectmanager/qt-maemo/qt4maemotargetfactory.cpp index 4dbfe011abd..b485fb6febe 100644 --- a/src/plugins/qt4projectmanager/qt-maemo/qt4maemotargetfactory.cpp +++ b/src/plugins/qt4projectmanager/qt-maemo/qt4maemotargetfactory.cpp @@ -44,8 +44,6 @@ #include <projectexplorer/projectexplorerconstants.h> #include <projectexplorer/customexecutablerunconfiguration.h> -#include <QtGui/QApplication> - using namespace Qt4ProjectManager; using namespace Qt4ProjectManager::Internal; using ProjectExplorer::idFromMap; @@ -72,7 +70,7 @@ bool Qt4MaemoTargetFactory::supportsTargetId(const QString &id) const QStringList Qt4MaemoTargetFactory::supportedTargetIds(ProjectExplorer::Project *parent) const { QStringList targetIds; - if (!qobject_cast<Qt4Project *>(parent)) + if (parent && !qobject_cast<Qt4Project *>(parent)) return targetIds; if (QtVersionManager::instance()->supportsTargetId(QLatin1String(Constants::MAEMO5_DEVICE_TARGET_ID))) targetIds << QLatin1String(Constants::MAEMO5_DEVICE_TARGET_ID); @@ -151,19 +149,10 @@ QString Qt4MaemoTargetFactory::defaultShadowBuildDirectory(const QString &projec return projectLocation + QLatin1Char('-') + suffix; } -QList<BuildConfigurationInfo> Qt4MaemoTargetFactory::availableBuildConfigurations(const QString &proFilePath) -{ - return QList<BuildConfigurationInfo>() - << availableBuildConfigurations(proFilePath, QLatin1String(Constants::MAEMO5_DEVICE_TARGET_ID)) - << availableBuildConfigurations(proFilePath, QLatin1String(Constants::HARMATTAN_DEVICE_TARGET_ID)) - << availableBuildConfigurations(proFilePath, QLatin1String(Constants::MEEGO_DEVICE_TARGET_ID)); -} - -QList<BuildConfigurationInfo> Qt4MaemoTargetFactory::availableBuildConfigurations(const QString &proFilePath, - const QString &id) +QList<BuildConfigurationInfo> Qt4MaemoTargetFactory::availableBuildConfigurations(const QString &id, const QString &proFilePath, const QtVersionNumber &minimumQtVersion) { QList<BuildConfigurationInfo> infos; - QList<QtVersion *> knownVersions = QtVersionManager::instance()->versionsForTargetId(id); + QList<QtVersion *> knownVersions = QtVersionManager::instance()->versionsForTargetId(id, minimumQtVersion); foreach (QtVersion *version, knownVersions) { if (!version->isValid()) @@ -176,6 +165,12 @@ QList<BuildConfigurationInfo> Qt4MaemoTargetFactory::availableBuildConfiguration return infos; } +bool Qt4MaemoTargetFactory::isMobileTarget(const QString &id) +{ + Q_UNUSED(id) + return true; +} + Qt4BaseTarget *Qt4MaemoTargetFactory::create(ProjectExplorer::Project *parent, const QString &id) { if (!canCreate(parent, id)) @@ -196,7 +191,7 @@ Qt4BaseTarget *Qt4MaemoTargetFactory::create(ProjectExplorer::Project *parent, c } Qt4BaseTarget *Qt4MaemoTargetFactory::create(ProjectExplorer::Project *parent, - const QString &id, QList<BuildConfigurationInfo> infos) + const QString &id, const QList<BuildConfigurationInfo> &infos) { if (!canCreate(parent, id)) return 0; diff --git a/src/plugins/qt4projectmanager/qt-maemo/qt4maemotargetfactory.h b/src/plugins/qt4projectmanager/qt-maemo/qt4maemotargetfactory.h index 819de2b09e2..fbf02731a85 100644 --- a/src/plugins/qt4projectmanager/qt-maemo/qt4maemotargetfactory.h +++ b/src/plugins/qt4projectmanager/qt-maemo/qt4maemotargetfactory.h @@ -55,15 +55,13 @@ public: Qt4ProjectManager::Qt4BaseTarget *restore(ProjectExplorer::Project *parent, const QVariantMap &map); QString defaultShadowBuildDirectory(const QString &projectLocation, const QString &id); - virtual bool supportsTargetId(const QString &id) const; + bool supportsTargetId(const QString &id) const; - QList<BuildConfigurationInfo> availableBuildConfigurations(const QString &proFilePath); Qt4BaseTarget *create(ProjectExplorer::Project *parent, const QString &id); - Qt4BaseTarget *create(ProjectExplorer::Project *parent, const QString &id, QList<BuildConfigurationInfo> infos); + Qt4BaseTarget *create(ProjectExplorer::Project *parent, const QString &id, const QList<BuildConfigurationInfo> &infos); -private: - QList<BuildConfigurationInfo> availableBuildConfigurations(const QString &proFilePath, - const QString &id); + QList<BuildConfigurationInfo> availableBuildConfigurations(const QString &id, const QString &proFilePath, const QtVersionNumber &minimumQtVersion); + bool isMobileTarget(const QString &id); }; } // namespace Internal diff --git a/src/plugins/qt4projectmanager/qt-s60/qt4symbiantargetfactory.cpp b/src/plugins/qt4projectmanager/qt-s60/qt4symbiantargetfactory.cpp index 767c068bd64..7766ca4b211 100644 --- a/src/plugins/qt4projectmanager/qt-s60/qt4symbiantargetfactory.cpp +++ b/src/plugins/qt4projectmanager/qt-s60/qt4symbiantargetfactory.cpp @@ -72,7 +72,7 @@ bool Qt4SymbianTargetFactory::supportsTargetId(const QString &id) const QStringList Qt4SymbianTargetFactory::supportedTargetIds(ProjectExplorer::Project *parent) const { - if (!qobject_cast<Qt4Project *>(parent)) + if (parent && !qobject_cast<Qt4Project *>(parent)) return QStringList(); QStringList ids; @@ -139,33 +139,34 @@ QString Qt4SymbianTargetFactory::defaultShadowBuildDirectory(const QString &proj return projectLocation + QChar('-') + shortName; } -QList<BuildConfigurationInfo> Qt4SymbianTargetFactory::availableBuildConfigurations(const QString &proFilePath) +QList<BuildConfigurationInfo> Qt4SymbianTargetFactory::availableBuildConfigurations(const QString &id, const QString &proFilePath, const QtVersionNumber &minimumQtVersion) { QList<BuildConfigurationInfo> infos; - QList<QtVersion *> knownVersions = QtVersionManager::instance()->versionsForTargetId(Constants::S60_EMULATOR_TARGET_ID); + QList<QtVersion *> knownVersions = QtVersionManager::instance()->versionsForTargetId(id, minimumQtVersion); foreach (QtVersion *version, knownVersions) { if (!version->isValid()) continue; bool buildAll = version->defaultBuildConfig() & QtVersion::BuildAll; QtVersion::QmakeBuildConfigs config = buildAll ? QtVersion::BuildAll : QtVersion::QmakeBuildConfig(0); - QString dir = defaultShadowBuildDirectory(Qt4Project::defaultTopLevelBuildDirectory(proFilePath), Constants::S60_EMULATOR_TARGET_ID); - infos.append(BuildConfigurationInfo(version, config | QtVersion::DebugBuild, QString(), dir)); - } - - knownVersions = QtVersionManager::instance()->versionsForTargetId(Constants::S60_DEVICE_TARGET_ID); - foreach (QtVersion *version, knownVersions) { - if (!version->isValid()) - continue; - QtVersion::QmakeBuildConfigs config = version->defaultBuildConfig(); - QString dir = defaultShadowBuildDirectory(Qt4Project::defaultTopLevelBuildDirectory(proFilePath), Constants::S60_DEVICE_TARGET_ID); - infos.append(BuildConfigurationInfo(version, config, QString(), dir)); - infos.append(BuildConfigurationInfo(version, config ^ QtVersion::DebugBuild, QString(), dir)); + QString dir = defaultShadowBuildDirectory(Qt4Project::defaultTopLevelBuildDirectory(proFilePath), id); + if (id == Constants::S60_EMULATOR_TARGET_ID) { + infos.append(BuildConfigurationInfo(version, config | QtVersion::DebugBuild, QString(), dir)); + } else { + infos.append(BuildConfigurationInfo(version, config, QString(), dir)); + infos.append(BuildConfigurationInfo(version, config ^ QtVersion::DebugBuild, QString(), dir)); + } } return infos; } +bool Qt4SymbianTargetFactory::isMobileTarget(const QString &id) +{ + Q_UNUSED(id) + return true; +} + Qt4BaseTarget *Qt4SymbianTargetFactory::create(ProjectExplorer::Project *parent, const QString &id) { if (!canCreate(parent, id)) @@ -192,7 +193,7 @@ Qt4BaseTarget *Qt4SymbianTargetFactory::create(ProjectExplorer::Project *parent, return create(parent, id, infos); } -Qt4BaseTarget *Qt4SymbianTargetFactory::create(ProjectExplorer::Project *parent, const QString &id, QList<BuildConfigurationInfo> infos) +Qt4BaseTarget *Qt4SymbianTargetFactory::create(ProjectExplorer::Project *parent, const QString &id, const QList<BuildConfigurationInfo> &infos) { if (!canCreate(parent, id)) return 0; @@ -210,3 +211,11 @@ Qt4BaseTarget *Qt4SymbianTargetFactory::create(ProjectExplorer::Project *parent, t->addRunConfiguration(new ProjectExplorer::CustomExecutableRunConfiguration(t)); return t; } + +Qt4BaseTarget *Qt4SymbianTargetFactory::create(ProjectExplorer::Project *parent, const QString &id, Qt4TargetSetupWidget *widget) +{ + if (!widget->isTargetSelected()) + return 0; + Qt4DefaultTargetSetupWidget *w = static_cast<Qt4DefaultTargetSetupWidget *>(widget); + return create(parent, id, w->buildConfigurationInfos()); +} diff --git a/src/plugins/qt4projectmanager/qt-s60/qt4symbiantargetfactory.h b/src/plugins/qt4projectmanager/qt-s60/qt4symbiantargetfactory.h index f591a2b4b45..923efb329aa 100644 --- a/src/plugins/qt4projectmanager/qt-s60/qt4symbiantargetfactory.h +++ b/src/plugins/qt4projectmanager/qt-s60/qt4symbiantargetfactory.h @@ -52,13 +52,15 @@ public: bool canCreate(ProjectExplorer::Project *parent, const QString &id) const; bool canRestore(ProjectExplorer::Project *parent, const QVariantMap &map) const; - Qt4ProjectManager::Qt4BaseTarget *restore(ProjectExplorer::Project *parent, const QVariantMap &map); + Qt4BaseTarget *create(ProjectExplorer::Project *parent, const QString &id); - Qt4BaseTarget *create(ProjectExplorer::Project *parent, const QString &id, QList<BuildConfigurationInfo> infos); + Qt4BaseTarget *create(ProjectExplorer::Project *parent, const QString &id, const QList<BuildConfigurationInfo> &infos); + Qt4BaseTarget *create(ProjectExplorer::Project *parent, const QString &id, Qt4TargetSetupWidget *widget); QString defaultShadowBuildDirectory(const QString &projectLocation, const QString &id); - QList<BuildConfigurationInfo> availableBuildConfigurations(const QString &proFilePath); + QList<BuildConfigurationInfo> availableBuildConfigurations(const QString &id, const QString &proFilePath, const QtVersionNumber &minimumQtVersion); + bool isMobileTarget(const QString &id); }; } // namespace Internal diff --git a/src/plugins/qt4projectmanager/qt-s60/s60symbiancertificate.cpp b/src/plugins/qt4projectmanager/qt-s60/s60symbiancertificate.cpp index f60288555c7..26f0e23f47a 100644 --- a/src/plugins/qt4projectmanager/qt-s60/s60symbiancertificate.cpp +++ b/src/plugins/qt4projectmanager/qt-s60/s60symbiancertificate.cpp @@ -67,7 +67,7 @@ namespace { /* * X.509 S60 Certificate Extension */ -class S60CertificateExtension : public Certificate_Extension +class S60CertificateExtension : Certificate_Extension { public: OID oid_of() const; diff --git a/src/plugins/qt4projectmanager/qt4target.cpp b/src/plugins/qt4projectmanager/qt4target.cpp index 1549a670d98..e220109fef8 100644 --- a/src/plugins/qt4projectmanager/qt4target.cpp +++ b/src/plugins/qt4projectmanager/qt4target.cpp @@ -39,12 +39,21 @@ #include "qt4projectmanagerconstants.h" #include "qt4projectconfigwidget.h" +#include <coreplugin/icore.h> #include <extensionsystem/pluginmanager.h> #include <projectexplorer/buildsteplist.h> #include <projectexplorer/runconfiguration.h> #include <projectexplorer/customexecutablerunconfiguration.h> #include <projectexplorer/toolchainmanager.h> #include <projectexplorer/projectexplorerconstants.h> +#include <projectexplorer/task.h> +#include <utils/pathchooser.h> +#include <utils/detailswidget.h> + +#include <QtGui/QPushButton> +#include <QtGui/QMessageBox> +#include <QtGui/QCheckBox> +#include <QtGui/QMainWindow> using namespace Qt4ProjectManager; using namespace Qt4ProjectManager::Internal; @@ -64,6 +73,24 @@ Qt4BaseTargetFactory::~Qt4BaseTargetFactory() } +Qt4TargetSetupWidget *Qt4BaseTargetFactory::createTargetSetupWidget(const QString &id, + const QString &proFilePath, + const QtVersionNumber &number, + bool importEnabled, + QList<BuildConfigurationInfo> importInfos) +{ + return new Qt4DefaultTargetSetupWidget(this, id, proFilePath, number, importEnabled, importInfos); +} + +Qt4BaseTarget *Qt4BaseTargetFactory::create(ProjectExplorer::Project *parent, const QString &id, Qt4TargetSetupWidget *widget) +{ + if (!widget->isTargetSelected()) + return 0; + Q_ASSERT(qobject_cast<Qt4DefaultTargetSetupWidget *>(widget)); + Qt4DefaultTargetSetupWidget *w = static_cast<Qt4DefaultTargetSetupWidget *>(widget); + return create(parent, id, w->buildConfigurationInfos()); +} + Qt4BaseTargetFactory *Qt4BaseTargetFactory::qt4BaseTargetFactoryForId(const QString &id) { QList<Qt4BaseTargetFactory *> factories = ExtensionSystem::PluginManager::instance()->getObjects<Qt4BaseTargetFactory>(); @@ -229,3 +256,534 @@ void Qt4BaseTarget::emitProFileEvaluateNeeded() { emit proFileEvaluateNeeded(this); } + +// ------------------------------------------------------------------------- +// Qt4TargetSetupWidget +// ------------------------------------------------------------------------- + +Qt4TargetSetupWidget::Qt4TargetSetupWidget() + : QWidget(0) +{ + +} + +Qt4TargetSetupWidget::~Qt4TargetSetupWidget() +{ + +} + +// ------------------------------------------------------------------------- +// Qt4DefaultTargetSetupWidget +// ------------------------------------------------------------------------- + +Qt4DefaultTargetSetupWidget::Qt4DefaultTargetSetupWidget(Qt4BaseTargetFactory *factory, + const QString &id, + const QString &proFilePath, + const QtVersionNumber &minimumQtVersion, + bool importEnabled, + QList<BuildConfigurationInfo> importInfos) + : Qt4TargetSetupWidget(), + m_id(id), + m_factory(factory), + m_proFilePath(proFilePath), + m_minimumQtVersion(minimumQtVersion), + m_importInfos(importInfos), + m_directoriesEnabled(true), + m_hasInSourceBuild(false), + m_ignoreChange(false), + m_showImport(importEnabled), + m_selected(0) +{ + QString sourceDir = QFileInfo(m_proFilePath).absolutePath(); + + setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); + QVBoxLayout *vboxLayout = new QVBoxLayout(); + vboxLayout->setMargin(0); + setLayout(vboxLayout); + m_detailsWidget = new Utils::DetailsWidget(this); + m_detailsWidget->setSummaryText(factory->displayNameForId(id)); + m_detailsWidget->setUseCheckBox(true); + m_detailsWidget->setChecked(true); + m_detailsWidget->setSummaryFontBold(true); + m_detailsWidget->setIcon(factory->iconForId(id)); + vboxLayout->addWidget(m_detailsWidget); + + QWidget *widget = new QWidget; + QVBoxLayout *layout = new QVBoxLayout; + widget->setLayout(layout); + + m_importLayout = new QGridLayout; + m_importLayout->setMargin(0); + layout->addLayout(m_importLayout); + + m_importLineLayout = new QHBoxLayout(); + m_importLineLabel = new QLabel(); + m_importLineLabel->setText(tr("Import build from:")); + m_importLineLayout->addWidget(m_importLineLabel); + + m_importLinePath = new Utils::PathChooser(); + m_importLinePath->setExpectedKind(Utils::PathChooser::ExistingDirectory); + m_importLinePath->setPath(sourceDir); + m_importLineLayout->addWidget(m_importLinePath); + + m_importLineButton = new QPushButton; + m_importLineButton->setText(tr("Add Build")); + m_importLineLayout->addWidget(m_importLineButton); + layout->addLayout(m_importLineLayout); + + if (!m_showImport) { + m_importLineLabel->setVisible(false); + m_importLinePath->setVisible(false); + m_importLineButton->setVisible(false); + } + + m_spacerTopWidget = new QWidget; + m_spacerTopWidget->setMinimumHeight(12); + layout->addWidget(m_spacerTopWidget); + + m_shadowBuildEnabled = new QCheckBox; + m_shadowBuildEnabled->setText(tr("Use Shadow Building")); + m_shadowBuildEnabled->setChecked(true); + m_shadowBuildEnabled->setVisible(false); + layout->addWidget(m_shadowBuildEnabled); + + m_spacerBottomWidget = new QWidget; + m_spacerBottomWidget->setMinimumHeight(0); + layout->addWidget(m_spacerBottomWidget); + + m_newBuildsLayout = new QGridLayout; + m_newBuildsLayout->setMargin(0); + layout->addLayout(m_newBuildsLayout); + + m_spacerTopWidget->setVisible(false); + m_spacerBottomWidget->setVisible(false); + + m_detailsWidget->setWidget(widget); + + for (int i = 0; i < m_importInfos.size(); ++i) { + if (m_importInfos.at(i).directory == sourceDir) + m_hasInSourceBuild = true; + m_importEnabled << true; + } + + m_selected += m_importInfos.size(); + + setupImportWidgets(); + + setBuildConfigurationInfos(factory->availableBuildConfigurations(id, proFilePath, minimumQtVersion)); + + if (!m_importInfos.isEmpty()) + m_detailsWidget->setState(Utils::DetailsWidget::Expanded); + + connect(m_importLineButton, SIGNAL(clicked()), + this, SLOT(addImportClicked())); + + connect(m_detailsWidget, SIGNAL(checked(bool)), + this, SIGNAL(selectedToggled())); + connect(m_detailsWidget, SIGNAL(checked(bool)), + widget, SLOT(setEnabled(bool))); + connect(m_shadowBuildEnabled, SIGNAL(toggled(bool)), + this, SLOT(shadowBuildingToggled())); + +} + +Qt4DefaultTargetSetupWidget::~Qt4DefaultTargetSetupWidget() +{ +} + +bool Qt4DefaultTargetSetupWidget::isTargetSelected() const +{ + return m_detailsWidget->isChecked() && m_selected; +} + +void Qt4DefaultTargetSetupWidget::setTargetSelected(bool b) +{ + // Only check target if there are build configurations possible + b == b && !buildConfigurationInfos().isEmpty(); + m_detailsWidget->setChecked(b); + // We want the shadow build option to be visible + if (m_shadowBuildEnabled->isVisible() && b) + m_detailsWidget->setState(Utils::DetailsWidget::Expanded); +} + +QString Qt4DefaultTargetSetupWidget::displayNameFrom(const BuildConfigurationInfo &info) +{ + QString buildType; + if ((info.buildConfig & QtVersion::BuildAll) == 0) { + if (info.buildConfig & QtVersion::DebugBuild) + //: Debug build + buildType = tr("debug"); + else + //: release build + buildType = tr("release"); + } + return info.version->displayName() + " " + buildType; +} + +void Qt4DefaultTargetSetupWidget::setProFilePath(const QString &proFilePath) +{ + m_proFilePath = proFilePath; + setBuildConfigurationInfos(m_factory->availableBuildConfigurations(m_id, proFilePath, m_minimumQtVersion), false); +} + +void Qt4DefaultTargetSetupWidget::setShadowBuildCheckBoxVisible(bool b) +{ + m_shadowBuildEnabled->setVisible(b); + m_spacerTopWidget->setVisible(b && !m_importInfos.isEmpty()); + m_spacerBottomWidget->setVisible(b); + m_shadowBuildEnabled->setChecked(!m_hasInSourceBuild); +} + +QList<BuildConfigurationInfo> Qt4DefaultTargetSetupWidget::buildConfigurationInfos() const +{ + QList<BuildConfigurationInfo> infos; + for (int i = 0; i < m_importInfos.size(); ++i) { + if (m_importEnabled.at(i)) + infos << m_importInfos.at(i); + } + + QString sourceDir = QFileInfo(m_proFilePath).absolutePath(); + + int size = m_infos.size(); + for (int i=0; i < size; ++i) { + if (m_enabled.at(i)) { + BuildConfigurationInfo info = m_infos.at(i); + if (m_shadowBuildEnabled->isChecked()) + info.directory = sourceDir; + infos << info; + } + } + return infos; +} + +void Qt4DefaultTargetSetupWidget::addImportClicked() +{ + BuildConfigurationInfo info = BuildConfigurationInfo::checkForBuild(m_importLinePath->path(), m_proFilePath); + if (!info.isValid()) { + QMessageBox::critical(Core::ICore::instance()->mainWindow(), + tr("No build found"), + tr("No Build found in %1 matching project %2.").arg(m_importLinePath->path()).arg(m_proFilePath)); + return; + } + + if (!info.version->supportsTargetId(m_id)) { + QMessageBox::critical(Core::ICore::instance()->mainWindow(), + tr("Incompatible build found"), + tr("The Build found in %1 is incompatible with this target").arg(m_importLinePath->path())); + return; + } + ++m_selected; + m_importEnabled << true; + + m_importInfos << info; + + createImportWidget(info, m_importEnabled.size() - 1); + emit newImportBuildConfiguration(info); +} + +QList<BuildConfigurationInfo> Qt4DefaultTargetSetupWidget::usedImportInfos() +{ + QList<BuildConfigurationInfo> infos; + for (int i = 0; i < m_importInfos.size(); ++i) { + if (m_importEnabled.at(i)) + infos << m_importInfos.at(i); + } + return infos; +} + +void Qt4DefaultTargetSetupWidget::setBuildConfigurationInfos(const QList<BuildConfigurationInfo> &infos, bool resetEnabled) +{ + m_infos = infos; + if (resetEnabled || m_infos.size() != m_enabled.size()) { + m_enabled.clear(); + m_selected = 0; + QStringList existingBuilds; + for (int i = 0; i < m_importInfos.size(); ++i) { + const BuildConfigurationInfo &info = m_importInfos.at(i); + existingBuilds << info.directory; + if (m_importEnabled.at(i)) + ++m_selected; + } + + // Default to importing existing builds and disable + // builds that would overwrite imports + for (int i=0; i < m_infos.size(); ++i) { + if (existingBuilds.contains(m_infos.at(i).directory) || m_hasInSourceBuild) { + m_enabled << false; + } else { + m_enabled << true; + ++m_selected; + } + } + + clearWidgets(); + setupWidgets(); + } else { + m_ignoreChange = true; + QString sourceDir = QFileInfo(m_proFilePath).absolutePath(); + for (int i=0; i < m_checkboxes.size(); ++i) { + const BuildConfigurationInfo &info = m_infos.at(i); + + m_checkboxes[i]->setText(displayNameFrom(info)); + if (m_shadowBuildEnabled->isChecked()) + m_pathChoosers[i]->setPath(info.directory); + else + m_pathChoosers[i]->setPath(sourceDir); + reportIssues(i); + } + m_ignoreChange = false; + } +} + +void Qt4DefaultTargetSetupWidget::setupImportWidgets() +{ + for (int i = 0; i < m_importInfos.size(); ++i) + createImportWidget(m_importInfos.at(i), i); +} + +void Qt4DefaultTargetSetupWidget::createImportWidget(const BuildConfigurationInfo &info, int pos) +{ + QCheckBox *checkBox = new QCheckBox; + checkBox->setText(tr("Import build from %1").arg(info.directory)); + checkBox->setChecked(m_importEnabled.at(pos)); + m_importLayout->addWidget(checkBox, pos, 0, 1, 2); + + connect(checkBox, SIGNAL(toggled(bool)), + this, SLOT(importCheckBoxToggled(bool))); + + m_importCheckBoxes.append(checkBox); +} + +void Qt4DefaultTargetSetupWidget::setupWidgets() +{ + m_ignoreChange = true; + QString sourceDir = QFileInfo(m_proFilePath).absolutePath(); + for (int i = 0; i < m_infos.size(); ++i) { + const BuildConfigurationInfo &info = m_infos.at(i); + QCheckBox *checkbox = new QCheckBox; + checkbox->setText(displayNameFrom(info)); + checkbox->setChecked(m_enabled.at(i)); + m_newBuildsLayout->addWidget(checkbox, i * 2, 0); + + Utils::PathChooser *pathChooser = new Utils::PathChooser(); + pathChooser->setExpectedKind(Utils::PathChooser::Directory); + if (m_shadowBuildEnabled->isChecked()) + pathChooser->setPath(info.directory); + else + pathChooser->setPath(sourceDir); + pathChooser->setReadOnly(!m_directoriesEnabled); + m_newBuildsLayout->addWidget(pathChooser, i * 2, 1); + + QLabel *reportIssuesLabel = new QLabel; + reportIssuesLabel->setIndent(32); + m_newBuildsLayout->addWidget(reportIssuesLabel, i * 2 + 1, 0, 1, 2); + + connect(checkbox, SIGNAL(toggled(bool)), + this, SLOT(checkBoxToggled(bool))); + + connect(pathChooser, SIGNAL(changed(QString)), + this, SLOT(pathChanged())); + + m_checkboxes.append(checkbox); + m_pathChoosers.append(pathChooser); + m_reportIssuesLabels.append(reportIssuesLabel); + reportIssues(i); + } + m_ignoreChange = false; +} + +void Qt4DefaultTargetSetupWidget::clearWidgets() +{ + qDeleteAll(m_checkboxes); + m_checkboxes.clear(); + qDeleteAll(m_pathChoosers); + m_pathChoosers.clear(); + qDeleteAll(m_reportIssuesLabels); + m_reportIssuesLabels.clear(); +} + +void Qt4DefaultTargetSetupWidget::checkBoxToggled(bool b) +{ + QCheckBox *box = qobject_cast<QCheckBox *>(sender()); + if (!box) + return; + int index = m_checkboxes.indexOf(box); + if (index == -1) + return; + if (m_enabled[index] == b) + return; + m_selected += b ? 1 : -1; + m_enabled[index] = b; + if ((m_selected == 0 && !b) || (m_selected == 1 && b)) + emit selectedToggled(); +} + +void Qt4DefaultTargetSetupWidget::importCheckBoxToggled(bool b) +{ + QCheckBox *box = qobject_cast<QCheckBox *>(sender()); + if (!box) + return; + int index = m_importCheckBoxes.indexOf(box); + if (index == -1) + return; + if (m_importEnabled[index] == b) + return; + m_selected += b ? 1 : -1; + m_importEnabled[index] = b; + if ((m_selected == 0 && !b) || (m_selected == 1 && b)) + emit selectedToggled(); +} + +void Qt4DefaultTargetSetupWidget::pathChanged() +{ + if (m_ignoreChange) + return; + Utils::PathChooser *pathChooser = qobject_cast<Utils::PathChooser *>(sender()); + if (!pathChooser) + return; + int index = m_pathChoosers.indexOf(pathChooser); + if (index == -1) + return; + m_infos[index].directory = pathChooser->path(); + reportIssues(index); +} + +void Qt4DefaultTargetSetupWidget::shadowBuildingToggled() +{ + m_ignoreChange = true; + bool b = m_shadowBuildEnabled->isChecked(); + if (m_directoriesEnabled == b) + return; + m_directoriesEnabled = b; + QString sourceDir = QFileInfo(m_proFilePath).absolutePath(); + for (int i = 0; i < m_pathChoosers.size(); ++i) { + Utils::PathChooser *pathChooser = m_pathChoosers.at(i); + pathChooser->setReadOnly(!b); + if (b) + pathChooser->setPath(m_infos.at(i).directory); + else + pathChooser->setPath(sourceDir); + reportIssues(i); + } + m_ignoreChange = false; +} + +void Qt4DefaultTargetSetupWidget::reportIssues(int index) +{ + QPair<ProjectExplorer::Task::TaskType, QString> issues = findIssues(m_infos.at(index)); + QLabel *reportIssuesLabel = m_reportIssuesLabels.at(index); + reportIssuesLabel->setText(issues.second); + reportIssuesLabel->setVisible(issues.first != ProjectExplorer::Task::Unknown); +} + +QPair<ProjectExplorer::Task::TaskType, QString> Qt4DefaultTargetSetupWidget::findIssues(const BuildConfigurationInfo &info) +{ + if (m_proFilePath.isEmpty()) + return qMakePair(ProjectExplorer::Task::Unknown, QString()); + + QString buildDir = info.directory; + QtVersion *version = info.version; + + QList<ProjectExplorer::Task> issues = version->reportIssues(m_proFilePath, buildDir); + + QString text; + ProjectExplorer::Task::TaskType highestType = ProjectExplorer::Task::Unknown; + foreach (const ProjectExplorer::Task &t, issues) { + if (!text.isEmpty()) + text.append(QLatin1String("<br>")); + // set severity: + QString severity; + if (t.type == ProjectExplorer::Task::Error) { + highestType = ProjectExplorer::Task::Error; + severity = tr("<b>Error:</b> ", "Severity is Task::Error"); + } else if (t.type == ProjectExplorer::Task::Warning) { + if (highestType == ProjectExplorer::Task::Unknown) + highestType = ProjectExplorer::Task::Warning; + severity = tr("<b>Warning:</b> ", "Severity is Task::Warning"); + } + text.append(severity + t.description); + } + if (!text.isEmpty()) + text = QLatin1String("<nobr>") + text; + return qMakePair(highestType, text); +} + +// ----------------------- +// BuildConfigurationInfo +// ----------------------- + +QList<BuildConfigurationInfo> BuildConfigurationInfo::filterBuildConfigurationInfos(const QList<BuildConfigurationInfo> &infos, const QString &id) +{ + QList<BuildConfigurationInfo> result; + foreach (const BuildConfigurationInfo &info, infos) + if (info.version->supportsTargetId(id)) + result.append(info); + return result; +} + +QList<BuildConfigurationInfo> BuildConfigurationInfo::importBuildConfigurations(const QString &proFilePath) +{ + QList<BuildConfigurationInfo> result; + + // Check for in source build first + QString sourceDir = QFileInfo(proFilePath).absolutePath(); + result.append(checkForBuild(sourceDir, proFilePath)); + + // If we found a in source build, we do not search for out of source builds + if (!result.isEmpty()) + return result; + + // Check for builds in build directoy + QList<Qt4BaseTargetFactory *> factories = + ExtensionSystem::PluginManager::instance()->getObjects<Qt4BaseTargetFactory>(); + QString defaultTopLevelBuildDirectory = Qt4Project::defaultTopLevelBuildDirectory(proFilePath); + foreach (Qt4BaseTargetFactory *factory, factories) { + foreach (const QString &id, factory->supportedTargetIds(0)) { + QString expectedBuild = factory->defaultShadowBuildDirectory(defaultTopLevelBuildDirectory, id); + result.append(checkForBuild(expectedBuild, proFilePath)); + } + } + return result; +} + +BuildConfigurationInfo BuildConfigurationInfo::checkForBuild(const QString &directory, const QString &proFilePath) +{ + QString makefile = directory + "/Makefile"; + QString qmakeBinary = QtVersionManager::findQMakeBinaryFromMakefile(makefile); + if (qmakeBinary.isEmpty()) + return BuildConfigurationInfo(); + if (!QtVersionManager::makefileIsFor(makefile, proFilePath)) + return BuildConfigurationInfo(); + + bool temporaryQtVersion = false; + QtVersion *version = QtVersionManager::instance()->qtVersionForQMakeBinary(qmakeBinary); + if (!version) { + version = new QtVersion(qmakeBinary); + temporaryQtVersion = true; + } + + QPair<QtVersion::QmakeBuildConfigs, QString> makefileBuildConfig = + QtVersionManager::scanMakeFile(makefile, version->defaultBuildConfig()); + + QString additionalArguments = makefileBuildConfig.second; + QString parsedSpec = Qt4BuildConfiguration::extractSpecFromArguments(&additionalArguments, directory, version); + QString versionSpec = version->mkspec(); + + QString specArgument; + // Compare mkspecs and add to additional arguments + if (parsedSpec.isEmpty() || parsedSpec == versionSpec || parsedSpec == "default") { + // using the default spec, don't modify additional arguments + } else { + specArgument = "-spec " + Utils::QtcProcess::quoteArg(parsedSpec); + } + Utils::QtcProcess::addArgs(&specArgument, additionalArguments); + + + BuildConfigurationInfo info = BuildConfigurationInfo(version, + makefileBuildConfig.first, + specArgument, + directory, + true, + temporaryQtVersion); + return info; +} diff --git a/src/plugins/qt4projectmanager/qt4target.h b/src/plugins/qt4projectmanager/qt4target.h index 7aa7be7381a..cfc1e53249e 100644 --- a/src/plugins/qt4projectmanager/qt4target.h +++ b/src/plugins/qt4projectmanager/qt4target.h @@ -40,6 +40,19 @@ #include <projectexplorer/target.h> #include <projectexplorer/projectnodes.h> +namespace Utils { +class DetailsWidget; +class PathChooser; +} + +QT_BEGIN_NAMESPACE +class QCheckBox; +class QHBoxLayout; +class QGridLayout; +class QLabel; +class QPushButton; +QT_END_NAMESPACE + namespace Qt4ProjectManager { class Qt4Project; @@ -49,14 +62,31 @@ class Qt4ProFileNode; } struct BuildConfigurationInfo { + explicit BuildConfigurationInfo() + : version(0), buildConfig(QtVersion::QmakeBuildConfig(0)), importing(false), temporaryQtVersion(false) + {} + explicit BuildConfigurationInfo(QtVersion *v, QtVersion::QmakeBuildConfigs bc, - const QString &aa, const QString &d) : - version(v), buildConfig(bc), additionalArguments(aa), directory(d) + const QString &aa, const QString &d, bool importing_ = false, bool temporaryQtVersion_ = false) : + version(v), buildConfig(bc), additionalArguments(aa), directory(d), importing(importing_), temporaryQtVersion(temporaryQtVersion_) { } + + bool isValid() const + { + return version != 0; + } + QtVersion *version; QtVersion::QmakeBuildConfigs buildConfig; QString additionalArguments; QString directory; + bool importing; + bool temporaryQtVersion; + + + static QList<BuildConfigurationInfo> importBuildConfigurations(const QString &proFilePath); + static BuildConfigurationInfo checkForBuild(const QString &directory, const QString &proFilePath); + static QList<BuildConfigurationInfo> filterBuildConfigurationInfos(const QList<BuildConfigurationInfo> &infos, const QString &id); }; class Qt4BaseTarget : public ProjectExplorer::Target @@ -101,6 +131,21 @@ private slots: void emitProFileEvaluateNeeded(); }; +class QT4PROJECTMANAGER_EXPORT Qt4TargetSetupWidget : public QWidget +{ + Q_OBJECT +public: + Qt4TargetSetupWidget(); + ~Qt4TargetSetupWidget(); + virtual bool isTargetSelected() const = 0; + virtual void setTargetSelected(bool b) = 0; + virtual void setProFilePath(const QString &proFilePath) = 0; + virtual QList<BuildConfigurationInfo> usedImportInfos() = 0; +signals: + void selectedToggled() const; + void newImportBuildConfiguration(const BuildConfigurationInfo &info); +}; + class QT4PROJECTMANAGER_EXPORT Qt4BaseTargetFactory : public ProjectExplorer::ITargetFactory { Q_OBJECT @@ -108,23 +153,101 @@ public: Qt4BaseTargetFactory(QObject *parent); ~Qt4BaseTargetFactory(); - virtual QString defaultShadowBuildDirectory(const QString &projectLocation, const QString &id) =0; - virtual QList<BuildConfigurationInfo> availableBuildConfigurations(const QString &proFilePath) = 0; - - virtual Qt4BaseTarget *create(ProjectExplorer::Project *parent, const QString &id) = 0; - virtual Qt4BaseTarget *create(ProjectExplorer::Project *parent, - const QString &id, - QList<BuildConfigurationInfo> infos) = 0; + virtual Qt4TargetSetupWidget *createTargetSetupWidget(const QString &id, + const QString &proFilePath, + const QtVersionNumber &minimumQtVersion, + bool importEnabled, + QList<BuildConfigurationInfo> importInfos); + virtual QString defaultShadowBuildDirectory(const QString &projectLocation, const QString &id) =0; + /// used by the default implementation of createTargetSetupWidget + /// not needed otherwise + virtual QList<BuildConfigurationInfo> availableBuildConfigurations(const QString &id, const QString &proFilePath, const QtVersionNumber &minimumQtVersion) = 0; /// only used in the TargetSetupPage virtual QIcon iconForId(const QString &id) const = 0; + virtual bool isMobileTarget(const QString &id) = 0; + + virtual Qt4BaseTarget *create(ProjectExplorer::Project *parent, const QString &id) = 0; + virtual Qt4BaseTarget *create(ProjectExplorer::Project *parent, const QString &id, const QList<BuildConfigurationInfo> &infos) = 0; + virtual Qt4BaseTarget *create(ProjectExplorer::Project *parent, const QString &id, Qt4TargetSetupWidget *widget); + static Qt4BaseTargetFactory *qt4BaseTargetFactoryForId(const QString &id); protected: static QString msgBuildConfigurationName(const BuildConfigurationInfo &info); }; +class Qt4DefaultTargetSetupWidget : public Qt4TargetSetupWidget +{ + Q_OBJECT +public: + Qt4DefaultTargetSetupWidget(Qt4BaseTargetFactory *factory, + const QString &id, + const QString &proFilePath, + const QtVersionNumber &minimumQtVersion, + bool importEnabled, + QList<BuildConfigurationInfo> importInfos); + ~Qt4DefaultTargetSetupWidget(); + bool isTargetSelected() const; + void setTargetSelected(bool b); + QList<BuildConfigurationInfo> usedImportInfos(); + + QList<BuildConfigurationInfo> buildConfigurationInfos() const; + void setProFilePath(const QString &proFilePath); + + void setShadowBuildCheckBoxVisible(bool b); + +public slots: + void addImportClicked(); + void checkBoxToggled(bool b); + void importCheckBoxToggled(bool b); + void pathChanged(); + void shadowBuildingToggled(); + +private: + void setBuildConfigurationInfos(const QList<BuildConfigurationInfo> &list, bool resetEnabled = true); + void reportIssues(int index); + QPair<ProjectExplorer::Task::TaskType, QString> findIssues(const BuildConfigurationInfo &info); + void createImportWidget(const BuildConfigurationInfo &info, int pos); + + QString m_id; + Qt4BaseTargetFactory *m_factory; + QString m_proFilePath; + QtVersionNumber m_minimumQtVersion; + Utils::DetailsWidget *m_detailsWidget; + QGridLayout *m_importLayout; + QGridLayout *m_newBuildsLayout; + QCheckBox *m_shadowBuildEnabled; + QWidget *m_spacerTopWidget; + QWidget *m_spacerBottomWidget; + + // import line widgets + QHBoxLayout *m_importLineLayout; + QLabel *m_importLineLabel; + Utils::PathChooser *m_importLinePath; + QPushButton *m_importLineButton; + + void setupWidgets(); + void clearWidgets(); + void setupImportWidgets(); + QString displayNameFrom(const BuildConfigurationInfo &info); + QList<QCheckBox *> m_checkboxes; + QList<Utils::PathChooser *> m_pathChoosers; + QList<BuildConfigurationInfo> m_infos; + QList<bool> m_enabled; + QList<QCheckBox *> m_importCheckBoxes; + QList<BuildConfigurationInfo> m_importInfos; + QList<bool> m_importEnabled; + QList<QLabel *> m_reportIssuesLabels; + bool m_directoriesEnabled; + bool m_hasInSourceBuild; + bool m_ignoreChange; + bool m_showImport; + int m_selected; + +}; + } // namespace Qt4ProjectManager #endif // QT4TARGET_H diff --git a/src/plugins/qt4projectmanager/qtversionmanager.cpp b/src/plugins/qt4projectmanager/qtversionmanager.cpp index 8132e2502f7..8cbe5961af3 100644 --- a/src/plugins/qt4projectmanager/qtversionmanager.cpp +++ b/src/plugins/qt4projectmanager/qtversionmanager.cpp @@ -1377,16 +1377,6 @@ QSet<QString> QtVersion::supportedTargetIds() const return m_targetIds; } -bool QtVersion::supportsMobileTarget() const -{ - return supportsTargetId(Constants::S60_DEVICE_TARGET_ID) || - supportsTargetId(Constants::S60_EMULATOR_TARGET_ID) || - supportsTargetId(Constants::MAEMO5_DEVICE_TARGET_ID) || - supportsTargetId(Constants::HARMATTAN_DEVICE_TARGET_ID) || - supportsTargetId(Constants::MEEGO_DEVICE_TARGET_ID) || - supportsTargetId(Constants::QT_SIMULATOR_TARGET_ID); -} - QList<ProjectExplorer::Abi> QtVersion::qtAbis() const { updateAbiAndMkspec(); diff --git a/src/plugins/qt4projectmanager/qtversionmanager.h b/src/plugins/qt4projectmanager/qtversionmanager.h index f8ca79ccf4e..aa6f896370c 100644 --- a/src/plugins/qt4projectmanager/qtversionmanager.h +++ b/src/plugins/qt4projectmanager/qtversionmanager.h @@ -110,7 +110,6 @@ public: bool supportsTargetId(const QString &id) const; QSet<QString> supportedTargetIds() const; - bool supportsMobileTarget() const; QList<ProjectExplorer::Abi> qtAbis() const; diff --git a/src/plugins/qt4projectmanager/wizards/abstractmobileappwizard.cpp b/src/plugins/qt4projectmanager/wizards/abstractmobileappwizard.cpp index 1ccb3c063cd..4cb1a3c8463 100644 --- a/src/plugins/qt4projectmanager/wizards/abstractmobileappwizard.cpp +++ b/src/plugins/qt4projectmanager/wizards/abstractmobileappwizard.cpp @@ -54,8 +54,9 @@ AbstractMobileAppWizardDialog::AbstractMobileAppWizardDialog(QWidget *parent) : ProjectExplorer::BaseProjectWizardDialog(parent) { m_targetsPage = new TargetSetupPage; + m_targetsPage->setPreferMobile(true); + m_targetsPage->setMinimumQtVersion(QtVersionNumber(4,7,0)); resize(900, 450); - m_targetsPage->setImportDirectoryBrowsingEnabled(false); m_targetsPageId = addPageWithTitle(m_targetsPage, tr("Qt Versions")); m_genericOptionsPage = new MobileAppWizardGenericOptionsPage; m_genericOptionsPageId = addPageWithTitle(m_genericOptionsPage, diff --git a/src/plugins/qt4projectmanager/wizards/html5appwizard.cpp b/src/plugins/qt4projectmanager/wizards/html5appwizard.cpp index 2afece5bc49..495203083fc 100644 --- a/src/plugins/qt4projectmanager/wizards/html5appwizard.cpp +++ b/src/plugins/qt4projectmanager/wizards/html5appwizard.cpp @@ -117,7 +117,7 @@ AbstractMobileAppWizardDialog *Html5AppWizard::createWizardDialogInternal(QWidge void Html5AppWizard::projectPathChanged(const QString &path) const { - m_d->wizardDialog->m_targetsPage->setImportInfos(TargetSetupPage::importInfosForKnownQtVersions(path)); + m_d->wizardDialog->m_targetsPage->setProFilePath(path); } void Html5AppWizard::prepareGenerateFiles(const QWizard *w, diff --git a/src/plugins/qt4projectmanager/wizards/mobileappwizard.cpp b/src/plugins/qt4projectmanager/wizards/mobileappwizard.cpp index ac6407e1bed..3bbb12e2fcc 100644 --- a/src/plugins/qt4projectmanager/wizards/mobileappwizard.cpp +++ b/src/plugins/qt4projectmanager/wizards/mobileappwizard.cpp @@ -109,7 +109,7 @@ AbstractMobileAppWizardDialog *MobileAppWizard::createWizardDialogInternal(QWidg void MobileAppWizard::projectPathChanged(const QString &path) const { - m_d->wizardDialog->m_targetsPage->setImportInfos(TargetSetupPage::importInfosForKnownQtVersions(path)); + m_d->wizardDialog->m_targetsPage->setProFilePath(path); } void MobileAppWizard::prepareGenerateFiles(const QWizard *w, diff --git a/src/plugins/qt4projectmanager/wizards/qtquickappwizard.cpp b/src/plugins/qt4projectmanager/wizards/qtquickappwizard.cpp index b3b5f31df48..04204fccf2f 100644 --- a/src/plugins/qt4projectmanager/wizards/qtquickappwizard.cpp +++ b/src/plugins/qt4projectmanager/wizards/qtquickappwizard.cpp @@ -117,21 +117,7 @@ AbstractMobileAppWizardDialog *QtQuickAppWizard::createWizardDialogInternal(QWid void QtQuickAppWizard::projectPathChanged(const QString &path) const { - const QList<TargetSetupPage::ImportInfo> &qtVersions - = TargetSetupPage::importInfosForKnownQtVersions(path); - QList<TargetSetupPage::ImportInfo> qmlQtVersions; - foreach (const TargetSetupPage::ImportInfo &qtVersion, qtVersions) { - const QString versionString = qtVersion.version->qtVersionString(); - bool isNumber; - const int majorVersion = versionString.mid(0, 1).toInt(&isNumber); - if (!isNumber || majorVersion < 4) - continue; - const int minorVersion = versionString.mid(2, 1).toInt(&isNumber); - if (!isNumber || (majorVersion == 4 && minorVersion < 7)) - continue; - qmlQtVersions << qtVersion; - } - m_d->wizardDialog->m_targetsPage->setImportInfos(qmlQtVersions); + m_d->wizardDialog->m_targetsPage->setProFilePath(path); } void QtQuickAppWizard::prepareGenerateFiles(const QWizard *w, diff --git a/src/plugins/qt4projectmanager/wizards/qtwizard.cpp b/src/plugins/qt4projectmanager/wizards/qtwizard.cpp index dc7a3a53f06..9f2815572e2 100644 --- a/src/plugins/qt4projectmanager/wizards/qtwizard.cpp +++ b/src/plugins/qt4projectmanager/wizards/qtwizard.cpp @@ -240,25 +240,13 @@ int BaseQt4ProjectWizardDialog::addTargetSetupPage(QSet<QString> targets, bool m m_targets = targets; resize(900, 450); - connect(this, SIGNAL(projectLocationChanged(QString)), - m_targetSetupPage, SLOT(setProFilePath(QString))); - - QList<TargetSetupPage::ImportInfo> infos = TargetSetupPage::importInfosForKnownQtVersions(path()); - if (!targets.isEmpty()) - infos = TargetSetupPage::filterImportInfos(targets, infos); - m_targetSetupPage->setImportDirectoryBrowsingEnabled(false); m_targetSetupPage->setPreferMobile(mobile); - if (infos.count() <= 1) - return -1; - - m_targetSetupPage->setImportInfos(infos); - if (id >= 0) setPage(id, m_targetSetupPage); else id = addPage(m_targetSetupPage); - wizardProgress()->item(id)->setTitle(tr("Qt Versions")); + wizardProgress()->item(id)->setTitle(tr("Targets")); return id; } @@ -324,11 +312,7 @@ bool BaseQt4ProjectWizardDialog::isTargetSelected(const QString &targetid) const void BaseQt4ProjectWizardDialog::generateProfileName(const QString &name, const QString &path) { const QString proFile = QDir::fromNativeSeparators(path) + QChar('/') + name + QChar('/') + name + QLatin1String(".pro"); - QList<TargetSetupPage::ImportInfo> infos = TargetSetupPage::importInfosForKnownQtVersions(proFile); - if (!m_targets.isEmpty()) - infos = TargetSetupPage::filterImportInfos(m_targets, infos); - m_targetSetupPage->setImportInfos(infos); - emit projectLocationChanged(proFile); + m_targetSetupPage->setProFilePath(proFile); } QSet<QString> BaseQt4ProjectWizardDialog::desktopTarget() diff --git a/src/plugins/qt4projectmanager/wizards/qtwizard.h b/src/plugins/qt4projectmanager/wizards/qtwizard.h index a0a507bee2e..0177b02b6b9 100644 --- a/src/plugins/qt4projectmanager/wizards/qtwizard.h +++ b/src/plugins/qt4projectmanager/wizards/qtwizard.h @@ -146,9 +146,6 @@ public: bool setupProject(Qt4Project *project) const; bool isTargetSelected(const QString &targetid) const; -signals: - void projectLocationChanged(const QString &proFileName); - private slots: void generateProfileName(const QString &name, const QString &path); diff --git a/src/plugins/qt4projectmanager/wizards/targetsetuppage.cpp b/src/plugins/qt4projectmanager/wizards/targetsetuppage.cpp index 5bd3daa7121..9d8b05ac4c3 100644 --- a/src/plugins/qt4projectmanager/wizards/targetsetuppage.cpp +++ b/src/plugins/qt4projectmanager/wizards/targetsetuppage.cpp @@ -46,245 +46,163 @@ #include <utils/qtcassert.h> #include <utils/qtcprocess.h> -#include <QtGui/QAction> -#include <QtGui/QFileDialog> -#include <QtGui/QHeaderView> #include <QtGui/QLabel> #include <QtGui/QLayout> -#include <QtGui/QMenu> -#include <QtGui/QMessageBox> -#include <QtGui/QPushButton> -#include <QtGui/QTreeWidget> using namespace Qt4ProjectManager; using namespace Qt4ProjectManager::Internal; -namespace { -enum Columns { - NAME_COLUMN = 0, - STATUS_COLUMN, - DIRECTORY_COLUMN -}; -} // namespace - TargetSetupPage::TargetSetupPage(QWidget *parent) : QWizardPage(parent), m_preferMobile(false), - m_toggleWillCheck(false), - m_ui(new Ui::TargetSetupPage), - m_contextMenu(0) + m_importSearch(false), + m_spacer(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::Expanding)), + m_ui(new Ui::TargetSetupPage) { m_ui->setupUi(this); - m_ui->versionTree->header()->setResizeMode(0, QHeaderView::ResizeToContents); - m_ui->versionTree->header()->setResizeMode(1, QHeaderView::ResizeToContents); - - m_ui->versionTree->setContextMenuPolicy(Qt::CustomContextMenu); - m_contextMenu = new QMenu(this); - - connect(m_ui->importButton, SIGNAL(clicked()), - this, SLOT(addShadowBuildLocation())); - connect(m_ui->uncheckButton, SIGNAL(clicked()), - this, SLOT(checkAllButtonClicked())); - connect(m_ui->versionTree, SIGNAL(customContextMenuRequested(QPoint)), - this, SLOT(contextMenuRequested(QPoint))); + QWidget *centralWidget = new QWidget(this); + m_ui->scrollArea->setWidget(centralWidget); + m_layout = new QVBoxLayout; + centralWidget->setLayout(m_layout); + m_layout->addSpacerItem(m_spacer); - setTitle(tr("Qt Versions")); + setTitle(tr("Target setup")); } void TargetSetupPage::initializePage() { - // WORKAROUND: Somebody sets all buttons to autoDefault between the ctor and here! - m_ui->importButton->setAutoDefault(false); - m_ui->uncheckButton->setAutoDefault(false); + cleanupImportInfos(); + deleteWidgets(); + + setupImportInfos(); + setupWidgets(); } TargetSetupPage::~TargetSetupPage() { - resetInfos(); + deleteWidgets(); delete m_ui; + cleanupImportInfos(); } -void TargetSetupPage::setImportInfos(const QList<ImportInfo> &infos) +bool TargetSetupPage::isTargetSelected(const QString &id) const { - disconnect(m_ui->versionTree, SIGNAL(itemChanged(QTreeWidgetItem*,int)), - this, SLOT(itemWasChanged())); - - // Create a list of all temporary Qt versions we need to delete in our existing list - QList<QtVersion *> toDelete; - foreach (const ImportInfo &info, m_infos) { - if (info.isTemporary) - toDelete.append(info.version); - } - // Remove those that got copied into the new list to set up - foreach (const ImportInfo &info, infos) { - if (info.isTemporary) - toDelete.removeAll(info.version); - } - // Delete the rest - qDeleteAll(toDelete); - // ... and clear the list - m_infos.clear(); - - // Find possible targets: - QStringList targetIds; - foreach (const ImportInfo &i, infos) { - // Make sure we have no duplicate directories: - bool skip = false; - foreach (const ImportInfo &j, m_infos) { - if (j.isExistingBuild && i.isExistingBuild && (j.directory == i.directory)) { - skip = true; - break; - } - } - if (skip) { - if (i.isTemporary) - delete i.version; - continue; - } + Qt4TargetSetupWidget *widget = m_widgets.value(id); + return widget && widget->isTargetSelected(); +} - m_infos.append(i); +bool TargetSetupPage::isComplete() const +{ + foreach (Qt4TargetSetupWidget *widget, m_widgets) + if (widget->isTargetSelected()) + return true; + return false; +} - QSet<QString> versionTargets = i.version->supportedTargetIds(); - foreach (const QString &t, versionTargets) { - if (!targetIds.contains(t)) - targetIds.append(t); - } - } - qSort(targetIds.begin(), targetIds.end()); +void TargetSetupPage::setPreferMobile(bool mobile) +{ + m_preferMobile = mobile; +} - m_ui->versionTree->clear(); +void TargetSetupPage::setMinimumQtVersion(const QtVersionNumber &number) +{ + m_minimumQtVersionNumber = number; +} - foreach (const QString &targetId, targetIds) { - QTreeWidgetItem *targetItem = new QTreeWidgetItem(m_ui->versionTree); +void TargetSetupPage::setImportSearch(bool b) +{ + m_importSearch = b; +} - Qt4BaseTargetFactory *factory = 0; - QList<Qt4BaseTargetFactory *> factories = - ExtensionSystem::PluginManager::instance()->getObjects<Qt4BaseTargetFactory>(); - foreach (Qt4BaseTargetFactory *fac, factories) { - if (fac->supportsTargetId(targetId)) { - factory = fac; - break; +void TargetSetupPage::setupWidgets() +{ + QList<Qt4BaseTargetFactory *> factories = ExtensionSystem::PluginManager::instance()->getObjects<Qt4BaseTargetFactory>(); + foreach (Qt4BaseTargetFactory *factory, factories) { + QStringList ids = factory->supportedTargetIds(0); + foreach (const QString &id, ids) { + QList<BuildConfigurationInfo> infos = BuildConfigurationInfo::filterBuildConfigurationInfos(m_importInfos, id); + Qt4TargetSetupWidget *widget = + factory->createTargetSetupWidget(id, m_proFilePath, m_minimumQtVersionNumber, m_importSearch, infos); + if (widget) { + widget->setTargetSelected( (m_preferMobile == factory->isMobileTarget(id) && m_importInfos.isEmpty()) + || !infos.isEmpty()); + m_widgets.insert(id, widget); + m_factories.insert(widget, factory); + m_layout->addWidget(widget); + connect(widget, SIGNAL(selectedToggled()), + this, SIGNAL(completeChanged())); + connect(widget, SIGNAL(newImportBuildConfiguration(BuildConfigurationInfo)), + this, SLOT(newImportBuildConfiguration(BuildConfigurationInfo))); } } - if (!factory) - continue; - - QString displayName = factory->displayNameForId(targetId); - - targetItem->setText(0, displayName); - targetItem->setToolTip(0, displayName); - targetItem->setFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable); - targetItem->setData(NAME_COLUMN, Qt::UserRole, targetId); - targetItem->setExpanded(true); - - int pos = -1; - foreach (const ImportInfo &i, m_infos) { - ++pos; - - if (!i.version->supportsTargetId(targetId)) - continue; - QTreeWidgetItem *versionItem = new QTreeWidgetItem(targetItem); - updateVersionItem(versionItem, pos); + } + m_layout->addSpacerItem(m_spacer); +} - // Prefer imports to creating new builds, but precheck any - // Qt that exists (if there is no import with that version) - bool shouldCheck = true; - if (!i.isExistingBuild) { - foreach (const ImportInfo &j, m_infos) { - if (j.isExistingBuild && j.version == i.version) { - shouldCheck = false; - break; - } - } - } +void TargetSetupPage::deleteWidgets() +{ + foreach (Qt4TargetSetupWidget *widget, m_widgets) + delete widget; + m_widgets.clear(); + m_factories.clear(); + m_layout->removeItem(m_spacer); +} - shouldCheck = shouldCheck && (m_preferMobile == i.version->supportsMobileTarget()); - shouldCheck = shouldCheck || i.isExistingBuild; // always check imports - shouldCheck = shouldCheck || m_infos.count() == 1; // always check only option - versionItem->setCheckState(NAME_COLUMN, shouldCheck ? Qt::Checked : Qt::Unchecked); - } +void TargetSetupPage::setProFilePath(const QString &path) +{ + m_proFilePath = path; + if (!m_proFilePath.isEmpty()) { + m_ui->descriptionLabel->setText(tr("Qt Creator can set up the following targets for project <b>%1</b>:", + "%1: Project name").arg(QFileInfo(m_proFilePath).baseName())); } - connect(m_ui->versionTree, SIGNAL(itemChanged(QTreeWidgetItem*,int)), - this, SLOT(itemWasChanged())); - - emit completeChanged(); + deleteWidgets(); + setupWidgets(); } -QList<TargetSetupPage::ImportInfo> TargetSetupPage::importInfos() const +void TargetSetupPage::setupImportInfos() { - return m_infos; + if (m_importSearch) + m_importInfos = BuildConfigurationInfo::importBuildConfigurations(m_proFilePath); } -bool TargetSetupPage::hasSelection() const +void TargetSetupPage::cleanupImportInfos() { - for (int i = 0; i < m_ui->versionTree->topLevelItemCount(); ++i) { - QTreeWidgetItem * current = m_ui->versionTree->topLevelItem(i); - for (int j = 0; j < current->childCount(); ++j) { - QTreeWidgetItem * child = current->child(j); - if (child->checkState(NAME_COLUMN) == Qt::Checked) - return true; - } + foreach (const BuildConfigurationInfo &info, m_importInfos) { + if (info.temporaryQtVersion) + delete info.version; } - return false; } -bool TargetSetupPage::isTargetSelected(const QString &targetid) const +void TargetSetupPage::newImportBuildConfiguration(const BuildConfigurationInfo &info) { - for (int i = 0; i < m_ui->versionTree->topLevelItemCount(); ++i) { - QTreeWidgetItem * current = m_ui->versionTree->topLevelItem(i); - if (current->data(NAME_COLUMN, Qt::UserRole).toString() != targetid) - continue; - for (int j = 0; j < current->childCount(); ++j) { - QTreeWidgetItem * child = current->child(j); - if (child->checkState(NAME_COLUMN) == Qt::Checked) - return true; - } - } - return false; + m_importInfos.append(info); } bool TargetSetupPage::setupProject(Qt4ProjectManager::Qt4Project *project) { - Q_ASSERT(project->targets().isEmpty()); - QtVersionManager *vm = QtVersionManager::instance(); - for (int i = 0; i < m_ui->versionTree->topLevelItemCount(); ++i) { - QTreeWidgetItem *current = m_ui->versionTree->topLevelItem(i); - QString targetId = current->data(NAME_COLUMN, Qt::UserRole).toString(); - - Qt4BaseTargetFactory *qt4TargetFactory = Qt4BaseTargetFactory::qt4BaseTargetFactoryForId(targetId); - if (qt4TargetFactory && qt4TargetFactory->canCreate(project, targetId)) { - QList<BuildConfigurationInfo> targetInfos; - for (int j = 0; j < current->childCount(); ++j) { - QTreeWidgetItem *child = current->child(j); - if (child->checkState(0) != Qt::Checked) - continue; - ImportInfo &info = m_infos[child->data(0, Qt::UserRole).toInt()]; - - // Register temporary Qt version - if (info.isTemporary) { - vm->addVersion(info.version); - info.isTemporary = false; + QMap<QString, Qt4TargetSetupWidget *>::const_iterator it, end; + end = m_widgets.constEnd(); + it = m_widgets.constBegin(); + for ( ; it != end; ++it) { + Qt4BaseTargetFactory *factory = m_factories.value(it.value()); + + foreach (const BuildConfigurationInfo &info, it.value()->usedImportInfos()) { + QtVersion *version = info.version; + for (int i=0; i < m_importInfos.size(); ++i) { + if (m_importInfos.at(i).version == version) { + if (m_importInfos[i].temporaryQtVersion) { + QtVersionManager::instance()->addVersion(m_importInfos[i].version); + m_importInfos[i].temporaryQtVersion = false; + } } - - targetInfos.append(BuildConfigurationInfo(info.version, info.buildConfig, - info.additionalArguments, info.directory)); - } - - // create the target: - Qt4BaseTarget *target = 0; - if (!targetInfos.isEmpty()) { - target = qt4TargetFactory->create(project, targetId, targetInfos); - } - - if (target) { - project->addTarget(target); - if (target->id() == QLatin1String(Constants::QT_SIMULATOR_TARGET_ID)) - project->setActiveTarget(target); } } - } + Qt4BaseTarget *target = factory->create(project, it.key(), it.value()); + if (target) + project->addTarget(target); + } // Create a desktop target if nothing else was set up: if (project->targets().isEmpty()) { @@ -315,346 +233,3 @@ bool TargetSetupPage::setupProject(Qt4ProjectManager::Qt4Project *project) return !project->targets().isEmpty(); } - -void TargetSetupPage::itemWasChanged() -{ - emit completeChanged(); -} - -bool TargetSetupPage::isComplete() const -{ - return hasSelection(); -} - -void TargetSetupPage::setImportDirectoryBrowsingEnabled(bool browsing) -{ - m_ui->importButton->setEnabled(browsing); - m_ui->importButton->setVisible(browsing); -} - -void TargetSetupPage::setImportDirectoryBrowsingLocation(const QString &directory) -{ - m_defaultShadowBuildLocation = directory; -} - -void TargetSetupPage::setPreferMobile(bool mobile) -{ - m_preferMobile = mobile; -} - -void TargetSetupPage::setProFilePath(const QString &path) -{ - m_proFilePath = path; - if (!m_proFilePath.isEmpty()) { - m_ui->descriptionLabel->setText(tr("Qt Creator can set up the following targets for<br>project <b>%1</b>:", - "%1: Project name").arg(QFileInfo(m_proFilePath).baseName())); - } - // Force regeneration of tree widget contents: - QList<ImportInfo> tmp = m_infos; - setImportInfos(tmp); -} - -QList<TargetSetupPage::ImportInfo> TargetSetupPage::importInfosForKnownQtVersions(const QString &proFilePath) -{ - QList<Qt4BaseTargetFactory *> factories = - ExtensionSystem::PluginManager::instance()->getObjects<Qt4BaseTargetFactory>(); - - QList<BuildConfigurationInfo> bcinfos; - - foreach (Qt4BaseTargetFactory *fac, factories) - bcinfos.append(fac->availableBuildConfigurations(proFilePath)); - - QList<ImportInfo> infos; - foreach (const BuildConfigurationInfo &info, bcinfos) { - infos.append(ImportInfo(info)); - } - - if (infos.isEmpty()) { - // Fallback to the Qt in Path version - ImportInfo info; - info.isExistingBuild = false; - info.isTemporary = false; - info.version = QtVersionManager::instance()->versions().at(0); - info.buildConfig = info.version->defaultBuildConfig(); - infos.append(info); - } - return infos; -} - -QList<TargetSetupPage::ImportInfo> TargetSetupPage::filterImportInfos(const QSet<QString> &validTargets, - const QList<ImportInfo> &infos) -{ - QList<ImportInfo> results; - foreach (const ImportInfo &info, infos) { - Q_ASSERT(info.version); - foreach (const QString &target, validTargets) { - if (info.version->supportsTargetId(target)) - results.append(info); - } - } - return results; -} - -QList<TargetSetupPage::ImportInfo> -TargetSetupPage::scanDefaultProjectDirectories(Qt4ProjectManager::Qt4Project *project) -{ - // Source directory: - QList<ImportInfo> importVersions = TargetSetupPage::recursivelyCheckDirectoryForBuild(project->projectDirectory(), - project->file()->fileName()); - QtVersionManager *vm = QtVersionManager::instance(); - foreach(const QString &id, vm->supportedTargetIds()) { - Qt4BaseTargetFactory *qt4Factory = Qt4BaseTargetFactory::qt4BaseTargetFactoryForId(id); - QString location = qt4Factory->defaultShadowBuildDirectory(project->defaultTopLevelBuildDirectory(), id); - importVersions.append(TargetSetupPage::recursivelyCheckDirectoryForBuild(location, - project->file()->fileName())); - } - return importVersions; -} - -QList<TargetSetupPage::ImportInfo> -TargetSetupPage::recursivelyCheckDirectoryForBuild(const QString &directory, const QString &proFile, int maxdepth) -{ - QList<ImportInfo> results; - - if (maxdepth <= 0 || directory.isEmpty()) - return results; - - // Check for in-source builds first: - QString qmakeBinary = QtVersionManager::findQMakeBinaryFromMakefile(directory + "/Makefile"); - QDir dir(directory); - - // Recurse into subdirectories: - if (qmakeBinary.isNull() || !QtVersionManager::makefileIsFor(directory + "/Makefile", proFile)) { - QStringList subDirs = dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot); - foreach (QString subDir, subDirs) - results.append(recursivelyCheckDirectoryForBuild(dir.absoluteFilePath(subDir), - proFile, maxdepth - 1)); - return results; - } - - // Shiny fresh directory with a Makefile... - QtVersionManager * vm = QtVersionManager::instance(); - TargetSetupPage::ImportInfo info; - info.directory = dir.absolutePath(); - - // This also means we have a build in there - // First get the qt version - info.version = vm->qtVersionForQMakeBinary(qmakeBinary); - info.isExistingBuild = true; - - // Okay does not yet exist, create - if (!info.version) { - info.version = new QtVersion(qmakeBinary); - info.isTemporary = true; - } - - QPair<QtVersion::QmakeBuildConfigs, QString> result = - QtVersionManager::scanMakeFile(directory + "/Makefile", info.version->defaultBuildConfig()); - info.buildConfig = result.first; - QString aa = result.second; - QString parsedSpec = Qt4BuildConfiguration::extractSpecFromArguments(&aa, directory, info.version); - QString versionSpec = info.version->mkspec(); - - // Compare mkspecs and add to additional arguments - if (parsedSpec.isEmpty() || parsedSpec == versionSpec || parsedSpec == "default") { - // using the default spec, don't modify additional arguments - } else { - info.additionalArguments = "-spec " + Utils::QtcProcess::quoteArg(parsedSpec); - } - Utils::QtcProcess::addArgs(&info.additionalArguments, aa); - - results.append(info); - return results; -} - -void TargetSetupPage::addShadowBuildLocation() -{ - QString newPath = - QFileDialog::getExistingDirectory(this, - tr("Choose a directory to scan for additional shadow builds"), - m_defaultShadowBuildLocation); - - if (newPath.isEmpty()) - return; - - QFileInfo dir(QDir::fromNativeSeparators(newPath)); - if (!dir.exists() || !dir.isDir()) - return; - - QList<ImportInfo> tmp; - tmp.append(recursivelyCheckDirectoryForBuild(dir.absoluteFilePath(), m_proFilePath)); - if (tmp.isEmpty()) { - QMessageBox::warning(this, tr("No builds found"), - tr("No builds for project file \"%1\" were found in the folder \"%2\".", - "%1: pro-file, %2: directory that was checked."). - arg(m_proFilePath, dir.absoluteFilePath())); - return; - } - tmp.append(m_infos); - setImportInfos(tmp); -} - -void TargetSetupPage::checkAll(bool checked) -{ - for (int i = 0; i < m_ui->versionTree->topLevelItemCount(); ++i) { - QTreeWidgetItem *current = m_ui->versionTree->topLevelItem(i); - for (int j = 0; j < current->childCount(); ++j) - checkOne(checked, current->child(j)); - } -} - -void TargetSetupPage::checkOne(bool checked, QTreeWidgetItem *item) -{ - Q_ASSERT(item->parent()); // we are a version item - item->setCheckState(0, checked ? Qt::Checked : Qt::Unchecked); -} - -void TargetSetupPage::checkAllButtonClicked() -{ - checkAll(m_toggleWillCheck); - - m_toggleWillCheck = !m_toggleWillCheck; - m_ui->uncheckButton->setText(m_toggleWillCheck ? tr("Check All") : tr("Uncheck All")); - m_ui->uncheckButton->setToolTip(m_toggleWillCheck - ? tr("Check all Qt versions") : tr("Uncheck all Qt versions")); -} - -void TargetSetupPage::checkAllTriggered() -{ - m_toggleWillCheck = true; - checkAllButtonClicked(); -} - -void TargetSetupPage::uncheckAllTriggered() -{ - m_toggleWillCheck = false; - checkAllButtonClicked(); -} - -void TargetSetupPage::checkOneTriggered() -{ - QAction * action = qobject_cast<QAction *>(sender()); - if (!action) - return; - QTreeWidgetItem *item = static_cast<QTreeWidgetItem *>(action->data().value<void *>()); - if (!item || !item->parent()) - return; - - checkAll(false); - checkOne(true, item); -} - -void TargetSetupPage::contextMenuRequested(const QPoint &position) -{ - m_contextMenu->clear(); - - QTreeWidgetItem *item = m_ui->versionTree->itemAt(position); - m_contextMenu = new QMenu(this); - if (item && item->parent()) { - // Qt version item - QAction *onlyThisAction = new QAction(tr("Check only this version"), m_contextMenu); - connect(onlyThisAction, SIGNAL(triggered()), this, SLOT(checkOneTriggered())); - onlyThisAction->setData(QVariant::fromValue(static_cast<void *>(item))); - m_contextMenu->addAction(onlyThisAction); - - QAction *checkAllAction = new QAction(tr("Check all versions"), m_contextMenu); - connect(checkAllAction, SIGNAL(triggered()), this, SLOT(checkAllTriggered())); - m_contextMenu->addAction(checkAllAction); - - QAction *uncheckAllAction = new QAction(tr("Uncheck all versions"), m_contextMenu); - connect(uncheckAllAction, SIGNAL(triggered()), this, SLOT(uncheckAllTriggered())); - m_contextMenu->addAction(uncheckAllAction); - } - if (!m_contextMenu->isEmpty()) - m_contextMenu->popup(m_ui->versionTree->mapToGlobal(position)); -} - -void TargetSetupPage::resetInfos() -{ - m_ui->versionTree->clear(); - foreach (const ImportInfo &info, m_infos) { - if (info.isTemporary) - delete info.version; - } - m_infos.clear(); -} - -QPair<QIcon, QString> TargetSetupPage::reportIssues(Qt4ProjectManager::QtVersion *version, - const QString &buildDir) -{ - if (m_proFilePath.isEmpty()) - return qMakePair(QIcon(), QString()); - - const ProjectExplorer::TaskHub *taskHub = ExtensionSystem::PluginManager::instance() - ->getObject<ProjectExplorer::TaskHub>(); - QTC_ASSERT(taskHub, return qMakePair(QIcon(), QString())); - - QList<ProjectExplorer::Task> issues = version->reportIssues(m_proFilePath, buildDir); - - QString text; - QIcon icon; - foreach (const ProjectExplorer::Task &t, issues) { - if (!text.isEmpty()) - text.append(QLatin1String("<br>")); - // set severity: - QString severity; - if (t.type == ProjectExplorer::Task::Error) { - icon = taskHub->taskTypeIcon(t.type); - severity = tr("<b>Error:</b> ", "Severity is Task::Error"); - } else if (t.type == ProjectExplorer::Task::Warning) { - if (icon.isNull()) - icon = taskHub->taskTypeIcon(t.type); - severity = tr("<b>Warning:</b> ", "Severity is Task::Warning"); - } - text.append(severity + t.description); - } - if (!text.isEmpty()) - text = QLatin1String("<nobr>") + text; - return qMakePair(icon, text); -} - -void TargetSetupPage::updateVersionItem(QTreeWidgetItem *versionItem, int index) -{ - ImportInfo &info = m_infos[index]; - QPair<QIcon, QString> issues = reportIssues(info.version, info.directory); - - //: We are going to build debug and release - QString buildType = tr("debug and release"); - if ((info.buildConfig & QtVersion::BuildAll) == 0) { - if (info.buildConfig & QtVersion::DebugBuild) - //: Debug build - buildType = tr("debug"); - else - //: release build - buildType = tr("release"); - } - - QString toolTip = info.version->displayName(); - //: %1: qmake used (incl. full path), %2: "debug", "release" or "debug and release" - toolTip.append(tr("<br>using %1 (%2)"). - arg(QDir::toNativeSeparators(info.version->qmakeCommand())). - arg(buildType)); - if (!issues.second.isEmpty()) - toolTip.append(QString::fromLatin1("<br><br>%1").arg(issues.second)); - - // Column 0: - versionItem->setToolTip(NAME_COLUMN, toolTip); - versionItem->setIcon(NAME_COLUMN, issues.first); - versionItem->setText(NAME_COLUMN, info.version->displayName() + " " + buildType); - versionItem->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable); - versionItem->setData(NAME_COLUMN, Qt::UserRole, index); - - // Column 1 (status): - const QString status = info.isExistingBuild ? - //: Is this an import of an existing build or a new one? - tr("Import") : - //: Is this an import of an existing build or a new one? - tr("New"); - versionItem->setText(STATUS_COLUMN, status); - versionItem->setToolTip(STATUS_COLUMN, status); - - // Column 2 (directory): - Q_ASSERT(versionItem->parent()); - versionItem->setText(DIRECTORY_COLUMN, QDir::toNativeSeparators(info.directory)); - versionItem->setToolTip(DIRECTORY_COLUMN, QDir::toNativeSeparators(info.directory)); -} diff --git a/src/plugins/qt4projectmanager/wizards/targetsetuppage.h b/src/plugins/qt4projectmanager/wizards/targetsetuppage.h index 47b9c847b83..d36b8e304bc 100644 --- a/src/plugins/qt4projectmanager/wizards/targetsetuppage.h +++ b/src/plugins/qt4projectmanager/wizards/targetsetuppage.h @@ -37,20 +37,18 @@ #include "qt4target.h" #include "qtversionmanager.h" -#include <QtCore/QList> -#include <QtCore/QPair> -#include <QtCore/QSet> #include <QtCore/QString> - -#include <QtGui/QIcon> #include <QtGui/QWizard> + QT_BEGIN_NAMESPACE class QLabel; class QMenu; class QPushButton; +class QSpacerItem; class QTreeWidget; class QTreeWidgetItem; +class QVBoxLayout; QT_END_NAMESPACE namespace Qt4ProjectManager { @@ -67,97 +65,48 @@ class TargetSetupPage : public QWizardPage Q_OBJECT public: - struct ImportInfo { - ImportInfo() : - version(0), - isTemporary(false), - buildConfig(QtVersion::QmakeBuildConfig(0)), - isExistingBuild(false) - { - if (version && version->isValid()) - buildConfig = version->defaultBuildConfig(); - } - - ImportInfo(const BuildConfigurationInfo &source) - : version(source.version), - isTemporary(false), - buildConfig(source.buildConfig), - additionalArguments(source.additionalArguments), - directory(source.directory), - isExistingBuild(false) - {} - - ImportInfo(const ImportInfo &other) : - version(other.version), - isTemporary(other.isTemporary), - buildConfig(other.buildConfig), - additionalArguments(other.additionalArguments), - directory(other.directory), - isExistingBuild(other.isExistingBuild) - { } - - QtVersion *version; - bool isTemporary; - QtVersion::QmakeBuildConfigs buildConfig; - QString additionalArguments; - QString directory; - bool isExistingBuild; - }; - explicit TargetSetupPage(QWidget* parent = 0); ~TargetSetupPage(); + /// Initializes the TargetSetupPage + /// \note The import information is gathered in initializePage(), make sure that the right proFilePath is set before void initializePage(); - - void setImportInfos(const QList<ImportInfo> &infos); - QList<ImportInfo> importInfos() const; - - void setImportDirectoryBrowsingEnabled(bool browsing); - void setImportDirectoryBrowsingLocation(const QString &directory); + /// Changes the default set of checked targets. For mobile Symbian, maemo5, simulator is checked + /// For non mobile, destkop is checked + /// call this before \sa initializePage() void setPreferMobile(bool mobile); - - static QList<ImportInfo> importInfosForKnownQtVersions(const QString &proFilePath); - static QList<ImportInfo> filterImportInfos(const QSet<QString> &validTargets, - const QList<ImportInfo> &infos); - - static QList<ImportInfo> scanDefaultProjectDirectories(Qt4Project *project); - static QList<ImportInfo> recursivelyCheckDirectoryForBuild(const QString &directory, - const QString &proFile, int maxdepth = 3); - - bool hasSelection() const; - bool isTargetSelected(const QString &targetid) const; + /// Sets the minimum qt version + /// calls this before \sa initializePage() + void setMinimumQtVersion(const QtVersionNumber &number); + /// Sets whether the TargetSetupPage looks on disk for builds of this project + /// call this before \sa initializePage() + void setImportSearch(bool b); bool isComplete() const; - - bool setupProject(Qt4Project *project); - -public slots: + bool setupProject(Qt4ProjectManager::Qt4Project *project); + bool isTargetSelected(const QString &id) const; void setProFilePath(const QString &dir); - void checkAll(bool checked); - void checkOne(bool, QTreeWidgetItem *); private slots: - void itemWasChanged(); - void checkAllButtonClicked(); - void checkAllTriggered(); - void uncheckAllTriggered(); - void checkOneTriggered(); - void addShadowBuildLocation(); - void contextMenuRequested(const QPoint & pos); + void newImportBuildConfiguration(const BuildConfigurationInfo &info); private: - void resetInfos(); - QPair<QIcon, QString> reportIssues(QtVersion *version, const QString &buildDir); - void updateVersionItem(QTreeWidgetItem *, int); + void setupImportInfos(); + void cleanupImportInfos(); + void setupWidgets(); + void deleteWidgets(); - QList<ImportInfo> m_infos; bool m_preferMobile; - bool m_toggleWillCheck; + bool m_importSearch; + QtVersionNumber m_minimumQtVersionNumber; QString m_proFilePath; QString m_defaultShadowBuildLocation; + QMap<QString, Qt4TargetSetupWidget *> m_widgets; + QHash<Qt4TargetSetupWidget *, Qt4BaseTargetFactory *> m_factories; + QVBoxLayout *m_layout; + QSpacerItem *m_spacer; Ui::TargetSetupPage *m_ui; - - QMenu *m_contextMenu; + QList<BuildConfigurationInfo> m_importInfos; }; } // namespace Internal diff --git a/src/plugins/qt4projectmanager/wizards/targetsetuppage.ui b/src/plugins/qt4projectmanager/wizards/targetsetuppage.ui index 4acbc473184..033c8ea4456 100644 --- a/src/plugins/qt4projectmanager/wizards/targetsetuppage.ui +++ b/src/plugins/qt4projectmanager/wizards/targetsetuppage.ui @@ -51,67 +51,26 @@ </property> </spacer> </item> - <item> - <widget class="QPushButton" name="uncheckButton"> - <property name="toolTip"> - <string>Uncheck all Qt versions</string> - </property> - <property name="text"> - <string>Uncheck All</string> - </property> - </widget> - </item> </layout> </item> <item> - <widget class="QTreeWidget" name="versionTree"> - <property name="columnCount"> - <number>3</number> + <widget class="QScrollArea" name="scrollArea"> + <property name="widgetResizable"> + <bool>true</bool> </property> - <column> - <property name="text"> - <string>Qt Version</string> - </property> - </column> - <column> - <property name="text"> - <string>Status</string> + <widget class="QWidget" name="scrollAreaWidgetContents"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>541</width> + <height>415</height> + </rect> </property> - </column> - <column> - <property name="text"> - <string>Build Directory</string> - </property> - </column> + <layout class="QVBoxLayout" name="verticalLayout_2"/> + </widget> </widget> </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout"> - <item> - <widget class="QPushButton" name="importButton"> - <property name="text"> - <string>Import Existing Shadow Build...</string> - </property> - <property name="flat"> - <bool>false</bool> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>0</height> - </size> - </property> - </spacer> - </item> - </layout> - </item> </layout> </widget> <resources/> -- GitLab