buildsettingspropertiespage.cpp 14.4 KB
Newer Older
1
/**************************************************************************
con's avatar
con committed
2
3
4
**
** This file is part of Qt Creator
**
5
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
con's avatar
con committed
6
**
7
** Contact: Nokia Corporation (qt-info@nokia.com)
con's avatar
con committed
8
**
9
** Commercial Usage
10
**
11
12
13
14
** 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.
15
**
16
** GNU Lesser General Public License Usage
17
**
18
19
20
21
22
23
** 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.
24
**
25
** 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.
con's avatar
con committed
27
**
28
**************************************************************************/
hjk's avatar
hjk committed
29

con's avatar
con committed
30
31
32
33
#include "buildsettingspropertiespage.h"
#include "buildstep.h"
#include "buildstepspage.h"
#include "project.h"
Tobias Hunger's avatar
Tobias Hunger committed
34
#include "target.h"
35
#include "buildconfiguration.h"
con's avatar
con committed
36

37
#include <coreplugin/coreconstants.h>
con's avatar
con committed
38
#include <extensionsystem/pluginmanager.h>
39
#include <utils/qtcassert.h>
con's avatar
con committed
40

41
42
#include <QtCore/QMargins>
#include <QtCore/QTimer>
43
#include <QtGui/QApplication>
44
#include <QtGui/QComboBox>
con's avatar
con committed
45
46
#include <QtGui/QInputDialog>
#include <QtGui/QLabel>
47
#include <QtGui/QMenu>
48
49
#include <QtGui/QPushButton>
#include <QtGui/QVBoxLayout>
con's avatar
con committed
50
51
52
53
54

using namespace ProjectExplorer;
using namespace ProjectExplorer::Internal;

///
55
// BuildSettingsPanelFactory
con's avatar
con committed
56
57
///

Tobias Hunger's avatar
Tobias Hunger committed
58
59
60
61
62
QString BuildSettingsPanelFactory::id() const
{
    return QLatin1String(BUILDSETTINGS_PANEL_ID);
}

con's avatar
con committed
63
64
65
66
67
QString BuildSettingsPanelFactory::displayName() const
{
    return QApplication::tr("Build Settings");
}

68
bool BuildSettingsPanelFactory::supports(Project *project)
con's avatar
con committed
69
{
Tobias Hunger's avatar
Tobias Hunger committed
70
71
72
73
74
75
    return project->targets().count() == 1;
}

bool BuildSettingsPanelFactory::supports(Target *target)
{
    return target->buildConfigurationFactory();
con's avatar
con committed
76
77
}

Tobias Hunger's avatar
Tobias Hunger committed
78

79
IPropertiesPanel *BuildSettingsPanelFactory::createPanel(Project *project)
con's avatar
con committed
80
{
Tobias Hunger's avatar
Tobias Hunger committed
81
82
    Q_ASSERT(supports(project));
    return new BuildSettingsPanel(project->activeTarget());
con's avatar
con committed
83
84
}

Tobias Hunger's avatar
Tobias Hunger committed
85
86
87
88
89
90
IPropertiesPanel *BuildSettingsPanelFactory::createPanel(Target *target)
{
    return new BuildSettingsPanel(target);
}


con's avatar
con committed
91
///
92
// BuildSettingsPanel
con's avatar
con committed
93
94
///

Tobias Hunger's avatar
Tobias Hunger committed
95
96
BuildSettingsPanel::BuildSettingsPanel(Target *target) :
    m_widget(new BuildSettingsWidget(target)),
97
    m_icon(":/projectexplorer/images/rebuild.png")
con's avatar
con committed
98
99
100
101
102
{
}

BuildSettingsPanel::~BuildSettingsPanel()
{
103
    delete m_widget;
con's avatar
con committed
104
105
}

106
QString BuildSettingsPanel::displayName() const
con's avatar
con committed
107
{
108
    return QApplication::tr("Build Settings");
con's avatar
con committed
109
110
}

111
QWidget *BuildSettingsPanel::widget() const
con's avatar
con committed
112
113
114
115
{
    return m_widget;
}

116
117
118
119
120
QIcon BuildSettingsPanel::icon() const
{
    return m_icon;
}

dt's avatar
dt committed
121
///
122
// BuildSettingsWidget
dt's avatar
dt committed
123
124
///

125
BuildSettingsWidget::~BuildSettingsWidget()
dt's avatar
dt committed
126
127
128
129
{
    clear();
}

