buildsettingspropertiespage.cpp 12.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"
34
#include "buildconfiguration.h"
con's avatar
con committed
35

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

#include <QtCore/QDebug>
#include <QtCore/QPair>
#include <QtGui/QInputDialog>
#include <QtGui/QLabel>
dt's avatar
dt committed
44
#include <QtGui/QVBoxLayout>
45
#include <QtGui/QMenu>
con's avatar
con committed
46
47
48
49
50
51
52
53

using namespace ProjectExplorer;
using namespace ProjectExplorer::Internal;

///
/// BuildSettingsPanelFactory
///

54
bool BuildSettingsPanelFactory::supports(Project *project)
con's avatar
con committed
55
{
56
    return project->hasBuildSettings();
con's avatar
con committed
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
}

PropertiesPanel *BuildSettingsPanelFactory::createPanel(Project *project)
{
    return new BuildSettingsPanel(project);
}

///
/// BuildSettingsPanel
///

BuildSettingsPanel::BuildSettingsPanel(Project *project)
        : PropertiesPanel(),
          m_widget(new BuildSettingsWidget(project))
{
}

BuildSettingsPanel::~BuildSettingsPanel()
{
    delete m_widget;
}

QString BuildSettingsPanel::name() const
{
    return tr("Build Settings");
}

QWidget *BuildSettingsPanel::widget()
{
    return m_widget;
}

dt's avatar
dt committed
89
90
91
92
93
94
95
96
97
98
99
///
// BuildSettingsSubWidgets
///

BuildSettingsSubWidgets::~BuildSettingsSubWidgets()
{
    clear();
}

void BuildSettingsSubWidgets::addWidget(const QString &name, QWidget *widget)
{
dt's avatar
dt committed
100
101
    QSpacerItem *item = new QSpacerItem(1, 10, QSizePolicy::Fixed, QSizePolicy::Fixed);

dt's avatar
dt committed
102
103
104
105
106
107
108
    QLabel *label = new QLabel(this);
    label->setText(name);
    QFont f = label->font();
    f.setBold(true);
    f.setPointSizeF(f.pointSizeF() *1.2);
    label->setFont(f);

dt's avatar
dt committed
109
    layout()->addItem(item);
dt's avatar
dt committed
110
111
112
    layout()->addWidget(label);
    layout()->addWidget(widget);

dt's avatar
dt committed
113
    m_spacerItems.append(item);
dt's avatar
dt committed
114
115
116
117
118
119
    m_labels.append(label);
    m_widgets.append(widget);
}

void BuildSettingsSubWidgets::clear()
{
dt's avatar
dt committed
120
121
122
    foreach(QSpacerItem *item, m_spacerItems)
        layout()->removeItem(item);
    qDeleteAll(m_spacerItems);
dt's avatar
dt committed
123
124
    qDeleteAll(m_widgets);
    qDeleteAll(m_labels);
125
126
    m_widgets.clear();
    m_labels.clear();
dt's avatar
dt committed
127
    m_spacerItems.clear();
dt's avatar
dt committed
128
129
130
131
132
133
134
135
}

QList<QWidget *> BuildSettingsSubWidgets::widgets() const
{
    return m_widgets;
}

BuildSettingsSubWidgets::BuildSettingsSubWidgets(QWidget *parent)
dt's avatar
dt committed
136
    : QWidget(parent)
dt's avatar
dt committed
137
138
{
    new QVBoxLayout(this);
139
    layout()->setMargin(0);
dt's avatar
dt committed
140
141
}

con's avatar
con committed
142
143
144
145
146
147
148
149
150
151
152
///
/// BuildSettingsWidget
///

BuildSettingsWidget::~BuildSettingsWidget()
{
}

