Commit 67cfb7e0 authored by dt's avatar dt

Qt4projectManager: Refactor Qt4Target, split up in per target classes

Almost(*) all of the symbian and maemo specific code is now theoretically
moveable to a separate plugin. Thus making it possible to implement
new targets in a plugin.

(*) Noteable missing is the qtversion, which needs to be split up
per target too.

Also fixes
Task-Nr: QTCREATORBUG-2440

Reviewed-By: hunger
Reviewed-By: ck
parent 77bf0c17
......@@ -186,7 +186,7 @@ CMakeTargetFactory::~CMakeTargetFactory()
{
}
QStringList CMakeTargetFactory::availableCreationIds(ProjectExplorer::Project *parent) const
QStringList CMakeTargetFactory::supportedTargetIds(ProjectExplorer::Project *parent) const
{
if (!qobject_cast<CMakeProject *>(parent))
return QStringList();
......
......@@ -89,7 +89,7 @@ public:
bool supportsTargetId(const QString &id) const;
QStringList availableCreationIds(ProjectExplorer::Project *parent) const;
QStringList supportedTargetIds(ProjectExplorer::Project *parent) const;
QString displayNameForId(const QString &id) const;
bool canCreate(ProjectExplorer::Project *parent, const QString &id) const;
......
......@@ -121,7 +121,7 @@ bool GenericTargetFactory::supportsTargetId(const QString &id) const
return id == QLatin1String(GENERIC_DESKTOP_TARGET_ID);
}
QStringList GenericTargetFactory::availableCreationIds(ProjectExplorer::Project *parent) const
QStringList GenericTargetFactory::supportedTargetIds(ProjectExplorer::Project *parent) const
{
if (!qobject_cast<GenericProject *>(parent))
return QStringList();
......
......@@ -91,7 +91,7 @@ public:
bool supportsTargetId(const QString &id) const;
QStringList availableCreationIds(ProjectExplorer::Project *parent) const;
QStringList supportedTargetIds(ProjectExplorer::Project *parent) const;
QString displayNameForId(const QString &id) const;
bool canCreate(ProjectExplorer::Project *parent, const QString &id) const;
......
......@@ -63,7 +63,6 @@ namespace ProjectExplorer {
class ProjectPrivate {
public:
ProjectPrivate();
QSet<QString> m_supportedTargetIds;
QList<Target *> m_targets;
Target *m_activeTarget;
EditorConfiguration *m_editorConfiguration;
......@@ -102,34 +101,6 @@ QString Project::makeUnique(const QString &preferredName, const QStringList &use
return tryName;
}
QSet<QString> Project::supportedTargetIds() const
{
return d->m_supportedTargetIds;
}
QSet<QString> Project::possibleTargetIds() const
{
QSet<QString> result(d->m_supportedTargetIds);
foreach (ProjectExplorer::Target *t, targets())
result.remove(t->id());
return result;
}
bool Project::canAddTarget(const QString &id) const
{
return possibleTargetIds().contains(id);
}
void Project::setSupportedTargetIds(const QSet<QString> &ids)
{
if (ids == d->m_supportedTargetIds)
return;
d->m_supportedTargetIds = ids;
emit supportedTargetIdsChanged();
}
void Project::changeEnvironment()
{
Target *t(qobject_cast<Target *>(sender()));
......@@ -280,26 +251,31 @@ bool Project::fromMap(const QVariantMap &map)
qWarning() << key << "was not found in data.";
return false;
}
QVariantMap targetMap = map.value(key).toMap();
QVariantMap targetMap = map.value(key).toMap();
QList<ITargetFactory *> factories =
ExtensionSystem::PluginManager::instance()->getObjects<ITargetFactory>();
Target *t = 0;
foreach (ITargetFactory *factory, factories) {
if (factory->canRestore(this, targetMap)) {
t = factory->restore(this, targetMap);
break;
if(target(idFromMap(targetMap))) {
qWarning() << "Duplicated target id found, not restoring second target with id"<<idFromMap(targetMap)<<"(Continuing)";
} else {
foreach (ITargetFactory *factory, factories) {
if (factory->canRestore(this, targetMap)) {
t = factory->restore(this, targetMap);
break;
}
}
}
if (!t) {
qWarning() << "Restoration of a target failed! (Continuing)";
continue;
if (!t) {
qWarning() << "Restoration of a target failed! (Continuing)";
continue;
}
addTarget(t);
if (i == active)
setActiveTarget(t);
}
addTarget(t);
if (i == active)
setActiveTarget(t);
}
return true;
}
......
......@@ -82,13 +82,6 @@ public:
EditorConfiguration *editorConfiguration() const;
// Target:
// Note: You can only add a specific kind of target (identified by id)
// once.
QSet<QString> supportedTargetIds() const;
QSet<QString> possibleTargetIds() const;
bool canAddTarget(const QString &id) const;
void addTarget(Target *target);
void removeTarget(Target *target);
......@@ -136,8 +129,6 @@ signals:
void removedTarget(ProjectExplorer::Target *target);
void addedTarget(ProjectExplorer::Target *target);
void supportedTargetIdsChanged();
/// convenience signal emitted if the activeBuildConfiguration emits environmentChanged
/// or if the activeBuildConfiguration changes
/// (which theoretically might happen due to the active target changing).
......@@ -149,8 +140,6 @@ protected:
// Note: Do not forget to call your base class' fromMap method!
virtual bool fromMap(const QVariantMap &map);
void setSupportedTargetIds(const QSet<QString> &ids);
private slots:
void changeEnvironment();
......
......@@ -961,6 +961,7 @@ void ProjectExplorerPlugin::clearSession()
void ProjectExplorerPlugin::extensionsInitialized()
{
d->m_proWindow->extensionsInitialized();
d->m_fileFactories = ProjectFileFactory::createFactories(&d->m_projectFilterString);
foreach (ProjectFileFactory *pf, d->m_fileFactories) {
d->m_profileMimeTypes += pf->mimeTypes();
......
......@@ -42,6 +42,7 @@
#include "projecttreewidget.h"
#include "iprojectproperties.h"
#include "targetsettingspanel.h"
#include "target.h"
#include <coreplugin/icore.h>
#include <coreplugin/ifile.h>
......@@ -261,6 +262,14 @@ ProjectWindow::~ProjectWindow()
{
}
void ProjectWindow::extensionsInitialized()
{
foreach (ITargetFactory *fac, ExtensionSystem::PluginManager::instance()->getObjects<ITargetFactory>())
connect(fac, SIGNAL(supportedTargetIdsChanged()),
this, SLOT(targetFactoriesChanged()));
}
void ProjectWindow::aboutToShutdown()
{
showProperties(-1, -1); // TODO that's a bit stupid, but otherwise stuff is still
......@@ -268,6 +277,35 @@ void ProjectWindow::aboutToShutdown()
disconnect(ProjectExplorerPlugin::instance()->session(), 0, this, 0);
}
void ProjectWindow::targetFactoriesChanged()
{
bool changed = false;
int index = m_tabWidget->currentIndex();
QList<Project *> projects = m_tabIndexToProject;
foreach (ProjectExplorer::Project *project, projects) {
if (m_usesTargetPage.value(project) != useTargetPage(project)) {
changed = true;
deregisterProject(project);
registerProject(project);
}
}
if (changed)
m_tabWidget->setCurrentIndex(index);
}
bool ProjectWindow::useTargetPage(ProjectExplorer::Project *project)
{
if (project->targets().size() > 1)
return true;
QStringList tmp;
foreach (ITargetFactory *fac, ExtensionSystem::PluginManager::instance()->getObjects<ITargetFactory>()) {
tmp.append(fac->supportedTargetIds(project));
if (tmp.size() > 1)
return true;
}
return false;
}
void ProjectWindow::registerProject(ProjectExplorer::Project *project)
{
if (!project || m_tabIndexToProject.contains(project))
......@@ -284,7 +322,11 @@ void ProjectWindow::registerProject(ProjectExplorer::Project *project)
}
QStringList subtabs;
if (project->supportedTargetIds().count() <= 1) {
bool usesTargetPage = useTargetPage(project);
m_usesTargetPage.insert(project, usesTargetPage);
if (!usesTargetPage){
// Show the target specific pages directly
QList<ITargetPanelFactory *> factories =
ExtensionSystem::PluginManager::instance()->getObjects<ITargetPanelFactory>();
......@@ -308,9 +350,6 @@ void ProjectWindow::registerProject(ProjectExplorer::Project *project)
m_tabIndexToProject.insert(index, project);
m_tabWidget->insertTab(index, project->displayName(), subtabs);
connect(project, SIGNAL(supportedTargetIdsChanged()),
this, SLOT(refreshProject()));
}
void ProjectWindow::deregisterProject(ProjectExplorer::Project *project)
......@@ -319,9 +358,6 @@ void ProjectWindow::deregisterProject(ProjectExplorer::Project *project)
if (index < 0)
return;
disconnect(project, SIGNAL(supportedTargetIdsChanged()),
this, SLOT(refreshProject()));
m_tabIndexToProject.removeAt(index);
m_tabWidget->removeTab(index);
}
......@@ -336,19 +372,6 @@ void ProjectWindow::saveStatus()
// TODO
}
void ProjectWindow::refreshProject()
{
Project *project = qobject_cast<ProjectExplorer::Project *>(sender());
if (!m_tabIndexToProject.contains(project))
return;
// TODO this changes the subindex
int index = m_tabWidget->currentIndex();
deregisterProject(project);
registerProject(project);
m_tabWidget->setCurrentIndex(index);
}
void ProjectWindow::startupProjectChanged(ProjectExplorer::Project *p)
{
int index = m_tabIndexToProject.indexOf(p);
......@@ -373,7 +396,8 @@ void ProjectWindow::showProperties(int index, int subIndex)
= qobject_cast<TargetSettingsPanelWidget*>(m_currentWidget)) {
m_previousTargetSubIndex = previousPanelWidget->currentSubIndex();
}
if (project->supportedTargetIds().count() > 1) {
if (m_usesTargetPage.value(project)) {
if (subIndex == 0) {
// Targets page
removeCurrentWidget();
......
......@@ -34,6 +34,7 @@
#ifndef PROJECTWINDOW_H
#define PROJECTWINDOW_H
#include <QtCore/QMap>
#include <QtGui/QScrollArea>
QT_BEGIN_NAMESPACE
......@@ -81,7 +82,9 @@ public:
~ProjectWindow();
void aboutToShutdown();
void extensionsInitialized();
private slots:
void targetFactoriesChanged();
void showProperties(int index, int subIndex);
void restoreStatus();
void saveStatus();
......@@ -89,15 +92,15 @@ private slots:
void deregisterProject(ProjectExplorer::Project*);
void startupProjectChanged(ProjectExplorer::Project *);
void refreshProject();
private:
bool useTargetPage(ProjectExplorer::Project *project);
void removeCurrentWidget();
DoubleTabWidget *m_tabWidget;
QStackedWidget *m_centralWidget;
QWidget *m_currentWidget;
QList<ProjectExplorer::Project *> m_tabIndexToProject;
QMap<ProjectExplorer::Project *, bool> m_usesTargetPage;
int m_previousTargetSubIndex;
};
......
......@@ -159,10 +159,9 @@ public:
explicit ITargetFactory(QObject *parent = 0);
virtual ~ITargetFactory();
virtual QStringList supportedTargetIds(ProjectExplorer::Project *project) const = 0;
virtual bool supportsTargetId(const QString &id) const = 0;
// used to show the list of possible additons to a target, returns a list of types
virtual QStringList availableCreationIds(Project *parent) const = 0;
// used to translate the types to names to display to the user
virtual QString displayNameForId(const QString &id) const = 0;
......@@ -172,7 +171,7 @@ public:
virtual Target *restore(Project *parent, const QVariantMap &map) = 0;
signals:
void availableCreationIdsChanged();
void supportedTargetIdsChanged();
};
} // namespace ProjectExplorer
......
......@@ -79,8 +79,14 @@ TargetSettingsPanelWidget::TargetSettingsPanelWidget(Project *project) :
connect(m_project, SIGNAL(activeTargetChanged(ProjectExplorer::Target*)),
this, SLOT(activeTargetChanged(ProjectExplorer::Target*)));
connect(m_project, SIGNAL(supportedTargetIdsChanged()),
this, SLOT(updateTargetAddAndRemoveButtons()));
QList<ITargetFactory *> factories =
ExtensionSystem::PluginManager::instance()->getObjects<ITargetFactory>();
foreach (ITargetFactory *fac, factories) {
connect(fac, SIGNAL(supportedTargetIdsChanged()),
this, SLOT(updateTargetAddAndRemoveButtons()));
}
}
TargetSettingsPanelWidget::~TargetSettingsPanelWidget()
......@@ -204,6 +210,7 @@ void TargetSettingsPanelWidget::currentTargetChanged(int targetIndex, int subInd
void TargetSettingsPanelWidget::addTarget(QAction *action)
{
QString id = action->data().toString();
Q_ASSERT(!m_project->target(id));
QList<ITargetFactory *> factories =
ExtensionSystem::PluginManager::instance()->getObjects<ITargetFactory>();
......@@ -284,30 +291,26 @@ void TargetSettingsPanelWidget::updateTargetAddAndRemoveButtons()
QList<ITargetFactory *> factories =
ExtensionSystem::PluginManager::instance()->getObjects<ITargetFactory>();
foreach (const QString &id, m_project->possibleTargetIds()) {
QString displayName;
foreach (ITargetFactory *fac, factories) {
if (fac->supportsTargetId(id)) {
displayName = fac->displayNameForId(id);
break;
foreach (ITargetFactory *fac, factories) {
foreach (const QString &id, fac->supportedTargetIds(m_project)) {
if (m_project->target(id))
continue;
QString displayName = fac->displayNameForId(id);
QAction *action = new QAction(displayName, m_addMenu);
action->setData(QVariant(id));
bool added = false;
foreach(QAction *existing, m_addMenu->actions()) {
if (existing->text() > action->text()) {
m_addMenu->insertAction(existing, action);
added = true;
}
}
}
if (displayName.isEmpty())
continue;
QAction *action = new QAction(displayName, m_addMenu);
action->setData(QVariant(id));
bool added = false;
foreach(QAction *existing, m_addMenu->actions()) {
if (existing->text() > action->text()) {
m_addMenu->insertAction(existing, action);
added = true;
}
if (!added)
m_addMenu->addAction(action);
}
if (!added)
m_addMenu->addAction(action);
}
m_selector->setAddButtonEnabled(!m_addMenu->actions().isEmpty());
m_selector->setRemoveButtonEnabled(m_project->targets().count() > 1);
}
......
......@@ -58,7 +58,6 @@ QmlProject::QmlProject(Internal::Manager *manager, const QString &fileName)
m_modelManager(ExtensionSystem::PluginManager::instance()->getObject<QmlJS::ModelManagerInterface>()),
m_fileWatcher(new ProjectExplorer::FileWatcher(this))
{
setSupportedTargetIds(QSet<QString>() << QLatin1String(Constants::QML_VIEWER_TARGET_ID));
QFileInfo fileInfo(m_fileName);
m_projectName = fileInfo.completeBaseName();
......
......@@ -108,7 +108,7 @@ bool QmlProjectTargetFactory::supportsTargetId(const QString &id) const
return id == QLatin1String(Constants::QML_VIEWER_TARGET_ID);
}
QStringList QmlProjectTargetFactory::availableCreationIds(ProjectExplorer::Project *parent) const
QStringList QmlProjectTargetFactory::supportedTargetIds(ProjectExplorer::Project *parent) const
{
if (!qobject_cast<QmlProject *>(parent))
return QStringList();
......
......@@ -76,7 +76,7 @@ public:
~QmlProjectTargetFactory();
bool supportsTargetId(const QString &id) const;
QStringList availableCreationIds(ProjectExplorer::Project *parent) const;
QStringList supportedTargetIds(ProjectExplorer::Project *parent) const;
QString displayNameForId(const QString &id) const;
bool canCreate(ProjectExplorer::Project *parent, const QString &id) const;
......
......@@ -34,7 +34,6 @@
#include "externaleditors.h"
#include "qt4project.h"
#include "qt4projectmanagerconstants.h"
#include "qt4target.h"
#include "qtversionmanager.h"
#include "qt4buildconfiguration.h"
......
......@@ -32,16 +32,8 @@
**************************************************************************/
#include "projectloadwizard.h"
#include "qt4project.h"
#include "qmakestep.h"
#include "qt4target.h"
#include "makestep.h"
#include "qt4buildconfiguration.h"
#include "qt4projectmanagerconstants.h"
#include "qtversionmanager.h"
#include "wizards/targetsetuppage.h"
#include "qt4project.h"
#include <QtGui/QCheckBox>
#include <QtGui/QHeaderView>
......@@ -98,7 +90,7 @@ void ProjectLoadWizard::setupTargetPage()
return;
QList<TargetSetupPage::ImportInfo> importVersions = TargetSetupPage::scanDefaultProjectDirectories(m_project);
importVersions.append(TargetSetupPage::importInfosForKnownQtVersions());
importVersions.append(TargetSetupPage::importInfosForKnownQtVersions(m_project->file()->fileName()));
m_targetSetupPage = new TargetSetupPage(this);
m_targetSetupPage->setProFilePath(m_project->file()->fileName());
......
......@@ -47,8 +47,8 @@ class Project;
}
namespace Qt4ProjectManager {
class Qt4Project;
class Qt4BuildConfiguration;
class Qt4Project;
namespace Internal {
......
HEADERS += \
$$PWD/qt4runconfiguration.h \
$$PWD/qt4desktoptargetfactory.h \
$$PWD/qt4simulatortargetfactory.h \
$$PWD/qt4desktoptarget.h \
$$PWD/qt4simulatortarget.h
SOURCES += \
$$PWD/qt4runconfiguration.cpp \
$$PWD/qt4desktoptargetfactory.cpp \
$$PWD/qt4simulatortargetfactory.cpp \
$$PWD/qt4desktoptarget.cpp \
$$PWD/qt4simulatortarget.cpp
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/
#include "qt4desktoptarget.h"
#include "qt4project.h"
#include "qt4runconfiguration.h"
#include <projectexplorer/deployconfiguration.h>
#include <projectexplorer/customexecutablerunconfiguration.h>
#include <QtGui/QApplication>
#include <QtGui/QStyle>
using namespace Qt4ProjectManager;
using namespace Qt4ProjectManager::Internal;
Qt4DesktopTarget::Qt4DesktopTarget(Qt4Project *parent, const QString &id) :
Qt4BaseTarget(parent, id),
m_buildConfigurationFactory(new Qt4BuildConfigurationFactory(this)),
m_deployConfigurationFactory(new ProjectExplorer::DeployConfigurationFactory(this))
{
setDisplayName(defaultDisplayName());
setIcon(qApp->style()->standardIcon(QStyle::SP_ComputerIcon));
}
Qt4DesktopTarget::~Qt4DesktopTarget()
{
}
QString Qt4DesktopTarget::defaultDisplayName()
{
return QApplication::translate("Qt4ProjectManager::Qt4Target", "Desktop", "Qt4 Desktop target display name");
}
Qt4BuildConfigurationFactory *Qt4DesktopTarget::buildConfigurationFactory() const
{
return m_buildConfigurationFactory;
}