Tobias Hunger's avatar
Tobias Hunger committed
130
131
BuildSettingsWidget::BuildSettingsWidget(Target *target) :
    m_target(target),
132
133
    m_buildConfiguration(0),
    m_leftMargin(0)
dt's avatar
dt committed
134
{
Tobias Hunger's avatar
Tobias Hunger committed
135
136
    Q_ASSERT(m_target);
    setupUi();
dt's avatar
dt committed
137
138
}

139
void BuildSettingsWidget::setupUi()
dt's avatar
dt committed
140
{
Tobias Hunger's avatar
Tobias Hunger committed
141
    m_leftMargin = Constants::PANEL_LEFT_MARGIN;
dt's avatar
dt committed
142
    QVBoxLayout *vbox = new QVBoxLayout(this);
143
    vbox->setContentsMargins(0, 0, 0, 0);
144

Tobias Hunger's avatar
Tobias Hunger committed
145
146
147
148
149
150
151
152
153
154
155
156
    if (!m_target->buildConfigurationFactory()) {
        QLabel * noSettingsLabel(new QLabel(this));
        noSettingsLabel->setText(tr("No Build Settings available"));
        {
            QFont f(noSettingsLabel->font());
            f.setPointSizeF(f.pointSizeF() * 1.2);
            noSettingsLabel->setFont(f);
        }
        vbox->addWidget(noSettingsLabel);
        return;
    }

157
158
    { // Edit Build Configuration row
        QHBoxLayout *hbox = new QHBoxLayout();
159
        hbox->setContentsMargins(m_leftMargin, 0, 0, 0);
160
161
162
163
164
165
166
167
168
        hbox->addWidget(new QLabel(tr("Edit Build Configuration:"), this));
        m_buildConfigurationComboBox = new QComboBox(this);
        m_buildConfigurationComboBox->setSizeAdjustPolicy(QComboBox::AdjustToContents);
        hbox->addWidget(m_buildConfigurationComboBox);

        m_addButton = new QPushButton(this);
        m_addButton->setText(tr("Add"));
        m_addButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
        hbox->addWidget(m_addButton);
169
170
        m_addButtonMenu = new QMenu(this);
        m_addButton->setMenu(m_addButtonMenu);
171
172
173
174
175

        m_removeButton = new QPushButton(this);
        m_removeButton->setText(tr("Remove"));
        m_removeButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
        hbox->addWidget(m_removeButton);
176
177
178
179
180
181
182

        m_makeActiveButton = new QPushButton(this);
        m_makeActiveButton->setText(tr("Make Active"));
        m_makeActiveButton->setToolTip(tr("Sets this build configuration to be used for this target."));
        m_makeActiveButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
        hbox->addWidget(m_makeActiveButton);

183
184
185
186
        hbox->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Fixed));
        vbox->addLayout(hbox);
    }

Tobias Hunger's avatar
Tobias Hunger committed
187
    m_buildConfiguration = m_target->activeBuildConfiguration();
dt's avatar
dt committed
188

dt's avatar
dt committed
189
190
    connect(m_buildConfigurationComboBox, SIGNAL(currentIndexChanged(int)),
            this, SLOT(currentIndexChanged(int)));
con's avatar
con committed
191

dt's avatar
dt committed
192
    connect(m_removeButton, SIGNAL(clicked()),
con's avatar
con committed
193
            this, SLOT(deleteConfiguration()));
dt's avatar
dt committed
194

195
196
197
    connect(m_makeActiveButton, SIGNAL(clicked()),
            this, SLOT(makeActive()));

198
    // TODO update on displayNameChange
199
200
//    connect(m_project, SIGNAL(buildConfigurationDisplayNameChanged(const QString &)),
//            this, SLOT(buildConfigurationDisplayNameChanged(const QString &)));
201

Tobias Hunger's avatar
Tobias Hunger committed
202
    connect(m_target, SIGNAL(activeBuildConfigurationChanged(ProjectExplorer::BuildConfiguration*)),
203
            this, SLOT(updateActiveConfiguration()));
Tobias Hunger's avatar
Tobias Hunger committed
204
205

    connect(m_target, SIGNAL(addedBuildConfiguration(ProjectExplorer::BuildConfiguration*)),
206
207
            this, SLOT(addedBuildConfiguration(ProjectExplorer::BuildConfiguration*)));

