genericmakestep.cpp 11.9 KB
Newer Older
Roberto Raggi's avatar
Roberto Raggi committed
1 2 3 4 5 6
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
**
7
** Contact: Nokia Corporation (qt-info@nokia.com)
Roberto Raggi's avatar
Roberto Raggi committed
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
**
** 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
hjk's avatar
hjk committed
26
** contact the sales department at http://qt.nokia.com/contact.
Roberto Raggi's avatar
Roberto Raggi committed
27 28 29
**
**************************************************************************/

30
#include "genericmakestep.h"
Roberto Raggi's avatar
Roberto Raggi committed
31 32
#include "genericprojectconstants.h"
#include "genericproject.h"
33
#include "ui_genericmakestep.h"
34
#include "genericbuildconfiguration.h"
Roberto Raggi's avatar
Roberto Raggi committed
35

36
#include <extensionsystem/pluginmanager.h>
37
#include <projectexplorer/toolchain.h>
38
#include <projectexplorer/projectexplorer.h>
Tobias Hunger's avatar
Tobias Hunger committed
39
#include <projectexplorer/gnumakeparser.h>
40
#include <coreplugin/variablemanager.h>
41
#include <utils/qtcassert.h>
42

Roberto Raggi's avatar
Roberto Raggi committed
43 44 45 46 47 48 49 50 51
#include <QtGui/QFormLayout>
#include <QtGui/QGroupBox>
#include <QtGui/QCheckBox>
#include <QtGui/QLineEdit>
#include <QtGui/QListWidget>

using namespace GenericProjectManager;
using namespace GenericProjectManager::Internal;

52 53 54 55 56 57 58 59 60 61
namespace {
const char * const GENERIC_MS_ID("GenericProjectManager.GenericMakeStep");
const char * const GENERIC_MS_DISPLAY_NAME(QT_TRANSLATE_NOOP("GenericProjectManager::Internal::GenericMakeStep",
                                                             "Make"));

const char * const BUILD_TARGETS_KEY("GenericProjectManager.GenericMakeStep.BuildTargets");
const char * const MAKE_ARGUMENTS_KEY("GenericProjectManager.GenericMakeStep.MakeArguments");
const char * const MAKE_COMMAND_KEY("GenericProjectManager.GenericMakeStep.MakeCommand");
}

Tobias Hunger's avatar
Tobias Hunger committed
62
GenericMakeStep::GenericMakeStep(ProjectExplorer::BuildConfiguration *bc) :
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
    AbstractProcessStep(bc, QLatin1String(GENERIC_MS_ID))
{
    ctor();
}

GenericMakeStep::GenericMakeStep(ProjectExplorer::BuildConfiguration *bc, const QString &id) :
    AbstractProcessStep(bc, id)
{
    ctor();
}

GenericMakeStep::GenericMakeStep(ProjectExplorer::BuildConfiguration *bc, GenericMakeStep *bs) :
    AbstractProcessStep(bc, bs),
    m_buildTargets(bs->m_buildTargets),
    m_makeArguments(bs->m_makeArguments),
    m_makeCommand(bs->m_makeCommand)
Roberto Raggi's avatar
Roberto Raggi committed
79
{
80
    ctor();
Roberto Raggi's avatar
Roberto Raggi committed
81 82
}

83
void GenericMakeStep::ctor()
dt's avatar
Compile  
dt committed
84
{
85 86
    setDisplayName(QCoreApplication::translate("GenericProjectManager::Internal::GenericMakeStep",
                   GENERIC_MS_DISPLAY_NAME));
dt's avatar
Compile  
dt committed
87 88
}

89
GenericMakeStep::~GenericMakeStep()
Roberto Raggi's avatar
Roberto Raggi committed
90 91 92
{
}

dt's avatar
dt committed
93 94 95 96 97
GenericBuildConfiguration *GenericMakeStep::genericBuildConfiguration() const
{
    return static_cast<GenericBuildConfiguration *>(buildConfiguration());
}