BuildSettingsWidget::BuildSettingsWidget(Project *project)
    : m_project(project)
{
dt's avatar
dt committed
153
    QVBoxLayout *vbox = new QVBoxLayout(this);
con's avatar
con committed
154
    vbox->setContentsMargins(0, -1, 0, -1);
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178

    { // Edit Build Configuration row
        QHBoxLayout *hbox = new QHBoxLayout();
        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);

        m_removeButton = new QPushButton(this);
        m_removeButton->setText(tr("Remove"));
        m_removeButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
        hbox->addWidget(m_removeButton);
        hbox->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Fixed));
        vbox->addLayout(hbox);
    }

    m_makeActiveLabel = new QLabel(this);
    m_makeActiveLabel->setVisible(false);
    vbox->addWidget(m_makeActiveLabel);
dt's avatar
dt committed
179
180
181

    m_subWidgets = new BuildSettingsSubWidgets(this);
    vbox->addWidget(m_subWidgets);
con's avatar
con committed
182

con's avatar
con committed
183
184
185
    m_addButtonMenu = new QMenu(this);
    m_addButton->setMenu(m_addButtonMenu);
    updateAddButtonMenu();
con's avatar
con committed
186

187
    m_buildConfiguration = m_project->activeBuildConfiguration()->name();
dt's avatar
dt committed
188

189
190
191
    connect(m_makeActiveLabel, SIGNAL(linkActivated(QString)),
            this, SLOT(makeActive()));

dt's avatar
dt committed
192
193
    connect(m_buildConfigurationComboBox, SIGNAL(currentIndexChanged(int)),
            this, SLOT(currentIndexChanged(int)));
con's avatar
con committed
194

dt's avatar
dt committed
195
    connect(m_removeButton, SIGNAL(clicked()),
con's avatar
con committed
196
            this, SLOT(deleteConfiguration()));
dt's avatar
dt committed
197

con's avatar
con committed
198
199
    connect(m_project, SIGNAL(buildConfigurationDisplayNameChanged(const QString &)),
            this, SLOT(buildConfigurationDisplayNameChanged(const QString &)));
200
201
202
203

    connect(m_project, SIGNAL(activeBuildConfigurationChanged()),
            this, SLOT(checkMakeActiveLabel()));

con's avatar
con committed
204
205
    if (m_project->buildConfigurationFactory())
        connect(m_project->buildConfigurationFactory(), SIGNAL(availableCreationTypesChanged()), SLOT(updateAddButtonMenu()));
con's avatar
con committed
206
207
208
209

    updateBuildSettings();
}

210
211
212
213
214
void BuildSettingsWidget::makeActive()
{
    m_project->setActiveBuildConfiguration(m_project->buildConfiguration(m_buildConfiguration));
}

con's avatar
con committed
215
void BuildSettingsWidget::updateAddButtonMenu()
216
{
con's avatar
con committed
217
218
    m_addButtonMenu->clear();
    m_addButtonMenu->addAction(tr("&Clone Selected"),
219
220
221
222
                             this, SLOT(cloneConfiguration()));
    IBuildConfigurationFactory *factory = m_project->buildConfigurationFactory();
    if (factory) {
        foreach (const QString &type, factory->availableCreationTypes()) {
con's avatar
con committed
223
            QAction *action = m_addButtonMenu->addAction(factory->displayNameForType(type), this, SLOT(createConfiguration()));
224
225
226
227
228
            action->setData(type);
        }
    }
}

con's avatar
con committed
229
230
void BuildSettingsWidget::buildConfigurationDisplayNameChanged(const QString &buildConfiguration)
{
dt's avatar
dt committed
231
232
    for (int i=0; i<m_buildConfigurationComboBox->count(); ++i) {
        if (m_buildConfigurationComboBox->itemData(i).toString() == buildConfiguration) {
233
            m_buildConfigurationComboBox->setItemText(i, m_project->buildConfiguration(buildConfiguration)->displayName());
dt's avatar
dt committed
234
            break;
con's avatar
con committed
235
236
237
238
239
240
241
        }
    }
}