Tobias Hunger's avatar
Tobias Hunger committed
208
    connect(m_target, SIGNAL(removedBuildConfiguration(ProjectExplorer::BuildConfiguration*)),
209
210
            this, SLOT(removedBuildConfiguration(ProjectExplorer::BuildConfiguration*)));

Tobias Hunger's avatar
Tobias Hunger committed
211
    foreach (BuildConfiguration *bc, m_target->buildConfigurations()) {
212
213
214
215
        connect(bc, SIGNAL(displayNameChanged()),
                this, SLOT(buildConfigurationDisplayNameChanged()));
    }

Tobias Hunger's avatar
Tobias Hunger committed
216
217
218
    if (m_target->buildConfigurationFactory())
        connect(m_target->buildConfigurationFactory(), SIGNAL(availableCreationIdsChanged()),
                SLOT(updateAddButtonMenu()));
con's avatar
con committed
219

220
    updateAddButtonMenu();
con's avatar
con committed
221
222
223
    updateBuildSettings();
}

224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
void BuildSettingsWidget::addedBuildConfiguration(BuildConfiguration *bc)
{
    connect(bc, SIGNAL(displayNameChanged()),
            this, SLOT(buildConfigurationDisplayNameChanged()));
}

void BuildSettingsWidget::removedBuildConfiguration(BuildConfiguration *bc)
{
    disconnect(bc, SIGNAL(displayNameChanged()),
               this, SLOT(buildConfigurationDisplayNameChanged()));
}

void BuildSettingsWidget::buildConfigurationDisplayNameChanged()
{
    for (int i = 0; i < m_buildConfigurationComboBox->count(); ++i) {
        BuildConfiguration *bc = m_buildConfigurationComboBox->itemData(i).value<BuildConfiguration *>();
240
        m_buildConfigurationComboBox->setItemText(i, buildConfigurationItemName(bc));
241
242
243
    }
}

244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
void BuildSettingsWidget::addSubWidget(const QString &name, QWidget *widget)
{
    widget->setContentsMargins(m_leftMargin, 10, 0, 0);

    QLabel *label = new QLabel(this);
    label->setText(name);
    QFont f = label->font();
    f.setBold(true);
    f.setPointSizeF(f.pointSizeF() * 1.2);
    label->setFont(f);

    label->setContentsMargins(m_leftMargin, 10, 0, 0);

    layout()->addWidget(label);
    layout()->addWidget(widget);

    m_labels.append(label);
    m_subWidgets.append(widget);
}

void BuildSettingsWidget::clear()
{
    qDeleteAll(m_subWidgets);
    m_subWidgets.clear();
    qDeleteAll(m_labels);
    m_labels.clear();
}

QList<QWidget *> BuildSettingsWidget::subWidgets() const
{
    return m_subWidgets;
}

con's avatar
con committed
277
void BuildSettingsWidget::updateAddButtonMenu()
278
{
con's avatar
con committed
279
    m_addButtonMenu->clear();
Tobias Hunger's avatar
Tobias Hunger committed
280
281
282
283
284
285
    if (m_target &&
        m_target->activeBuildConfiguration()) {
        m_addButtonMenu->addAction(tr("&Clone Selected"),
                                   this, SLOT(cloneConfiguration()));
    }
    IBuildConfigurationFactory *factory = m_target->buildConfigurationFactory();
286
    if (factory) {
Tobias Hunger's avatar
Tobias Hunger committed
287
        foreach (const QString &id, factory->availableCreationIds(m_target)) {
288
289
            QAction *action = m_addButtonMenu->addAction(factory->displayNameForId(id), this, SLOT(createConfiguration()));
            action->setData(id);
290
291
292
293
        }
    }
}