98
bool GenericMakeStep::init()
Roberto Raggi's avatar
Roberto Raggi committed
99
{
dt's avatar
dt committed
100
    GenericBuildConfiguration *bc = genericBuildConfiguration();
Roberto Raggi's avatar
Roberto Raggi committed
101

102
    setEnabled(true);
103
    Core::VariableManager *vm = Core::VariableManager::instance();
104
    const QString rawBuildDir = bc->buildDirectory();
105
    const QString buildDir = vm->resolve(rawBuildDir);
106
    setWorkingDirectory(buildDir);
107

108 109
    setCommand(makeCommand());
    setArguments(replacedArguments());
110

111
    setEnvironment(bc->environment());
Tobias Hunger's avatar
Tobias Hunger committed
112 113 114 115 116 117

    setOutputParser(new ProjectExplorer::GnuMakeParser(buildDir));
    if (bc->genericProject()->toolChain())
        appendOutputParser(bc->genericProject()->toolChain()->outputParser());

    return AbstractProcessStep::init();
118 119
}

120
QVariantMap GenericMakeStep::toMap() const
121
{
122 123 124 125 126 127
    QVariantMap map(AbstractProcessStep::toMap());

    map.insert(QLatin1String(BUILD_TARGETS_KEY), m_buildTargets);
    map.insert(QLatin1String(MAKE_ARGUMENTS_KEY), m_makeArguments);
    map.insert(QLatin1String(MAKE_COMMAND_KEY), m_makeCommand);
    return map;
128 129
}

130
bool GenericMakeStep::fromMap(const QVariantMap &map)
131
{
132 133 134 135 136
    m_buildTargets = map.value(QLatin1String(BUILD_TARGETS_KEY)).toStringList();
    m_makeArguments = map.value(QLatin1String(MAKE_ARGUMENTS_KEY)).toStringList();
    m_makeCommand = map.value(QLatin1String(MAKE_COMMAND_KEY)).toString();

    return BuildStep::fromMap(map);
137 138
}

139
QStringList GenericMakeStep::replacedArguments() const
140 141
{
    Core::VariableManager *vm = Core::VariableManager::instance();
142 143
    const QStringList targets = m_buildTargets;
    QStringList arguments = m_makeArguments;
144 145 146 147 148 149 150
    QStringList replacedArguments;
    foreach (const QString &arg, arguments) {
      replacedArguments.append(vm->resolve(arg));
    }
    foreach (const QString &arg, targets) {
      replacedArguments.append(vm->resolve(arg));
    }
151 152
    return replacedArguments;
}
153

154
QString GenericMakeStep::makeCommand() const
155
{
156
    QString command = m_makeCommand;
157
    if (command.isEmpty()) {
dt's avatar
dt committed
158
        GenericProject *pro = genericBuildConfiguration()->genericProject();
dt's avatar
dt committed
159
        if (ProjectExplorer::ToolChain *toolChain = pro->toolChain())
160 161 162 163 164
            command = toolChain->makeCommand();
        else
            command = QLatin1String("make");
    }
    return command;
Roberto Raggi's avatar
Roberto Raggi committed
165 166
}

167
void GenericMakeStep::run(QFutureInterface<bool> &fi)
Roberto Raggi's avatar
Roberto Raggi committed
168 169 170 171
{
    AbstractProcessStep::run(fi);
}

172
ProjectExplorer::BuildStepConfigWidget *GenericMakeStep::createConfigWidget()
Roberto Raggi's avatar
Roberto Raggi committed
173
{
174
    return new GenericMakeStepConfigWidget(this);
Roberto Raggi's avatar
Roberto Raggi committed
175 176
}

177
bool GenericMakeStep::immutable() const
Roberto Raggi's avatar
Roberto Raggi committed
178 179 180 181
{
    return true;
}

182
bool GenericMakeStep::buildsTarget(const QString &target) const
Roberto Raggi's avatar
Roberto Raggi committed
183
{
184
    return m_buildTargets.contains(target);
Roberto Raggi's avatar
Roberto Raggi committed
185 186
}

187
void GenericMakeStep::setBuildTarget(const QString &target, bool on)
Roberto Raggi's avatar
Roberto Raggi committed
188
{
189
    QStringList old = m_buildTargets;
Roberto Raggi's avatar
Roberto Raggi committed
190
    if (on && !old.contains(target))
191
         old << target;
Roberto Raggi's avatar
Roberto Raggi committed
192
    else if(!on && old.contains(target))
193
        old.removeOne(target);
194

195
    m_buildTargets = old;
Roberto Raggi's avatar
Roberto Raggi committed
196 197 198
}