void BuildSettingsWidget::updateBuildSettings()
{
dt's avatar
dt committed
242
    // TODO save position, entry from combbox
con's avatar
con committed
243
244

    // Delete old tree items
245
    bool blocked = m_buildConfigurationComboBox->blockSignals(true);
dt's avatar
dt committed
246
247
    m_buildConfigurationComboBox->clear();
    m_subWidgets->clear();
con's avatar
con committed
248

dt's avatar
dt committed
249
250
    // update buttons
    m_removeButton->setEnabled(m_project->buildConfigurations().size() > 1);
con's avatar
con committed
251
252

    // Add pages
dt's avatar
dt committed
253
    BuildConfigWidget *generalConfigWidget = m_project->createConfigWidget();
dt's avatar
dt committed
254
255
256
257
    m_subWidgets->addWidget(generalConfigWidget->displayName(), generalConfigWidget);

    m_subWidgets->addWidget(tr("Build Steps"), new BuildStepsPage(m_project));
    m_subWidgets->addWidget(tr("Clean Steps"), new BuildStepsPage(m_project, true));
con's avatar
con committed
258

dt's avatar
dt committed
259
260
    QList<BuildConfigWidget *> subConfigWidgets = m_project->subConfigWidgets();
    foreach (BuildConfigWidget *subConfigWidget, subConfigWidgets)
dt's avatar
dt committed
261
        m_subWidgets->addWidget(subConfigWidget->displayName(), subConfigWidget);
con's avatar
con committed
262
263

    // Add tree items
264
265
266
    foreach (const BuildConfiguration *bc, m_project->buildConfigurations()) {
        m_buildConfigurationComboBox->addItem(bc->displayName(), bc->name());
        if (bc->name() == m_buildConfiguration)
dt's avatar
dt committed
267
            m_buildConfigurationComboBox->setCurrentIndex(m_buildConfigurationComboBox->count() - 1);
con's avatar
con committed
268
269
    }

270
    m_buildConfigurationComboBox->blockSignals(blocked);
con's avatar
con committed
271

dt's avatar
dt committed
272
273
274
    // TODO Restore position, entry from combbox
    // TODO? select entry from combobox ?
    activeBuildConfigurationChanged();
con's avatar
con committed
275
276
}

dt's avatar
dt committed
277
void BuildSettingsWidget::currentIndexChanged(int index)
con's avatar
con committed
278
{
dt's avatar
dt committed
279
280
    m_buildConfiguration = m_buildConfigurationComboBox->itemData(index).toString();
    activeBuildConfigurationChanged();
con's avatar
con committed
281
282
}

dt's avatar
dt committed
283
void BuildSettingsWidget::activeBuildConfigurationChanged()
con's avatar
con committed
284
{
dt's avatar
dt committed
285
    for (int i = 0; i < m_buildConfigurationComboBox->count(); ++i) {
dt's avatar
dt committed
286
        if (m_buildConfigurationComboBox->itemData(i).toString() == m_buildConfiguration) {
dt's avatar
dt committed
287
288
289
290
291
            m_buildConfigurationComboBox->setCurrentIndex(i);
            break;
        }
    }
    foreach (QWidget *widget, m_subWidgets->widgets()) {
dt's avatar
dt committed
292
        if (BuildConfigWidget *buildStepWidget = qobject_cast<BuildConfigWidget*>(widget)) {
dt's avatar
dt committed
293
            buildStepWidget->init(m_buildConfiguration);
con's avatar
con committed
294
295
        }
    }
296
297
298
299
300
301
302
303
304
305
306
307
    checkMakeActiveLabel();
}

void BuildSettingsWidget::checkMakeActiveLabel()
{
    m_makeActiveLabel->setVisible(false);
    if (!m_project->activeBuildConfiguration() || m_project->activeBuildConfiguration()->name() != m_buildConfiguration) {
        BuildConfiguration *bc = m_project->buildConfiguration(m_buildConfiguration);
        QTC_ASSERT(bc, return);
        m_makeActiveLabel->setText(tr("<a href=\"#\">Make %1 active.</a>").arg(bc->displayName()));
        m_makeActiveLabel->setVisible(true);
    }
con's avatar
con committed
308
309
310
311
}