con's avatar
con committed
294
295
void BuildSettingsWidget::updateBuildSettings()
{
dt's avatar
dt committed
296
    // TODO save position, entry from combbox
con's avatar
con committed
297
298

    // Delete old tree items
299
    bool blocked = m_buildConfigurationComboBox->blockSignals(true);
dt's avatar
dt committed
300
    m_buildConfigurationComboBox->clear();
301
    clear();
con's avatar
con committed
302

dt's avatar
dt committed
303
    // update buttons
Tobias Hunger's avatar
Tobias Hunger committed
304
    m_removeButton->setEnabled(m_target->buildConfigurations().size() > 1);
con's avatar
con committed
305
306

    // Add pages
Tobias Hunger's avatar
Tobias Hunger committed
307
    BuildConfigWidget *generalConfigWidget = m_target->project()->createConfigWidget();
308
    addSubWidget(generalConfigWidget->displayName(), generalConfigWidget);
dt's avatar
dt committed
309

Tobias Hunger's avatar
Tobias Hunger committed
310
311
    addSubWidget(tr("Build Steps"), new BuildStepsPage(m_target, false));
    addSubWidget(tr("Clean Steps"), new BuildStepsPage(m_target, true));
con's avatar
con committed
312

Tobias Hunger's avatar
Tobias Hunger committed
313
    QList<BuildConfigWidget *> subConfigWidgets = m_target->project()->subConfigWidgets();
dt's avatar
dt committed
314
    foreach (BuildConfigWidget *subConfigWidget, subConfigWidgets)
315
        addSubWidget(subConfigWidget->displayName(), subConfigWidget);
con's avatar
con committed
316
317

    // Add tree items
Tobias Hunger's avatar
Tobias Hunger committed
318
    foreach (BuildConfiguration *bc, m_target->buildConfigurations()) {
319
        m_buildConfigurationComboBox->addItem(buildConfigurationItemName(bc), QVariant::fromValue<BuildConfiguration *>(bc));
dt's avatar
dt committed
320
        if (bc == m_buildConfiguration)
dt's avatar
dt committed
321
            m_buildConfigurationComboBox->setCurrentIndex(m_buildConfigurationComboBox->count() - 1);
con's avatar
con committed
322
323
    }

324
    m_buildConfigurationComboBox->blockSignals(blocked);
con's avatar
con committed
325

326
    currentBuildConfigurationChanged();
con's avatar
con committed
327
328
}

dt's avatar
dt committed
329
void BuildSettingsWidget::currentIndexChanged(int index)
con's avatar
con committed
330
{
331
    m_buildConfiguration = m_buildConfigurationComboBox->itemData(index).value<BuildConfiguration *>();
332
    currentBuildConfigurationChanged();
con's avatar
con committed
333
334
}

335
void BuildSettingsWidget::currentBuildConfigurationChanged()
con's avatar
con committed
336
{
337
338
339
    m_makeActiveButton->setEnabled(m_buildConfiguration
            && m_buildConfiguration != m_target->activeBuildConfiguration());

Tobias Hunger's avatar
Tobias Hunger committed
340
341
342
    if (!m_buildConfiguration)
        return;

dt's avatar
dt committed
343
    for (int i = 0; i < m_buildConfigurationComboBox->count(); ++i) {
dt's avatar
dt committed
344
        if (m_buildConfigurationComboBox->itemData(i).value<BuildConfiguration *>() == m_buildConfiguration) {
dt's avatar
dt committed
345
346
347
348
            m_buildConfigurationComboBox->setCurrentIndex(i);
            break;
        }
    }
Tobias Hunger's avatar
Tobias Hunger committed
349

350
    foreach (QWidget *widget, subWidgets()) {
dt's avatar
dt committed
351
        if (BuildConfigWidget *buildStepWidget = qobject_cast<BuildConfigWidget*>(widget)) {
dt's avatar
dt committed
352
            buildStepWidget->init(m_buildConfiguration);
con's avatar
con committed
353
354
        }
    }
355
356
}

357
void BuildSettingsWidget::updateActiveConfiguration()
358
{
359
360
361
    for (int i = 0; i < m_buildConfigurationComboBox->count(); ++i) {
        BuildConfiguration *bc = m_buildConfigurationComboBox->itemData(i).value<BuildConfiguration *>();
        m_buildConfigurationComboBox->setItemText(i, buildConfigurationItemName(bc));
362
    }
363
364
    m_makeActiveButton->setEnabled(currentBuildConfiguration()
            && currentBuildConfiguration() != m_target->activeBuildConfiguration());
con's avatar
con committed
365
366
}

367
368
QString BuildSettingsWidget::buildConfigurationItemName(const BuildConfiguration *bc) const
{
Tobias Hunger's avatar
Tobias Hunger committed
369
    if (bc == m_target->activeBuildConfiguration())
370
371
372
373
        return tr("%1 (Active)").arg(bc->displayName());
    return bc->displayName();
}

374
375
376
377
378
BuildConfiguration *BuildSettingsWidget::currentBuildConfiguration() const {
    const int index = m_buildConfigurationComboBox->currentIndex();
    return m_buildConfigurationComboBox->itemData(index).value<BuildConfiguration *>();
}