//
199
// GenericMakeStepConfigWidget
Roberto Raggi's avatar
Roberto Raggi committed
200
//
201 202

GenericMakeStepConfigWidget::GenericMakeStepConfigWidget(GenericMakeStep *makeStep)
Roberto Raggi's avatar
Roberto Raggi committed
203 204
    : m_makeStep(makeStep)
{
205 206
    m_ui = new Ui::GenericMakeStep;
    m_ui->setupUi(this);
Roberto Raggi's avatar
Roberto Raggi committed
207 208

    // TODO update this list also on rescans of the GenericLists.txt
dt's avatar
dt committed
209
    GenericProject *pro = m_makeStep->genericBuildConfiguration()->genericProject();
210 211
    foreach (const QString &target, pro->targets()) {
        QListWidgetItem *item = new QListWidgetItem(target, m_ui->targetsList);
Roberto Raggi's avatar
Roberto Raggi committed
212 213 214 215
        item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
        item->setCheckState(Qt::Unchecked);
    }

216 217
    connect(m_ui->targetsList, SIGNAL(itemChanged(QListWidgetItem*)),
            this, SLOT(itemChanged(QListWidgetItem*)));
218
    connect(m_ui->makeLineEdit, SIGNAL(textEdited(QString)),
219
            this, SLOT(makeLineEditTextEdited()));
220
    connect(m_ui->makeArgumentsLineEdit, SIGNAL(textEdited(QString)),
221
            this, SLOT(makeArgumentsLineEditTextEdited()));
222 223 224 225 226

    connect(ProjectExplorer::ProjectExplorerPlugin::instance(), SIGNAL(settingsChanged()),
            this, SLOT(updateMakeOverrrideLabel()));
    connect(ProjectExplorer::ProjectExplorerPlugin::instance(), SIGNAL(settingsChanged()),
            this, SLOT(updateDetails()));
Roberto Raggi's avatar
Roberto Raggi committed
227 228
}

229
QString GenericMakeStepConfigWidget::displayName() const
Roberto Raggi's avatar
Roberto Raggi committed
230
{
231
    return tr("Make", "GenericMakestep display name.");
Roberto Raggi's avatar
Roberto Raggi committed
232 233
}

234 235 236
// TODO: Label should update when tool chain is changed
void GenericMakeStepConfigWidget::updateMakeOverrrideLabel()
{
237
    m_ui->makeLabel->setText(tr("Override %1:").arg(m_makeStep->makeCommand()));
238 239
}

240
void GenericMakeStepConfigWidget::init()
Roberto Raggi's avatar
Roberto Raggi committed
241
{
242
    updateMakeOverrrideLabel();
243

244
    QString makeCommand = m_makeStep->m_makeCommand;
245 246
    m_ui->makeLineEdit->setText(makeCommand);

247
    const QStringList &makeArguments = m_makeStep->m_makeArguments;
248 249 250 251 252 253 254 255
    m_ui->makeArgumentsLineEdit->setText(ProjectExplorer::Environment::joinArgumentList(makeArguments));

    // Disconnect to make the changes to the items
    disconnect(m_ui->targetsList, SIGNAL(itemChanged(QListWidgetItem*)), this, SLOT(itemChanged(QListWidgetItem*)));

    int count = m_ui->targetsList->count();
    for (int i = 0; i < count; ++i) {
        QListWidgetItem *item = m_ui->targetsList->item(i);
256
        item->setCheckState(m_makeStep->buildsTarget(item->text()) ? Qt::Checked : Qt::Unchecked);
Roberto Raggi's avatar
Roberto Raggi committed
257
    }
258

259
    updateDetails();
Roberto Raggi's avatar
Roberto Raggi committed
260
    // and connect again
261 262 263
    connect(m_ui->targetsList, SIGNAL(itemChanged(QListWidgetItem*)), this, SLOT(itemChanged(QListWidgetItem*)));
}

264 265 266
void GenericMakeStepConfigWidget::updateDetails()
{
    m_summaryText = tr("<b>Make:</b> %1 %2")
267 268
                    .arg(m_makeStep->makeCommand(),
                         ProjectExplorer::Environment::joinArgumentList(m_makeStep->replacedArguments()));
269 270 271
    emit updateSummary();
}

dt's avatar
dt committed
272 273
QString GenericMakeStepConfigWidget::summaryText() const
{
274
    return m_summaryText;
dt's avatar
dt committed
275 276
}