void BuildSettingsWidget::createConfiguration()
{
312
313
    QAction *action = qobject_cast<QAction *>(sender());
    const QString &type = action->data().toString();
314
    if (m_project->buildConfigurationFactory()->create(type)) {
con's avatar
con committed
315
        // TODO switching to last buildconfiguration in list might not be what we want
316
        m_buildConfiguration = m_project->buildConfigurations().last()->name();
317
318
        updateBuildSettings();
    }
con's avatar
con committed
319
320
321
322
}

void BuildSettingsWidget::cloneConfiguration()
{
dt's avatar
dt committed
323
    const QString configuration = m_buildConfigurationComboBox->itemData(m_buildConfigurationComboBox->currentIndex()).toString();
con's avatar
con committed
324
325
326
327
328
    cloneConfiguration(configuration);
}

void BuildSettingsWidget::deleteConfiguration()
{
dt's avatar
dt committed
329
    const QString configuration = m_buildConfigurationComboBox->itemData(m_buildConfigurationComboBox->currentIndex()).toString();
con's avatar
con committed
330
331
332
333
334
    deleteConfiguration(configuration);
}

void BuildSettingsWidget::cloneConfiguration(const QString &sourceConfiguration)
{
hjk's avatar
hjk committed
335
    if (sourceConfiguration.isEmpty())
con's avatar
con committed
336
337
338
        return;

    QString newBuildConfiguration = QInputDialog::getText(this, tr("Clone configuration"), tr("New Configuration Name:"));
hjk's avatar
hjk committed
339
    if (newBuildConfiguration.isEmpty())
con's avatar
con committed
340
341
342
        return;

    QString newDisplayName = newBuildConfiguration;
343
344
345
346
347
348
349
350
351
352
353
    QStringList buildConfigurationDisplayNames;
    foreach(BuildConfiguration *bc, m_project->buildConfigurations())
        buildConfigurationDisplayNames << bc->displayName();
    newDisplayName = Project::makeUnique(newDisplayName, buildConfigurationDisplayNames);

    QStringList buildConfigurationNames;
    foreach(BuildConfiguration *bc, m_project->buildConfigurations())
        buildConfigurationNames << bc->name();

    newBuildConfiguration = Project::makeUnique(newBuildConfiguration, buildConfigurationNames);

con's avatar
con committed
354
    m_project->copyBuildConfiguration(sourceConfiguration, newBuildConfiguration);
355
    m_project->setDisplayNameFor(m_project->buildConfiguration(newBuildConfiguration), newDisplayName);
con's avatar
con committed
356

dt's avatar
dt committed
357
    m_buildConfiguration = newBuildConfiguration;
con's avatar
con committed
358
359
360
361
362
363
364
365
    updateBuildSettings();
}

void BuildSettingsWidget::deleteConfiguration(const QString &deleteConfiguration)
{
    if (deleteConfiguration.isEmpty() || m_project->buildConfigurations().size() <= 1)
        return;

366
367
368
369
    if (m_project->activeBuildConfiguration()->name() == deleteConfiguration) {
        foreach (BuildConfiguration *bc, m_project->buildConfigurations()) {
            if (bc->name() != deleteConfiguration) {
                m_project->setActiveBuildConfiguration(bc);
con's avatar
con committed
370
371
372
373
374
                break;
            }
        }
    }

dt's avatar
dt committed
375
    if (m_buildConfiguration == deleteConfiguration) {
376
377
378
        foreach (const BuildConfiguration *bc, m_project->buildConfigurations()) {
            if (bc->name() != deleteConfiguration) {
                m_buildConfiguration = bc->name();
dt's avatar
dt committed
379
380
381
382
383
                break;
            }
        }
    }

384
    m_project->removeBuildConfiguration(m_project->buildConfiguration(deleteConfiguration));
con's avatar
con committed
385
386
387

    updateBuildSettings();
}