con's avatar
con committed
379
380
void BuildSettingsWidget::createConfiguration()
{
Tobias Hunger's avatar
Tobias Hunger committed
381
382
383
    if (!m_target->buildConfigurationFactory())
        return;

384
    QAction *action = qobject_cast<QAction *>(sender());
Tobias Hunger's avatar
Tobias Hunger committed
385
386
    const QString &id = action->data().toString();
    BuildConfiguration *bc = m_target->buildConfigurationFactory()->create(m_target, id);
dt's avatar
dt committed
387
388
    if (bc) {
        m_buildConfiguration = bc;
389
390
        updateBuildSettings();
    }
con's avatar
con committed
391
392
393
394
}

void BuildSettingsWidget::cloneConfiguration()
{
395
    cloneConfiguration(currentBuildConfiguration());
con's avatar
con committed
396
397
398
399
}

void BuildSettingsWidget::deleteConfiguration()
{
400
401
402
403
404
405
    deleteConfiguration(currentBuildConfiguration());
}

void BuildSettingsWidget::makeActive()
{
    m_target->setActiveBuildConfiguration(currentBuildConfiguration());
con's avatar
con committed
406
407
}

dt's avatar
dt committed
408
void BuildSettingsWidget::cloneConfiguration(BuildConfiguration *sourceConfiguration)
con's avatar
con committed
409
{
Tobias Hunger's avatar
Tobias Hunger committed
410
411
    if (!sourceConfiguration ||
        !m_target->buildConfigurationFactory())
con's avatar
con committed
412
413
        return;

414
    QString newDisplayName(QInputDialog::getText(this, tr("Clone configuration"), tr("New Configuration Name:")));
dt's avatar
dt committed
415
    if (newDisplayName.isEmpty())
con's avatar
con committed
416
417
        return;

418
    QStringList buildConfigurationDisplayNames;
Tobias Hunger's avatar
Tobias Hunger committed
419
    foreach(BuildConfiguration *bc, m_target->buildConfigurations())
420
421
422
        buildConfigurationDisplayNames << bc->displayName();
    newDisplayName = Project::makeUnique(newDisplayName, buildConfigurationDisplayNames);

Tobias Hunger's avatar
Tobias Hunger committed
423
424
    BuildConfiguration * bc(m_target->buildConfigurationFactory()->clone(m_target, sourceConfiguration));
    if (!bc)
425
        return;
Tobias Hunger's avatar
Tobias Hunger committed
426
427

    m_buildConfiguration = bc;
428
    m_buildConfiguration->setDisplayName(newDisplayName);
Tobias Hunger's avatar
Tobias Hunger committed
429
    m_target->addBuildConfiguration(m_buildConfiguration);
dt's avatar
dt committed
430

con's avatar
con committed
431
432
433
    updateBuildSettings();
}

dt's avatar
dt committed
434
void BuildSettingsWidget::deleteConfiguration(BuildConfiguration *deleteConfiguration)
con's avatar
con committed
435
{
Tobias Hunger's avatar
Tobias Hunger committed
436
437
    if (!deleteConfiguration ||
        m_target->buildConfigurations().size() <= 1)
con's avatar
con committed
438
439
        return;

Tobias Hunger's avatar
Tobias Hunger committed
440
441
    if (m_target->activeBuildConfiguration() == deleteConfiguration) {
        foreach (BuildConfiguration *bc, m_target->buildConfigurations()) {
dt's avatar
dt committed
442
            if (bc != deleteConfiguration) {
Tobias Hunger's avatar
Tobias Hunger committed
443
                m_target->setActiveBuildConfiguration(bc);
con's avatar
con committed
444
445
446
447
448
                break;
            }
        }
    }

dt's avatar
dt committed
449
    if (m_buildConfiguration == deleteConfiguration) {
Tobias Hunger's avatar
Tobias Hunger committed
450
        foreach (BuildConfiguration *bc, m_target->buildConfigurations()) {
dt's avatar
dt committed
451
452
            if (bc != deleteConfiguration) {
                m_buildConfiguration = bc;
dt's avatar
dt committed
453
454
455
456
457
                break;
            }
        }
    }

Tobias Hunger's avatar
Tobias Hunger committed
458
    m_target->removeBuildConfiguration(deleteConfiguration);
con's avatar
con committed
459
460
461

    updateBuildSettings();
}