277 278
void GenericMakeStepConfigWidget::itemChanged(QListWidgetItem *item)
{
279
    m_makeStep->setBuildTarget(item->text(), item->checkState() & Qt::Checked);
280
    updateDetails();
281 282 283 284
}

void GenericMakeStepConfigWidget::makeLineEditTextEdited()
{
285
    m_makeStep->m_makeCommand = m_ui->makeLineEdit->text();
286
    updateDetails();
287 288 289 290
}

void GenericMakeStepConfigWidget::makeArgumentsLineEditTextEdited()
{
291 292
    m_makeStep->m_makeArguments =
            ProjectExplorer::Environment::parseCombinedArgString(m_ui->makeArgumentsLineEdit->text());
293
    updateDetails();
Roberto Raggi's avatar
Roberto Raggi committed
294 295 296
}

//
297
// GenericMakeStepFactory
Roberto Raggi's avatar
Roberto Raggi committed
298 299
//

300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332
GenericMakeStepFactory::GenericMakeStepFactory(QObject *parent) :
    ProjectExplorer::IBuildStepFactory(parent)
{
}

GenericMakeStepFactory::~GenericMakeStepFactory()
{
}

bool GenericMakeStepFactory::canCreate(ProjectExplorer::BuildConfiguration *parent, const QString &id) const
{
    if (!qobject_cast<GenericBuildConfiguration *>(parent))
        return false;
    return id == QLatin1String(GENERIC_MS_ID);
}

ProjectExplorer::BuildStep *GenericMakeStepFactory::create(ProjectExplorer::BuildConfiguration *parent,
                                                           const QString &id)
{
    if (!canCreate(parent, id))
        return 0;
    return new GenericMakeStep(parent);
}

bool GenericMakeStepFactory::canClone(ProjectExplorer::BuildConfiguration *parent,
                                      ProjectExplorer::BuildStep *source) const
{
    const QString id(source->id());
    return canCreate(parent, id);
}

ProjectExplorer::BuildStep *GenericMakeStepFactory::clone(ProjectExplorer::BuildConfiguration *parent,
                                                          ProjectExplorer::BuildStep *source)
Roberto Raggi's avatar
Roberto Raggi committed
333
{
334 335 336 337 338
    if (!canClone(parent, source))
        return 0;
    GenericMakeStep *old(qobject_cast<GenericMakeStep *>(source));
    Q_ASSERT(old);
    return new GenericMakeStep(parent, old);
Roberto Raggi's avatar
Roberto Raggi committed
339 340
}

341 342
bool GenericMakeStepFactory::canRestore(ProjectExplorer::BuildConfiguration *parent,
                                        const QVariantMap &map) const
Roberto Raggi's avatar
Roberto Raggi committed
343
{
344 345
    QString id(ProjectExplorer::idFromMap(map));
    return canCreate(parent, id);
346 347
}

348 349
ProjectExplorer::BuildStep *GenericMakeStepFactory::restore(ProjectExplorer::BuildConfiguration *parent,
                                                            const QVariantMap &map)
350
{
351 352 353 354 355 356 357
    if (!canRestore(parent, map))
        return 0;
    GenericMakeStep *bs(new GenericMakeStep(parent));
    if (bs->fromMap(map))
        return bs;
    delete bs;
    return 0;
Roberto Raggi's avatar
Roberto Raggi committed
358 359
}

360
QStringList GenericMakeStepFactory::availableCreationIds(ProjectExplorer::BuildConfiguration *parent) const
Roberto Raggi's avatar
Roberto Raggi committed
361
{
362 363 364
    if (!qobject_cast<GenericBuildConfiguration *>(parent))
        return QStringList();
    return QStringList() << QLatin1String(GENERIC_MS_ID);
Roberto Raggi's avatar
Roberto Raggi committed
365 366
}

367
QString GenericMakeStepFactory::displayNameForId(const QString &id) const
Roberto Raggi's avatar
Roberto Raggi committed
368
{
369 370 371 372
    if (id == QLatin1String(GENERIC_MS_ID))
        return QCoreApplication::translate("GenericProjectManager::Internal::GenericMakeStep",
                                           GENERIC_MS_DISPLAY_NAME);
    return QString();
Roberto Raggi's avatar
Roberto Raggi committed
373
}